PATCH: Pre-ObjC++ ObjC Overhaul -- Part B

Ziemowit Laski zlaski@apple.com
Mon Aug 16 08:03:00 GMT 2004


This is the ObjC-specific part of the patch.  As you can see, the 
changes to objc-act.c
are very extensive (with c-parse.in changes to match), and have mostly 
to do with
weaning ObjC off the raw-declspec tree format in favor of better 
groomed VAR_DECLs,
PARM_DECLs, FIELD_DECLs and the like.

[gcc/ChangeLog]
2004-08-16  Ziemowit Laski  <zlaski@apple.com>

	* c-parse.in (methodtype): Specify %type; remove (explicit) semantic
	actions.
	(objc_inherit_code, objc_public_flag): Remove.
	(primary): Call objc_is_public() instead of is_public(),
	objc_build_message_expr() instead of build_message_expr(),
	objc_build_selector_expr() instead of build_selector_expr(),
	objc_build_protocol_expr() instead of build_protocol_expr(),
	objc_build_encode_expr() instead of build_encode_expr(),
	objc_build_string_object() instead of build_objc_string_object().
	(typespec_nonreserved_nonattr): Call objc_get_static_reference()
	instead of get_static_reference(), objc_get_object_reference()
	instead of get_object_reference().
	(component_decl_list2): Call objc_get_class_ivars() instead of
	get_class_ivars_from_name().
	(objcdef): Move semantic action to objc_finish_implementation(),
	and call it.
	(classdef): Move semantic actions to objc_start_class_interface(),
	objc_continue_interface(), objc_finish_interface(),
	objc_start_class_implementation(), objc_continue_implementation(),
	objc_start_category_interface() and 
objc_start_category_implementation()
	and call them.
	(protocoldef): Move semantic actions to objc_start_protocol() and
	objc_finish_interface() and call them.
	(visibility_spec): Move semantic actions to objc_set_visibility() and
	call it.
	* c-parse.in (OBJC_TYPE_QUAL): New %token.
	(ivars, ivar_declarator): Remove nonterminals and their associated
	productions.
	(objc_quals, objc_qual, objc_typename, optparms, optellipsis): New
	nonterminals.
	(ivar_decl): Use component_decl; adjust call to
	objc_add_instance_variable().
	(opt_semi): New nonterminal, with a pedantic-mode warning.
	(objc_catch_prefix): Call grokparm() before calling
	objc_begin_catch_clause().
	(methoddef): Move semantic actions to objc_set_method_type() and
	objc_start_method_definition(), objc_continue_method_definition()
	and objc_finish_method_definition() and call them.
	(methodproto): Move semantic actions to objc_set_method_type() and
	objc_add_method_declaration() and call them.
	(methoddecl): Call objc_build_method_signature() instead of
	build_method_decl(); use objc_typename instead of typename.
	(optparmlist): Call objc_method_ellipsis().
	(keyworddecl): Call objc_build_keyword_decl() instead of
	build_keyword_decl(); use objc_typename instead of typename.
	(receiver): Call objc_get_class_reference() instead of
	get_class_reference().
	(rid_to_yy): Mark RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF
	and RID_ONEWAY as returning OBJC_TYPE_QUAL to yyparse().
	(yylexname): Call objc_is_class_name() instead of is_class_name().
	* stub-objc.c (lookup_interface): Remove stub.
	(is_class_name): Rename to objc_is_class_name.
	(lookup_objc_ivar): Rename to objc_lookup_ivar.
	(objc_is_reserved_word, objc_declare_alias, objc_declare_class,
	objc_declare_protocols, objc_start_protocol, objc_is_id,
	objc_start_class_interface, objc_start_category_interface,
	objc_continue_interface, objc_finish_interface,
	objc_add_instance_variable, objc_set_visibility,
	objc_set_method_type, objc_start_class_implementation,
	objc_start_category_implementation, objc_continue_implementation,
	objc_finish_implementation, objc_add_method_declaration,
	objc_start_method_definition, objc_get_protocol_qualified_type,
	objc_finish_method_definition, objc_build_keyword_decl,
	objc_build_method_signature, objc_build_encode_expr,
	objc_build_protocol_expr, objc_static_init_needed_p,
	objc_build_selector_expr, objc_build_message_expr,
	objc_build_string_object, objc_get_class_reference,
	objc_generate_static_init_call): New stubs.

[gcc/objc/ChangeLog]
2004-08-16  Ziemowit Laski  <zlaski@apple.com>

	* Make-lang.in (objc/objc-act.o): Depend on $(HASHTAB_H).
	(objc/objc-parse.o): Depend on $(C_COMMON_H) instead of 
objc/objc-act.h.
	* config-lang.in (lang_requires): Add "C" as a dependency.
	* lang-specs.h: Rename 'objc-cpp-output' to 'objective-c-cpp-output'.
	* objc-act.c: Include hashtab.h; in ObjC++ mode, include cp-tree.h and
	objcp-decl.h instead of c-tree.h.
	(objc_inherit_code, objc_public_flag): New, moved from c-parse.in.
	(TYPE_ID): Rename to OBJECT_TYPEDEF_NAME.
	(CLASS_TYPEDEF_NAME): New.
	(TAG_EXECCLASS): Change from a global variable to a #define.
	(TAG_RETURN_STRUCT): Delete.
	(TAG_GNUINIT): New, holds '__objc_gnu_init' name.
	(string_descriptor): New type.
	(string_htab): New hash table, for constant strings.
	(string_hash, string_eq): New functions.
	(hash_init): Initialize string_htab hash table.
	(build_objc_string_object): Rename to objc_build_string_object();
	unique string objects using the string_htab hash table.
	(objc_start_function, objc_push_parm, objc_get_parm_info,
	gen_type_name, start_var_decl, finish_var_decl): New functions.
	(objc_expr_last, gen_declaration_1, gen_declarator, is_complex_decl,
	adorn_decl, define_decl, gen_declspecs, objc_is_type_qualifier): Remove
	functions.
	(synth_module_prologue): Call build_class_template(); predefine 'id'
	and 'Class' as typedefs; rename 'temp_type' to 'type'; disable debug
	hooks for duration of function; fix GNU runtime messenger signatures
	to correspond to reality; forward-declare '__objc_exec_class' for the
	GNU runtime; call build_selector_table_decl(); in ObjC++ mode, generate
	'extern "C" { ... }' wrappers around synthesized declarations; call
	build_protocol_template() and build_category_template().
	(build_metadata_decl): Call start_var_decl() instead of define_decl().
	(generate_objc_symtab_decl): Do not call build_category_template();
	call start_var_decl() and finish_var_decl() instead of start_decl()
	and finish_decl().
	(build_module_descriptor): Call create_field_decl() instead of
	grokfield(); call start_var_decl() and finish_var_decl() instead of
	start_decl() and finish_decl(); always mark module descriptor as
	used; move GNU runtime-specific functionality to
	build_module_initializer_routine().
	(build_module_initializer_routine): New function,
	broken off of build_module_descriptor().
	(generate_static_references, generate_strings,
	build_selector_translation_table, generate_descriptor_table,
	generate_ivars_list, generate_dispatch_table, generate_category): Call
	start_var_decl() and finish_var_decl() instead of start_decl() and
	finish_decl(); : build a type directly instead of via groktypename().
	(build_selector_reference_decl, build_selector_table_decl,
	build_class_reference_decl, build_protocol_reference,
	generate_objc_image_info): Call start_var_decl() instead of
	build_decl().
	(build_selector_reference): For GNU runtime, do not call
	build_selector_reference_decl().
	(objc_get_class_ivars): Do not call grokfield().
	(get_class_ivars): Remove second parameter; create a fresh copy
	of the ivar list for each call; do not check for existence of
	super class.
	(objc_begin_catch_clause): Convert the incoming PARM_DECL into
	a VAR_DECL before placing it in the appropriate scope; do not
	call define_decl().
	(build_private_template): Adjust call to get_class_ivars(); build
	a type directly instead of via groktypename().
	(build_protocol_template, build_method_prototype_list_template,
	build_method_prototype_template, build_category_template,
	build_selector_template, build_class_template, build_super_template,
	build_ivar_template, build_ivar_list_template,
	build_method_list_template, build_method_template):
	Call create_field_decl() instead of grokfield().
	(objc_method_parm_type): Do not call groktypename().
	(objc_encoded_type_size): Use INTEGRALTYPE_P instead of INTEGER_TYPE,
	BOOLEAN_TYPE and ENUMERAL_TYPE.
	(generate_protocols): Do not call build_protocol_template() or
	groktypename(); call start_var_decl() and finish_var_decl() instead of
	start_decl() and finish_decl().
	(synth_forward_declarations): Adjust call to build_metadata_decl().
	(error_with_ivar): Remove last parameter.
	(check_ivars): Do not iterate ovar CLASS_RAW_IVARS lists in addition
	to CLASS_IVARS lists; adjust calls to error_with_ivar().
	(generate_protocol_list, generate_shared_structures): Call
	start_var_decl() and finish_var_decl() instead of start_decl() and
	finish_decl(); build a type directly instead of via
	groktypename().
	(synth_id_with_class_suffix): Return a string.
	(get_arg_type_list): For instance methods, use the instance type for
	'self'; do not call groktypename_in_parm_context().
	(finish_message_expr): Rename to objc_finish_message_expr();
	call gen_type_name() instead of gen_declaration(); call objc_is_id()
	instead of using IS_ID and IS_CLASS; Use objc_class_name instead of
	calling get_identifier("Class"); handle CONVERT_EXPRs in receiver.
	(build_objc_method_call, warn_with_method): Do not call groktypename().
	(add_instance_variable): Simplify parameter list; do not call 
grokfield();
	do not populate CLASS_IVARS list.
	(start_class): Check for the existence of super class, if one was 
specified.
	(continue_class): Use CLASS_RAW_IVARS rather than CLASS_IVARS; do not
	call build_class_template(); adjust call to get_class_ivars(); call
	build_decl(), pushdecl() and finish_decl() instead of define_decl().
	(add_protocols): Use PROTOCOL_BINFO_ELTS for the tree vector size.
	(start_protocol): Do not call build_protocol_template(); use
	PROTOCOL_BINFO_ELTS for the tree vector size.
	(encode_type_qualifiers): Do not handle the 'const' qualifier here.
	(encode_pointer): Encode 'const char *' as 'r*', for backwards
	compatibility.
	(encode_array): Use HOST_WIDE_INT_PRINT_DEC instead of "%ld".
	(encode_type): Handle the 'const' qualifier here.
	(objc_parmlist): New global variable, sued by objc_push_parm and
	objc_get_parm_info().
	(synth_self_and_ucmd_args): For instance methods,  use the instance
	type for 'self'; call objc_push_parm() instead of push_parm_decl().
	(start_method_def): Do not call push_scope(), declare_parm_level(),
	pop_scope(), push_parm_decl(), store_parm_decls() or objc_expr_last();
	just use objc_push_parm() and objc_get_parm_info().
	(really_start_method); Call objc_start_function() instead of
	start_function() and objc_expr_last().
	(get_super_receiver): Call build_decl() and pushdecl() instead of
	start_decl().
	(tmpbuf, RAW_TYPESPEC): Remove.
	(gen_method_decl): Call gen_type_name() instead of gen_declaration_1().
	(generate_classref_translation_entry): Do not call start_decl(); call
	finish_var_decl() instead of finish_decl(); call convert() instead of
	build_c_cast().
	(init_objc_symtab): Cast initializer element to appropriate
	type.
	(objc_static_init_needed_p, objc_generate_static_init_call): New
	functions, called from within C and C++ static initializer logic.
	(build_selector, build_typed_selector_reference): Always convert
	result to the selector type.
	(build_method_prototype_template, build_selector_template,
	build_method_template): Use actual selector type for fields
	pointing to selectors.
	(finish_objc): For GNU runtime, call
	build_module_initializer_routine() after build_module_descriptor().
	(objc_init): Do not initialize objc_ellipsis_node or TAG_EXECCLASS;
	In ObjC++ mode, call cxx_init() instead of c_objc_common_init().
	(objc_method_ellipsis): Remove.
	(get_static_reference, get_object_reference): Removed, replaced by...
	(objc_get_protocol_qualified_type): ... this function; the 'id' and
	'Class' types no longer need to be defined in a header.
	(id_type, objc_id_id): Rename to objc_object_type and objc_object_name,
	respectively.
	(objc_class_type, objc_class_name, objc_class_reference): New.
	(objc_build_constructor): Remove initializer element conversions;
	tweak Objective-C++ impedance matching.
	(add_objc_string): Cast return value to 'char *'.
	(objc_is_id): New function.
	(objc_is_object_ptr): Return the canonical type node.
	(generate_ivar_lists): Convert one of the initializer elements.
	(get_arg_type_list, start_method_def, gen_method_def): Account for
	new representation of variable arguments and '...' in Objective-C
	methods; add Objective-C++ impedance matching code.
	(really_start_method): Initialize SELF_DECL here, and not in
	start_method_def.
	(continue_method_def): Remove.
	(is_objc_type_qualifier): Rename to objc_is_type_qualifier and
	make extern.
	(adjust_type_for_id_default): Call objc_is_type_qualifier() instead
	of is_objc_type_qualifier(); simplify; there is no longer a need to
	wade through declspecs.
	(objc_finish_file): Instantiate templates before calling
	finish_objc(); move calls to cp_finish_file() (for ObjC++) or
	c_objc_common_finish_file() (for ObjC) to the end.
	(objc_is_object_ptr): Rewrite using POINTER_TYPE_P() and
	IS_CLASS() macros.
	(receiver_is_class_object, finish_message_expr): Use new
	IS_CLASS() macro.
	(build_module_descriptor): Use '__objc_gnu_init'
	as static constructor name, so as not to collide with the
	global C/C++ module constructor, and mark it as
	DECL_STATIC_CONSTRUCTOR so that the back-end treats it
	properly; call objc_begin_compount_stmt() and
	objc_end_compound_stmt().
	(objc_begin_compound_stmt, objc_end_compound_stmt,
	objc_build_selector_decl): New functions.
	(objc_enter_block): Call objc_begin_compound_stmt().
	(objc_exit_block): Call objc_end_compound_stmt().
	(create_builtin_decl): Rename to 'create_field_decl' and get
	rid of the first parameter.
	(objc_build_constructor): For ObjC++, zero out the constructor
	type.
	(generate_struct_by_value_array, build_objc_symtab_template):
	Call create_field_decl() instead of create_builtin_decl().
	(build_objc_exception_stuff): Call create_field_decl() instead
	of create_builtin_decl(); do not touch debug hooks.
	(build_super_template): Do not touch debug hooks.
	(finish_objc): Do not hand-generate the constructor after
	calling build_module_descriptor(); the C/C++ machinery will
	do it for us.
	(lookup_interface, start_class, continue_class,
	finish_class, start_method_def, start_protocol, build_method_decl,
	objc_add_method, add_instance_variable, build_ivar_reference,
	is_ivar, is_private, get_super_receiver,
	objc_build_finally_epilogue): Make into static functions.
	(objc_start_class_interface, objc_start_category_interface,
	objc_start_protocol, objc_continue_interface, objc_finish_interface,
	objc_start_class_implementation, objc_start_category_implementation,
	objc_continue_implementation, objc_finish_implementation,
	objc_set_visibility, objc_set_method_type, objc_method_ellipsis,
	objc_build_method_signature, objc_add_method_declaration,
	objc_start_method_definition, objc_add_instance_variable,
	objc_is_reserved_word): New functions.
	(objc_check_decl): Call objc_is_class_name() instead of
	is_class_name().
	(objc_declare_alias): Call objc_is_class_name() instead of
	is_class_name().
	(is_class_name): Rename to objc_is_class_name().
	(get_class_ivars_from_name): Rename to objc_get_class_ivars.
	(objc_build_try_prologue): Call objc_get_current_scope()
	instead of get_current_scope().
	(objc_build_catch_stmt): Call objc_get_class_reference()
	instead of get_class_reference().
	(build_super_template): Name field 'super_class' instead
	of 'class'.
	(build_keyword_decl): Rename to objc_build_keyword_decl.
	(build_method_decl): Tweak ObjC++ additional argument handling.
	(build_message_expr): Rename to objc_build_message_expr;
	tweak ObjC++ message argument handling; call
	objc_finish_message_expr() instead of finish_message_expr().
	(build_protocol_expr): Rename to objc_build_protocol_expr.
	(build_selector_expr): Rename to objc_build_selector_expr.
	(build_encode_expr): Rename to objc_build_encode_expr.
	(is_public): Rename to objc_is_public.
	(start_class): Call objc_is_class_name() instead of
	is_class_name().
	(finish_protocol, objc_expand_function_end): Remove.
	(start_method_def): Tweak ObjC++ additional argument
	handling.
	(get_super_receiver): Call objc_get_current_scope() instead of
	get_current_scope(); reference 'super_class' field (instead of
	'class'); call objc_get_class_reference() instead of
	get_class_reference().
	(finish_method_def): Rename to objc_finish_method_definition and
	add a function decl parameter; move method encoding call from
	objc_expand_function_end.
	(lookup_objc_ivar): Rename to objc_lookup_ivar.
	(comp_method_with_proto): Remove.
	(objc_check_decl, is_class_name): Use OBJC_TYPE_NAME instead of 
TYPE_NAME.
	(objc_exit_block): Adjust ObjC++ finish_compound_stmt() impedance
	mismatch.
	(finish_message_expr): Use OBJC_TYPE_NAME and OBJC_SET_TYPE_NAME
	macros instead of TYPE_NAME.
	(objc_types_are_equivalent): Strip away indirections before comparing
	underlying types.
	(really_start_method): Call comp_proto_with_proto instead of
	comp_method_with_proto.
	* objc-act.h (CLASS_OWN_IVARS): Remove accessor.
	(CLASS_BINFO_ELTS): Reduce from 6 to 5, now that CLASS_OWN_IVARS is
	gone.
	(OCTI_GNU_INIT_DECL, GNU_INIT_decl): New.
	(OCTI_ELLIPSIS_NODE, objc_ellipsis_node): Remove.
	(OCTI_ID_ID, id_type, objc_id_id): Rename to OCTI_ID_NAME,
	objc_object_type and objc_object_name, respectively.
	(OCTI_CLS_REF, OCTI_CLASS_NAME, objc_class_reference,
	objc_class_name): New.
	(IS_CLASS): New macro.
	(IS_ID, IS_SUPER): Robustify.
	(OCTI_EXECCLASS_DECL, execclass_decl): New.
	(finish_file, start_class, continue_class, finish_class,
	start_method_def, continue_method_def, finish_method_def,
	start_protocol, finish_protocol, objc_build_throw_stmt,
	objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
	objc_build_synchronized_epilogue, objc_build_try_prologue,
	objc_build_try_epilogue, objc_build_catch_stmt, 
objc_build_catch_epilogue,
	objc_build_finally_prologue, objc_build_finally_epilogue,
	is_ivar, is_private, is_public, add_instance_variable, objc_add_method,
	get_super_receiver, objc_clear_super_receiver, 
get_class_ivars_from_name,
	get_class_reference, get_static_reference, get_object_reference,
	build_message_expr, finish_message_expr, build_selector_expr,
	build_ivar_reference, build_keyword_decl, build_method_decl,
	build_protocol_expr, build_objc_string_object, objc_declare_alias,
	objc_declare_class, objc_declare_protocols, objc_comptypes,
	objc_check_decl, build_encode_expr): Remove prototypes.
	(imp_count, cat_count): Make GGC-aware.
	(OBJC_SET_TYPE_NAME): New macro.

[gcc/testsuite/ChangeLog]
2004-08-16  Ziemowit Laski  <zlaski@apple.com>

	* objc/execute/next_mapping.h: Include stdlib.h and string.h.
	(MIN, MAX, ROUND): Redefine macros to be C/C++-agnostic.
	(__small_struct): New typedef.
	(STRUCTURE_SIZE_BOUNDARY): Use __small_struct instead of an inline
	struct definition.
	(arglist_t): Provide a union tag.
	(objc_aligned_size): Add missing prototype.
	(objc_sizeof_type): Use sizeof(char) in place of sizeof(void);
	remove extraneous break statements.
	(objc_alignof_type, objc_skip_typespec): Remove extraneous break
	statements.
	* objc.dg/bitfield-2.m: Make 'id' definition a typedef.
	* obj.dg/bitfield-4.m, objc.dg/method-6.m: Allow 'unsigned' in addition
	to 'unsigned int' in error message.
	* objc.dg/const-str-3.m: Include <memory.h> and <stdlib.h>.
	* objc.dg/id-1.m: Attempt to define 'id' in an incompatible fashion.
	* objc.dg/proto-qual-1.m: Protocol qualifiers now appear before the
	types they qualify.
	* objc.dg/type-size-2.m: Fix wording in comment.
	* objc.dg/va-meth-1.m: New test case.

Index: gcc/c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.226
diff -u -3 -p -r1.226 c-parse.in
--- gcc/c-parse.in      15 Aug 2004 15:44:51 -0000      1.226
+++ gcc/c-parse.in      16 Aug 2004 00:26:05 -0000
@@ -175,7 +176,7 @@ do {                                                
                         \
  /* The Objective-C keywords.  These are included in C and in
     Objective C, so that the token codes are the same in both.  */
  %token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS 
AT_ENCODE
-%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
+%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
  %token OBJECTNAME AT_CLASS AT_ALIAS
  %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
  %token OBJC_STRING
@@ -244,17 +245,18 @@ do {                                              
                         \
  @@ifobjc
  /* the Objective-C nonterminals */

-%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
  %type <ttype> methoddecl unaryselector keywordselector selector
+%type <code> methodtype
  %type <ttype> keyworddecl receiver objcmessageexpr messageargs
  %type <ttype> keywordexpr keywordarglist keywordarg
-%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
+%type <ttype> optparmlist optparms reservedwords objcselectorexpr
  %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
  %type <ttype> non_empty_protocolrefs protocolrefs identifier_list 
objcprotocolexpr

-%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING OBJC_TYPE_QUAL

-%type <ttype> superclass
+%type <ttype> superclass objc_quals objc_qual objc_typename
+%type <itype> objc_try_catch_stmt optellipsis
  @@end_ifobjc


  %{
@@ -308,8 +310,7 @@ static GTY(()) tree declspec_stack;
  @@ifobjc
  /* Objective-C specific parser/lexer information */

-static enum tree_code objc_inherit_code;
-static int objc_pq_context = 0, objc_public_flag = 0;
+static int objc_pq_context = 0;

  /* The following flag is needed to contextualize ObjC lexical analysis.
     In some cases (e.g., 'int NSObject;'), it is undesirable to bind
@@ -730,19 +731,19 @@ primary:
                   $$.original_code = ERROR_MARK; }
  @@ifobjc
         | objcmessageexpr
-               { $$.value = build_message_expr ($1);
+               { $$.value = objc_build_message_expr ($1);
                   $$.original_code = ERROR_MARK; }
         | objcselectorexpr
-               { $$.value = build_selector_expr ($1);
+               { $$.value = objc_build_selector_expr ($1);
                   $$.original_code = ERROR_MARK; }
         | objcprotocolexpr
-               { $$.value = build_protocol_expr ($1);
+               { $$.value = objc_build_protocol_expr ($1);
                   $$.original_code = ERROR_MARK; }
         | objcencodeexpr
-               { $$.value = build_encode_expr ($1);
+               { $$.value = objc_build_encode_expr ($1);
                   $$.original_code = ERROR_MARK; }
         | OBJC_STRING
-               { $$.value = build_objc_string_object ($1);
+               { $$.value = objc_build_string_object ($1);
                   $$.original_code = ERROR_MARK; }
  @@end_ifobjc
         ;
@@ -1356,14 +1357,14 @@ typespec_nonreserved_nonattr:
                   $$ = lookup_name ($1); }
  @@ifobjc
         | CLASSNAME protocolrefs
-               { $$ = get_static_reference ($1, $2); }
+               { $$ = objc_get_protocol_qualified_type ($1, $2); }
         | OBJECTNAME protocolrefs
-               { $$ = get_protocol_reference ($2); }
+               { $$ = objc_get_protocol_qualified_type ($1, $2); }

  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
     - nisse@lysator.liu.se */
          | non_empty_protocolrefs
-                { $$ = get_protocol_reference ($1); }
+                { $$ = objc_get_protocol_qualified_type (NULL_TREE, 
$1); }
  @@end_ifobjc
         | typeof '(' expr ')'
                 { skip_evaluation--;
@@ -1796,7 +1797,7 @@ component_decl_list2:     /* empty */
  @@ifobjc
         /* foo(sizeof(struct{ @defs(ClassName)})); */
         | AT_DEFS '(' CLASSNAME ')'
-               { $$ = nreverse (get_class_ivars_from_name ($3)); }
+               { $$ = nreverse (objc_get_class_ivars ($3)); }
  @@end_ifobjc
         ;

@@ -2305,7 +2306,7 @@ stmt_nocomp:

  objc_catch_prefix:
         AT_CATCH '(' parm ')'
-               { objc_begin_catch_clause ($3); }
+               { objc_begin_catch_clause (grokparm ($3)); }
         ;

  objc_catch_clause:
@@ -2648,14 +2649,7 @@ objcdef:
         | methoddef
         | AT_END
                 {
-                 if (objc_implementation_context)
-                    {
-                     finish_class (objc_implementation_context);
-                     objc_ivar_chain = NULL_TREE;
-                     objc_implementation_context = NULL_TREE;
-                   }
-                 else
-                   warning ("`@end' must appear in an implementation 
context");
+                 objc_finish_implementation ();
                 }
         ;

@@ -2694,50 +2688,38 @@ class_ivars:
  classdef:
           AT_INTERFACE identifier superclass protocolrefs
                 {
-                 objc_interface_context = objc_ivar_context
-                   = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
-                  objc_public_flag = 0;
+                 objc_start_class_interface ($2, $3, $4);
                 }
           class_ivars
                 {
-                  continue_class (objc_interface_context);
+                 objc_continue_interface ();
                 }
           methodprotolist AT_END
                 {
-                 finish_class (objc_interface_context);
-                 objc_interface_context = NULL_TREE;
+                 objc_finish_interface ();
                 }

         | AT_IMPLEMENTATION identifier superclass
                 {
-                 objc_implementation_context = objc_ivar_context
-                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, 
NULL_TREE);
-                  objc_public_flag = 0;
+                 objc_start_class_implementation ($2, $3);
                 }
           class_ivars
                 {
-                  objc_ivar_chain
-                   = continue_class (objc_implementation_context);
+                 objc_continue_implementation ();
                 }

         | AT_INTERFACE identifier '(' identifier ')' protocolrefs
                 {
-                 objc_interface_context
-                   = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
-                  continue_class (objc_interface_context);
+                 objc_start_category_interface ($2, $4, $6);
                 }
           methodprotolist AT_END
                 {
-                 finish_class (objc_interface_context);
-                 objc_interface_context = NULL_TREE;
+                 objc_finish_interface ();
                 }

         | AT_IMPLEMENTATION identifier '(' identifier ')'
                 {
-                 objc_implementation_context
-                   = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, 
$4, NULL_TREE);
-                  objc_ivar_chain
-                   = continue_class (objc_implementation_context);
+                 objc_start_category_implementation ($2, $4);
                 }
         ;

@@ -2745,14 +2727,12 @@ protocoldef:
           AT_PROTOCOL identifier protocolrefs
                 {
                   objc_pq_context = 1;
-                 objc_interface_context
-                   = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
+                 objc_start_protocol ($2, $3);
                 }
           methodprotolist AT_END
                 {
                   objc_pq_context = 0;
-                 finish_protocol(objc_interface_context);
-                 objc_interface_context = NULL_TREE;
+                 objc_finish_interface ();
                 }
         /* The @protocol forward-declaration production introduces a
            reduce/reduce conflict on ';', which should be resolved in
@@ -2782,109 +2762,67 @@ non_empty_protocolrefs:
         ;

  ivar_decl_list:
-          ivar_decl_list visibility_spec ivar_decls
-        | ivar_decls
+         /* empty */
+        | ivar_decl_list visibility_spec ivar_decls
          ;

  visibility_spec:
-         AT_PRIVATE { objc_public_flag = 2; }
-       | AT_PROTECTED { objc_public_flag = 0; }
-       | AT_PUBLIC { objc_public_flag = 1; }
+         /* empty */
+       | AT_PRIVATE { objc_set_visibility (2); }
+       | AT_PROTECTED { objc_set_visibility (0); }
+       | AT_PUBLIC { objc_set_visibility (1); }
         ;

  ivar_decls:
-          /* empty */
-               {
-                  $$ = NULL_TREE;
-                }
+         /* empty */
         | ivar_decls ivar_decl ';'
         | ivar_decls ';'
                 {
-                  if (pedantic)
+                 if (pedantic)
                     pedwarn ("extra semicolon in struct or union 
specified");
-                }
+               }
         ;

-
-/* There is a shift-reduce conflict here, because `components' may
-   start with a `typename'.  It happens that shifting (the default 
resolution)
-   does the right thing, because it treats the `typename' as part of
-   a `typed_typespecs'.
-
-   It is possible that this same technique would allow the distinction
-   between `notype_initdecls' and `initdecls' to be eliminated.
-   But I am being cautious and not trying it.  */
-
  ivar_decl:
-       declspecs_nosc_ts setspecs ivars
-               { $$ = $3;
-                 POP_DECLSPEC_STACK; }
-       | declspecs_nosc_nots setspecs ivars
-               { $$ = $3;
-                 POP_DECLSPEC_STACK; }
-       | error
-               { $$ = NULL_TREE; }
-       ;
+       component_decl
+               {
+                 /* Comma-separated ivars are chained together in
+                    reverse order; add them one by one.  */
+                 tree ivar = nreverse ($1);

-ivars:
-         /* empty */
-               { $$ = NULL_TREE; }
-       | ivar_declarator
-       | ivars ',' maybe_resetattrs ivar_declarator
+                 for (; ivar; ivar = TREE_CHAIN (ivar))
+                   objc_add_instance_variable (copy_node (ivar));
+               }
         ;

-ivar_declarator:
-         declarator
-               {
-                 $$ = add_instance_variable (objc_ivar_context,
-                                             objc_public_flag,
-                                             $1, current_declspecs,
-                                             NULL_TREE);
-                }
-       | declarator ':' expr_no_commas
-               {
-                 $$ = add_instance_variable (objc_ivar_context,
-                                             objc_public_flag,
-                                             $1, current_declspecs, 
$3.value);
-                }
-       | ':' expr_no_commas
+opt_semi:
+         /* NULL */
+       | ';'
                 {
-                 $$ = add_instance_variable (objc_ivar_context,
-                                             objc_public_flag,
-                                             NULL_TREE,
-                                             current_declspecs, 
$2.value);
-                }
+                 if (pedantic)
+                   pedwarn ("extra semicolon in method definition 
specified");
+               }
         ;

  methodtype:
           '+'
-               { objc_inherit_code = CLASS_METHOD_DECL; }
         | '-'
-               { objc_inherit_code = INSTANCE_METHOD_DECL; }
         ;

  methoddef:
           methodtype
                 {
+                 objc_set_method_type ($1);
                   objc_pq_context = 1;
-                 if (!objc_implementation_context)
-                   fatal_error ("method definition not in class 
context");
                 }
-         methoddecl
+         methoddecl opt_semi
                 {
                   objc_pq_context = 0;
-                 objc_add_method (objc_implementation_context,
-                                  $3,
-                                  objc_inherit_code == 
CLASS_METHOD_DECL);
-                 start_method_def ($3);
-               }
-         optarglist
-               {
-                 continue_method_def ();
+                 objc_start_method_definition ($3);
                 }
           compstmt_or_error
                 {
-                 finish_method_def ();
+                 objc_finish_method_definition (current_function_decl);
                 }
         ;

@@ -2906,6 +2844,7 @@ semi_or_error:
  methodproto:
           methodtype
                 {
+                 objc_set_method_type ($1);
                   /* Remember protocol qualifiers in prototypes.  */
                   objc_pq_context = 1;
                 }
@@ -2913,109 +2852,63 @@ methodproto:
                 {
                   /* Forget protocol qualifiers here.  */
                   objc_pq_context = 0;
-                 objc_add_method (objc_interface_context,
-                                  $3,
-                                  objc_inherit_code == 
CLASS_METHOD_DECL);
+                 objc_add_method_declaration ($3);
                 }
           semi_or_error
         ;

  methoddecl:
-         '(' typename ')' unaryselector
+         '(' objc_typename ')' unaryselector
                 {
-                 $$ = build_method_decl (objc_inherit_code, $2, $4, 
NULL_TREE);
+                 $$ = objc_build_method_signature ($2, $4, NULL_TREE);
                 }

         | unaryselector
                 {
-                 $$ = build_method_decl (objc_inherit_code, NULL_TREE, 
$1, NULL_TREE);
+                 $$ = objc_build_method_signature (NULL_TREE, $1, 
NULL_TREE);
                 }

-       | '(' typename ')' keywordselector optparmlist
+       | '(' objc_typename ')' keywordselector optparmlist
                 {
-                 $$ = build_method_decl (objc_inherit_code, $2, $4, 
$5);
+                 $$ = objc_build_method_signature ($2, $4, $5);
                 }

         | keywordselector optparmlist
                 {
-                 $$ = build_method_decl (objc_inherit_code, NULL_TREE, 
$1, $2);
+                 $$ = objc_build_method_signature (NULL_TREE, $1, $2);
                 }
         ;

-/* "optarglist" assumes that start_method_def has already been 
called...
-   if it is not, the "xdecls" will not be placed in the proper scope */
-
-optarglist:
-         /* empty */
-       | ';' myxdecls
-       ;
-
-/* to get around the following situation: "int foo (int a) int b; {}" 
that
-   is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
-
-myxdecls:
-         /* empty */
-       | mydecls
-       ;
-
-mydecls:
-       mydecl
-       | errstmt
-       | mydecls mydecl
-       | mydecl errstmt
-       ;
-
-mydecl:
-       declspecs_ts setspecs myparms ';'
-               { POP_DECLSPEC_STACK; }
-       | declspecs_ts ';'
-               { shadow_tag ($1); }
-       | declspecs_nots ';'
-               { pedwarn ("empty declaration"); }
-       ;
-
-myparms:
-       myparm
-               { push_parm_decl ($1); }
-       | myparms ',' myparm
-               { push_parm_decl ($3); }
-       ;
+/* Optional ObjC method parameters follow the C syntax, and may 
include '...'
+   to denote a variable number of arguments.  */

-/* A single parameter declaration or parameter type name,
-   as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
-
-myparm:
-         parm_declarator maybe_attribute
-               { $$ = build_tree_list (build_tree_list 
(current_declspecs,
-                                                        $1),
-                                       chainon ($2, 
all_prefix_attributes)); }
-       | notype_declarator maybe_attribute
-               { $$ = build_tree_list (build_tree_list 
(current_declspecs,
-                                                        $1),
-                                       chainon ($2, 
all_prefix_attributes)); }
-       | absdcl_maybe_attribute
-               { $$ = $1; }
+optparmlist:
+         optparms optellipsis
+               {
+                 TREE_OVERFLOW ($$) = $2;
+               }
         ;

-optparmlist:
-         /* empty */
+optparms:
+         /* NULL */
                 {
-                 $$ = NULL_TREE;
+                 $$ = make_node (TREE_LIST);
                 }
-       | ',' ELLIPSIS
+       | optparms ',' parm
                 {
-                 /* oh what a kludge! */
-                 $$ = objc_ellipsis_node;
+                 $$ = chainon ($1, build_tree_list (NULL_TREE,
+                                                    grokparm ($3)));
                 }
-       | ','
+       ;
+
+optellipsis:
+         /* NULL */
                 {
-                 push_scope ();
+                 $$ = 0;
                 }
-         parmlist_2
+       | ',' ELLIPSIS
                 {
-                 /* returns a tree list node generated by 
get_parm_info */
-                 $$ = $3;
-                 pop_scope ();
+                 $$ = 1;
                 }
         ;

@@ -3041,31 +2934,57 @@ selector:
         ;

  reservedwords:
-         ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR
+         ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR
         | SWITCH | CASE | DEFAULT | BREAK | CONTINUE | RETURN
         | GOTO | ASM_KEYWORD | SIZEOF | TYPEOF | ALIGNOF
         | TYPESPEC | TYPE_QUAL
         ;

+objc_qual:
+         OBJC_TYPE_QUAL
+       ;
+
+objc_quals:
+         objc_quals objc_qual
+               {
+                 $$ = chainon ($1, build_tree_list (NULL_TREE, $2));
+               }
+       | /* NULL */
+               {
+                 $$ = NULL_TREE;
+               }
+       ;
+
+objc_typename:
+         objc_quals typename
+               {
+                 $$ = build_tree_list ($1, groktypename ($2));
+               }
+       | objc_quals
+               {
+                 $$ = build_tree_list ($1, NULL_TREE);
+               }
+       ;
+
  keyworddecl:
-         selector ':' '(' typename ')' identifier
+         selector ':' '(' objc_typename ')' identifier
                 {
-                 $$ = build_keyword_decl ($1, $4, $6);
+                 $$ = objc_build_keyword_decl ($1, $4, $6);
                 }

         | selector ':' identifier
                 {
-                 $$ = build_keyword_decl ($1, NULL_TREE, $3);
+                 $$ = objc_build_keyword_decl ($1, NULL_TREE, $3);
                 }

-       | ':' '(' typename ')' identifier
+       | ':' '(' objc_typename ')' identifier
                 {
-                 $$ = build_keyword_decl (NULL_TREE, $3, $5);
+                 $$ = objc_build_keyword_decl (NULL_TREE, $3, $5);
                 }

         | ':' identifier
                 {
-                 $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
+                 $$ = objc_build_keyword_decl (NULL_TREE, NULL_TREE, 
$2);
                 }
         ;

@@ -3111,11 +3030,11 @@ receiver:
                 { $$ = $1.value; }
         | CLASSNAME
                 {
-                 $$ = get_class_reference ($1);
+                 $$ = objc_get_class_reference ($1);
                 }
         | TYPENAME
                 {
-                 $$ = get_class_reference ($1);
+                 $$ = objc_get_class_reference ($1);
                 }
         ;

@@ -3274,6 +3193,7 @@ static const struct resword reswords[] =
    { "void",            RID_VOID,       0 },
    { "volatile",                RID_VOLATILE,   0 },
    { "while",           RID_WHILE,      0 },
+
  @@ifobjc
    { "id",              RID_ID,                 D_OBJC },

@@ -3339,12 +3259,12 @@ static const short rid_to_yy[RID_MAX] =
    /* RID_MUTABLE */    0,

    /* ObjC */
-  /* RID_IN */         TYPE_QUAL,
-  /* RID_OUT */                TYPE_QUAL,
-  /* RID_INOUT */      TYPE_QUAL,
-  /* RID_BYCOPY */     TYPE_QUAL,
-  /* RID_BYREF */      TYPE_QUAL,
-  /* RID_ONEWAY */     TYPE_QUAL,
+  /* RID_IN */         OBJC_TYPE_QUAL,
+  /* RID_OUT */                OBJC_TYPE_QUAL,
+  /* RID_INOUT */      OBJC_TYPE_QUAL,
+  /* RID_BYCOPY */     OBJC_TYPE_QUAL,
+  /* RID_BYREF */      OBJC_TYPE_QUAL,
+  /* RID_ONEWAY */     OBJC_TYPE_QUAL,

    /* C */
    /* RID_INT */                TYPESPEC,
@@ -3518,7 +3438,7 @@ yylexname (void)
  @@ifobjc
    else
      {
-      tree objc_interface_decl = is_class_name (yylval.ttype);
+      tree objc_interface_decl = objc_is_class_name (yylval.ttype);
        /* ObjC class names are in the same namespace as variables and
          typedefs, and hence are shadowed by local declarations.  */
        if (objc_interface_decl
Index: gcc/stub-objc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stub-objc.c,v
retrieving revision 2.4
diff -u -3 -p -r2.4 stub-objc.c
--- gcc/stub-objc.c     25 Jul 2004 00:13:00 -0000      2.4
+++ gcc/stub-objc.c     16 Aug 2004 04:35:39 -0000
@@ -2,7 +2,7 @@
     that are called from within the C and C++ front-ends,
     respectively.
     Copyright (C) 1991, 1995, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.

  This file is part of GCC.

@@ -28,13 +28,13 @@ Software Foundation, 59 Temple Place - S
  #include "c-common.h"

  tree
-lookup_interface (tree ARG_UNUSED (arg))
+objc_is_class_name (tree ARG_UNUSED (arg))
  {
    return 0;
  }

  tree
-is_class_name (tree ARG_UNUSED (arg))
+objc_is_id (tree ARG_UNUSED (arg))
  {
    return 0;
  }
@@ -46,7 +46,7 @@ objc_is_object_ptr (tree ARG_UNUSED (arg
  }

  tree
-lookup_objc_ivar (tree ARG_UNUSED (arg))
+objc_lookup_ivar (tree ARG_UNUSED (arg))
  {
    return 0;
  }
@@ -57,9 +57,15 @@ objc_check_decl (tree ARG_UNUSED (decl))
  }

  int
+objc_is_reserved_word (tree ARG_UNUSED (ident))
+{
+  return 0;
+}
+
+int
  objc_comptypes (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs),
                  int ARG_UNUSED (reflexive))
-{
+{
    return -1;
  }

@@ -70,10 +76,178 @@ objc_message_selector (void)
  }

  void
+objc_declare_alias (tree ARG_UNUSED (alias), tree ARG_UNUSED (orig))
+{
+}
+
+void
+objc_declare_class (tree ARG_UNUSED (list))
+{
+}
+
+void
+objc_declare_protocols (tree ARG_UNUSED (list))
+{
+}
+
+void
+objc_start_protocol (tree ARG_UNUSED (proto),
+                    tree ARG_UNUSED (protorefs))
+{
+}
+
+void
+objc_start_class_interface (tree ARG_UNUSED (name),
+                           tree ARG_UNUSED (super),
+                           tree ARG_UNUSED (protos))
+{
+}
+
+void
+objc_start_category_interface (tree ARG_UNUSED (name),
+                              tree ARG_UNUSED (categ),
+                              tree ARG_UNUSED (protos))
+{
+}
+
+void
+objc_continue_interface (void)
+{
+}
+
+void
+objc_finish_interface (void)
+{
+}
+
+void
+objc_add_instance_variable (tree ARG_UNUSED (decl))
+{
+}
+
+void
+objc_set_visibility (int ARG_UNUSED (vis))
+{
+}
+
+void
+objc_set_method_type (enum tree_code ARG_UNUSED (code))
+{
+}
+
+void
+objc_start_class_implementation (tree ARG_UNUSED (name),
+                                tree ARG_UNUSED (super))
+{
+}
+
+void
+objc_start_category_implementation (tree ARG_UNUSED (name),
+                                   tree ARG_UNUSED (categ))
+{
+}
+
+void
+objc_continue_implementation (void)
+{
+}
+
+void
  objc_clear_super_receiver (void)
  {
  }

+void
+objc_finish_implementation (void)
+{
+}
+
+void
+objc_add_method_declaration (tree ARG_UNUSED (signature))
+{
+}
+
+void
+objc_start_method_definition (tree ARG_UNUSED (signature))
+{
+}
+
+void
+objc_finish_method_definition (tree ARG_UNUSED (fndecl))
+{
+}
+
+tree
+objc_build_keyword_decl (tree ARG_UNUSED (selector),
+                        tree ARG_UNUSED (typename),
+                        tree ARG_UNUSED (identifier))
+{
+  return 0;
+}
+
+tree
+objc_build_method_signature (tree ARG_UNUSED (rettype),
+                            tree ARG_UNUSED (selectors),
+                            tree ARG_UNUSED (optparms))
+{
+  return 0;
+}
+
+tree
+objc_build_encode_expr (tree ARG_UNUSED (expr))
+{
+  return 0;
+}
+
+tree
+objc_build_protocol_expr (tree ARG_UNUSED (expr))
+{
+  return 0;
+}
+
+tree
+objc_build_selector_expr (tree ARG_UNUSED (expr))
+{
+  return 0;
+}
+
+tree
+objc_build_message_expr (tree ARG_UNUSED (expr))
+{
+  return 0;
+}
+
+tree
+objc_build_string_object (tree ARG_UNUSED (str))
+{
+  return 0;
+}
+
+tree
+objc_get_class_reference (tree ARG_UNUSED (name))
+{
+  return 0;
+}
+
+tree
+objc_get_protocol_qualified_type (tree ARG_UNUSED (name),
+                                 tree ARG_UNUSED (protos))
+{
+  return 0;
+}
+
+int
+objc_static_init_needed_p (void)
+{
+  return 0;
+}
+
+tree
+objc_generate_static_init_call (tree ARG_UNUSED (ctors))
+{
+  return 0;
+}
+
  int
  objc_is_public (tree ARG_UNUSED (expr), tree ARG_UNUSED (identifier))
  {
Index: gcc/objc/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/Make-lang.in,v
retrieving revision 1.73
diff -u -3 -p -r1.73 Make-lang.in
--- gcc/objc/Make-lang.in       15 Aug 2004 21:47:32 -0000      1.73
+++ gcc/objc/Make-lang.in       16 Aug 2004 04:35:42 -0000
@@ -66,18 +66,18 @@ objc/objc-lang.o : objc/objc-lang.c \

  objc/objc-parse.o : objc/objc-parse.c \
     $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
-   toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h 
objc/objc-act.h \
+   toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h $(C_COMMON_H) 
\
     langhooks.h

  objc/objc-act.o : objc/objc-act.c \
     $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) 
$(TM_P_H) \
     $(EXPR_H) $(TARGET_H) $(C_TREE_H) diagnostic.h toplev.h flags.h \
     objc/objc-act.h input.h function.h output.h debug.h langhooks.h \
-   $(LANGHOOKS_DEF_H) gt-objc-objc-act.h
+   $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h

  objc.srcextra: objc/objc-parse.c objc/objc-parse.y
         -cp -p $^ $(srcdir)/objc
-
+
  objc/objc-parse.c : objc/objc-parse.y
         -$(BISON) $(BISONFLAGS) -o $@ $<

Index: gcc/objc/config-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/config-lang.in,v
retrieving revision 1.12
diff -u -3 -p -r1.12 config-lang.in
--- gcc/objc/config-lang.in     20 Aug 2003 10:50:20 -0000      1.12
+++ gcc/objc/config-lang.in     16 Aug 2004 04:35:42 -0000
@@ -34,4 +34,7 @@ stagestuff="cc1obj\$(exeext)"

  target_libs=target-libobjc

+# Most of the object files for cc1obj actually come from C.
+lang_requires="c"
+
  gtfiles="\$(srcdir)/objc/objc-act.h \$(srcdir)/c-parse.in 
\$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-objc-common.c 
\$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c 
\$(srcdir)/objc/objc-act.c"
Index: gcc/objc/lang-specs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/lang-specs.h,v
retrieving revision 1.35
diff -u -3 -p -r1.35 lang-specs.h
--- gcc/objc/lang-specs.h       5 Apr 2004 19:23:24 -0000       1.35
+++ gcc/objc/lang-specs.h       16 Aug 2004 04:35:42 -0000
@@ -34,8 +34,8 @@ Boston, MA 02111-1307, USA.  */
         %{!save-temps:%{!no-integrated-cpp:\
             cc1obj %(cpp_unique_options) %(cc1_options) 
%{print-objc-runtime-info} %{gen-decls}}}\
          %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
-  {".mi", "@objc-cpp-output", 0, 0, 0},
-  {"@objc-cpp-output",
+  {".mi", "@objective-c-cpp-output", 0, 0, 0},
+  {"@objective-c-cpp-output",
       "%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) 
%{print-objc-runtime-info} %{gen-decls}\
                              %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 
0},
    {"@objective-c-header",
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.237
diff -u -3 -p -r1.237 objc-act.c
--- gcc/objc/objc-act.c 15 Aug 2004 21:47:32 -0000      1.237
+++ gcc/objc/objc-act.c 16 Aug 2004 04:35:42 -0000
@@ -47,7 +47,13 @@ Boston, MA 02111-1307, USA.  */
  #include "rtl.h"
  #include "tm_p.h"
  #include "expr.h"
+
+#ifdef OBJCPLUS
+#include "cp-tree.h"
+#else
  #include "c-tree.h"
+#endif
+
  #include "c-common.h"
  #include "flags.h"
  #include "langhooks.h"
@@ -65,6 +71,16 @@ Boston, MA 02111-1307, USA.  */
  #include "cgraph.h"
  #include "tree-iterator.h"
  #include "libfuncs.h"
+#include "hashtab.h"
+
+#define OBJC_VOID_AT_END       void_list_node
+
+/* When building Objective-C++, we are not linking against the C 
front-end
+   and so need to replicate the C tree-construction functions in some 
way.  */
+#ifdef OBJCPLUS
+#define OBJCP_REMAP_FUNCTIONS
+#include "objcp-decl.h"
+#endif  /* OBJCPLUS */

  /* This is the default way of generating a method name.  */
  /* I am not sure it is really correct.
@@ -126,15 +142,30 @@ static void finish_objc (void);

  static void synth_module_prologue (void);
  static tree objc_build_constructor (tree, tree);
-static rtx build_module_descriptor (void);
+static void build_module_descriptor (void);
+static void build_module_initializer_routine (void);
  static tree init_module_descriptor (tree);
  static tree build_objc_method_call (int, tree, tree, tree, tree);
  static void generate_strings (void);
  static tree get_proto_encoding (tree);
  static void build_selector_translation_table (void);
-
+static tree lookup_interface (tree);
  static tree objc_add_static_instance (tree, tree);

+static tree start_class (enum tree_code, tree, tree, tree);
+static tree continue_class (tree);
+static void finish_class (tree);
+static void start_method_def (tree);
+static void objc_start_function (tree, tree, tree, tree);
+static tree start_protocol (enum tree_code, tree, tree);
+static tree build_method_decl (enum tree_code, tree, tree, tree);
+static tree objc_add_method (tree, tree, int);
+static tree add_instance_variable (tree, int, tree);
+static tree build_ivar_reference (tree);
+static tree is_ivar (tree, tree);
+static int is_private (tree);
+static tree get_super_receiver (void);
+
  static void build_objc_exception_stuff (void);
  static void build_next_objc_exception_stuff (void);

@@ -150,7 +181,7 @@ static tree build_category_initializer (
  static tree build_protocol_initializer (tree, tree, tree, tree, tree);
  static void synth_forward_declarations (void);
  static int ivar_list_length (tree);
-static tree get_class_ivars (tree, int);
+static tree get_class_ivars (tree);
  static void generate_ivar_lists (void);
  static void generate_dispatch_tables (void);
  static void generate_shared_structures (void);
@@ -158,13 +189,12 @@ static tree generate_protocol_list (tree
  static void build_protocol_reference (tree);

  static tree build_keyword_selector (tree);
-static tree synth_id_with_class_suffix (const char *, tree);
+static const char *synth_id_with_class_suffix (const char *, tree);

  static void generate_static_references (void);
  static int check_methods_accessible (tree, tree, int);
  static void encode_aggregate_within (tree, int, int, int, int);
  static const char *objc_demangle (const char *);
-static void objc_expand_function_end (void);

  /* Hash tables to manage the global pool of method prototypes.  */

@@ -194,6 +224,7 @@ static tree add_objc_string (tree, enum
  static tree get_objc_string_decl (tree, enum string_section);
  static tree build_objc_string_decl (enum string_section);
  static tree build_selector_reference_decl (void);
+static void build_selector_table_decl (void);

  /* Protocol additions.  */

@@ -214,31 +245,29 @@ static void encode_type (tree, int, int)
  static void encode_field_decl (tree, int, int);

  static void really_start_method (tree, tree);
-static int comp_method_with_proto (tree, tree);
  static int objc_types_are_equivalent (tree, tree);
  static int comp_proto_with_proto (tree, tree);
  static tree get_arg_type_list (tree, int, int);
-static tree objc_expr_last (tree);
+static void objc_push_parm (tree);
+static tree objc_get_parm_info (int);
  static void synth_self_and_ucmd_args (void);

  /* Utilities for debugging and error diagnostics.  */

  static void warn_with_method (const char *, int, tree);
-static void error_with_ivar (const char *, tree, tree);
+static void error_with_ivar (const char *, tree);
+static char *gen_type_name (tree, char *);
  static char *gen_method_decl (tree, char *);
  static char *gen_declaration (tree, char *);
-static void gen_declaration_1 (tree, char *);
-static char *gen_declarator (tree, char *, const char *);
-static int is_complex_decl (tree);
-static void adorn_decl (tree, char *);
  static void dump_interface (FILE *, tree);

  /* Everything else.  */

-static tree define_decl (tree, tree);
  static tree lookup_method_in_protocol_list (tree, tree, int);
  static tree lookup_protocol_in_reflist (tree, tree);
-static tree create_builtin_decl (enum tree_code, tree, const char *);
+static tree start_var_decl (tree, const char *);
+static void finish_var_decl (tree, tree);
+static tree create_field_decl (tree, const char *);
  static void setup_string_decl (void);
  static int check_string_class_template (void);
  static tree my_build_string (int, const char *);
@@ -253,7 +282,7 @@ static tree build_typed_selector_referen
  static tree build_selector_reference (tree);
  static tree build_class_reference_decl (void);
  static void add_class_reference (tree);
-static tree build_protocol_template (void);
+static void build_protocol_template (void);
  static tree build_descriptor_table_initializer (tree, tree);
  static tree build_method_prototype_list_template (tree, int);
  static tree build_method_prototype_template (void);
@@ -274,7 +303,6 @@ static tree generate_dispatch_table (tre
  static tree build_shared_structure_initializer (tree, tree, tree, tree,
                                                 tree, int, tree, tree, 
tree);
  static void generate_category (tree);
-static int is_objc_type_qualifier (tree);
  static tree adjust_type_for_id_default (tree);
  static tree check_duplicates (hash, int, int);
  static tree receiver_is_class_object (tree, int, int);
@@ -282,7 +310,6 @@ static int check_methods (tree, tree, in
  static int conforms_to_protocol (tree, tree);
  static void check_protocol (tree, const char *, const char *);
  static void check_protocols (tree, const char *, const char *);
-static void gen_declspecs (tree, char *, int);
  static void generate_classref_translation_entry (tree);
  static void handle_class_ref (tree);
  static void generate_struct_by_value_array (void)
@@ -294,32 +321,34 @@ static void generate_objc_image_info (vo

  /* Reserved tag definitions.  */

-#define TYPE_ID                        "id"
-#define TAG_OBJECT             "objc_object"
-#define TAG_CLASS              "objc_class"
-#define TAG_SUPER              "objc_super"
-#define TAG_SELECTOR           "objc_selector"
-
-#define UTAG_CLASS             "_objc_class"
-#define UTAG_IVAR              "_objc_ivar"
-#define UTAG_IVAR_LIST         "_objc_ivar_list"
-#define UTAG_METHOD            "_objc_method"
-#define UTAG_METHOD_LIST       "_objc_method_list"
-#define UTAG_CATEGORY          "_objc_category"
-#define UTAG_MODULE            "_objc_module"
-#define UTAG_SYMTAB            "_objc_symtab"
-#define UTAG_SUPER             "_objc_super"
-#define UTAG_SELECTOR          "_objc_selector"
-
-#define UTAG_PROTOCOL          "_objc_protocol"
-#define UTAG_METHOD_PROTOTYPE  "_objc_method_prototype"
-#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
+#define OBJECT_TYPEDEF_NAME            "id"
+#define CLASS_TYPEDEF_NAME             "Class"
+
+#define TAG_OBJECT                     "objc_object"
+#define TAG_CLASS                      "objc_class"
+#define TAG_SUPER                      "objc_super"
+#define TAG_SELECTOR                   "objc_selector"
+
+#define UTAG_CLASS                     "_objc_class"
+#define UTAG_IVAR                      "_objc_ivar"
+#define UTAG_IVAR_LIST                 "_objc_ivar_list"
+#define UTAG_METHOD                    "_objc_method"
+#define UTAG_METHOD_LIST               "_objc_method_list"
+#define UTAG_CATEGORY                  "_objc_category"
+#define UTAG_MODULE                    "_objc_module"
+#define UTAG_SYMTAB                    "_objc_symtab"
+#define UTAG_SUPER                     "_objc_super"
+#define UTAG_SELECTOR                  "_objc_selector"
+
+#define UTAG_PROTOCOL                  "_objc_protocol"
+#define UTAG_METHOD_PROTOTYPE          "_objc_method_prototype"
+#define UTAG_METHOD_PROTOTYPE_LIST     "_objc__method_prototype_list"

  /* Note that the string object global name is only needed for the
     NeXT runtime.  */
-#define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
+#define STRING_OBJECT_GLOBAL_FORMAT    "_%sClassReference"

-#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
+#define PROTOCOL_OBJECT_CLASS_NAME     "Protocol"

  static const char *TAG_GETCLASS;
  static const char *TAG_GETMETACLASS;
@@ -329,7 +358,6 @@ static const char *TAG_MSGSENDSUPER;
     when returning a structure. */
  static const char *TAG_MSGSEND_STRET;
  static const char *TAG_MSGSENDSUPER_STRET;
-static const char *TAG_EXECCLASS;
  static const char *default_constant_string_class_name;

  /* Runtime metadata flags.  */
@@ -348,6 +376,8 @@ static const char *default_constant_stri
  #define OBJC_MODIFIER_TRANSIENT                0x00000200
  #define OBJC_MODIFIER_NONE_SPECIFIED   0x80000000

+/* NeXT-specific tags.  */
+
  #define TAG_MSGSEND_NONNIL             "objc_msgSendNonNil"
  #define TAG_MSGSEND_NONNIL_STRET       "objc_msgSendNonNil_stret"
  #define TAG_EXCEPTIONEXTRACT           "objc_exception_extract"
@@ -358,10 +388,13 @@ static const char *default_constant_stri
  #define TAG_SYNCENTER                  "objc_sync_enter"
  #define TAG_SYNCEXIT                   "objc_sync_exit"
  #define TAG_SETJMP                     "_setjmp"
-#define TAG_RETURN_STRUCT              "objc_return_struct"
-
  #define UTAG_EXCDATA                   "_objc_exception_data"

+/* GNU-specific tags.  */
+
+#define TAG_EXECCLASS                  "__objc_exec_class"
+#define TAG_GNUINIT                    "__objc_gnu_init"
+
  /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
  tree objc_global_trees[OCTI_MAX];

@@ -371,6 +404,9 @@ struct imp_entry *imp_list = 0;
  int imp_count = 0;     /* `@implementation' */
  int cat_count = 0;     /* `@category' */

+enum tree_code objc_inherit_code;
+int objc_public_flag;
+
  /* Use to generate method labels.  */
  static int method_slot = 0;

@@ -388,6 +424,23 @@ extern const char *dump_base_name;


  static int flag_typed_selectors;

+/* Store all constructed constant strings in a hash table so that
+   they get uniqued properly.  */
+
+struct string_descriptor GTY(())
+{
+  /* The literal argument .  */
+  tree literal;
+
+  /* The resulting constant string.  */
+  tree constructor;
+};
+
+static GTY((param_is (struct string_descriptor))) htab_t string_htab;
+
+static hashval_t string_hash (const void *);
+static int string_eq (const void *, const void *);
+
  FILE *gen_declaration_file;

  /* Tells "encode_pointer/encode_aggregate" whether we are generating
@@ -419,17 +472,15 @@ generate_struct_by_value_array (void)
        type = start_struct (RECORD_TYPE, NULL_TREE);

        strcpy (buffer, "c1");
-      field_decl = create_builtin_decl (FIELD_DECL,
-                                       char_type_node,
-                                       buffer);
+      field_decl = create_field_decl (char_type_node,
+                                     buffer);
        field_decl_chain = field_decl;

        for (j = 1; j < i; j++)
         {
           sprintf (buffer, "c%d", j + 1);
-         field_decl = create_builtin_decl (FIELD_DECL,
-                                           char_type_node,
-                                           buffer);
+         field_decl = create_field_decl (char_type_node,
+                                         buffer);
           chainon (field_decl_chain, field_decl);
         }
        finish_struct (type, field_decl_chain, NULL_TREE);
@@ -463,7 +514,11 @@ generate_struct_by_value_array (void)
  bool
  objc_init (void)
  {
+#ifdef OBJCPLUS
+  if (cxx_init () == false)
+#else
    if (c_objc_common_init () == false)
+#endif
      return false;

    /* Force the line number back to 0; check_newline will have
@@ -489,7 +544,6 @@ objc_init (void)
        TAG_MSGSENDSUPER = "objc_msgSendSuper";
        TAG_MSGSEND_STRET = "objc_msgSend_stret";
        TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
-      TAG_EXECCLASS = "__objc_execClass";
        default_constant_string_class_name = "NSConstantString";
      }
    else
@@ -500,13 +554,10 @@ objc_init (void)
        TAG_MSGSENDSUPER = "objc_msg_lookup_super";
        /* GNU runtime does not provide special functions to support
          structure-returning methods.  */
-      TAG_EXECCLASS = "__objc_exec_class";
        default_constant_string_class_name = "NXConstantString";
        flag_typed_selectors = 1;
      }

-  objc_ellipsis_node = make_node (ERROR_MARK);
-
    init_objc ();

    if (print_struct_values)
@@ -520,6 +571,12 @@ objc_finish_file (void)
  {
    mark_referenced_methods ();

+#ifdef OBJCPLUS
+  /* We need to instantiate templates _before_ we emit ObjC metadata;
+     if we do not, some metadata (such as selectors) may go missing.  
*/
+  instantiate_pending_templates ();
+#endif
+
    /* Finalize Objective-C runtime data.  No need to generate tables
       and code if only checking syntax.  */
    if (!flag_syntax_only)
@@ -527,16 +584,12 @@ objc_finish_file (void)

    if (gen_declaration_file)
      fclose (gen_declaration_file);
+
+#ifdef OBJCPLUS
+  cp_finish_file ();
+#endif
  }


-static tree
-define_decl (tree declarator, tree declspecs)
-{
-  tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
-  finish_decl (decl, NULL_TREE, NULL_TREE);
-  return decl;
-}
-
  /* Return the first occurrence of a method declaration corresponding
     to sel_name in rproto_list.  Search rproto_list recursively.
     If is_class is 0, search for instance methods, otherwise for class
@@ -608,6 +661,151 @@ lookup_protocol_in_reflist (tree rproto_
    return 0;
  }

+void
+objc_start_class_interface (tree class, tree super_class, tree protos)
+{
+  objc_interface_context
+    = objc_ivar_context
+    = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
+  objc_public_flag = 0;
+}
+
+void
+objc_start_category_interface (tree class, tree categ, tree protos)
+{
+  objc_interface_context
+    = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
+  objc_ivar_chain
+    = continue_class (objc_interface_context);
+}
+
+void
+objc_start_protocol (tree name, tree protos)
+{
+  objc_interface_context
+    = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
+}
+
+void
+objc_continue_interface (void)
+{
+  objc_ivar_chain
+    = continue_class (objc_interface_context);
+}
+
+void
+objc_finish_interface (void)
+{
+  finish_class (objc_interface_context);
+  objc_interface_context = NULL_TREE;
+}
+
+void
+objc_start_class_implementation (tree class, tree super_class)
+{
+  objc_implementation_context
+    = objc_ivar_context
+    = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, 
NULL_TREE);
+  objc_public_flag = 0;
+}
+
+void
+objc_start_category_implementation (tree class, tree categ)
+{
+  objc_implementation_context
+    = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, 
NULL_TREE);
+  objc_ivar_chain
+    = continue_class (objc_implementation_context);
+}
+
+void
+objc_continue_implementation (void)
+{
+  objc_ivar_chain
+    = continue_class (objc_implementation_context);
+}
+
+void
+objc_finish_implementation (void)
+{
+  if (objc_implementation_context)
+    {
+      finish_class (objc_implementation_context);
+      objc_ivar_chain = NULL_TREE;
+      objc_implementation_context = NULL_TREE;
+    }
+  else
+    warning ("`@end' must appear in an @implementation context");
+}
+
+void
+objc_set_visibility (int visibility)
+{
+  objc_public_flag = visibility;
+}
+
+void
+objc_set_method_type (enum tree_code type)
+{
+  objc_inherit_code = (type == PLUS_EXPR
+                      ? CLASS_METHOD_DECL
+                      : INSTANCE_METHOD_DECL);
+}
+
+tree
+objc_build_method_signature (tree rettype, tree selector, tree 
optparms)
+{
+  return build_method_decl (objc_inherit_code, rettype, selector, 
optparms);
+}
+
+void
+objc_add_method_declaration (tree decl)
+{
+  if (!objc_interface_context)
+    fatal_error ("method declaration not in @interface context");
+
+  objc_add_method (objc_interface_context,
+                  decl,
+                  objc_inherit_code == CLASS_METHOD_DECL);
+}
+
+void
+objc_start_method_definition (tree decl)
+{
+  if (!objc_implementation_context)
+    fatal_error ("method definition not in @implementation context");
+
+  objc_add_method (objc_implementation_context,
+                  decl,
+                  objc_inherit_code == CLASS_METHOD_DECL);
+  start_method_def (decl);
+}
+
+void
+objc_add_instance_variable (tree decl)
+{
+  (void) add_instance_variable (objc_ivar_context,
+                               objc_public_flag,
+                               decl);
+}
+
+/* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context 
of
+   an '@'.  */
+
+int
+objc_is_reserved_word (tree ident)
+{
+  unsigned char code = C_RID_CODE (ident);
+
+  return (OBJC_IS_AT_KEYWORD (code)
+#ifdef OBJCPLUS
+         || code == RID_CLASS || code == RID_PUBLIC
+         || code == RID_PROTECTED || code == RID_PRIVATE
+         || code == RID_TRY || code == RID_THROW || code == RID_CATCH
+#endif
+           );
+}
+
  /* Return true if TYPE is 'id'.  */

  static bool
@@ -944,67 +1142,31 @@ objc_check_decl (tree decl)

    if (TREE_CODE (type) != RECORD_TYPE)
      return;
-  if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
+  if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name 
(OBJC_TYPE_NAME (type))))
      error ("statically allocated instance of Objective-C class `%s'",
            IDENTIFIER_POINTER (type));
  }

-/* Implement static typing.  At this point, we know we have an 
interface.  */
-
-tree
-get_static_reference (tree interface, tree protocols)
-{
-  tree type = xref_tag (RECORD_TYPE, interface);
-
-  if (protocols)
-    {
-      tree t, m = TYPE_MAIN_VARIANT (type);
-
-      t = copy_node (type);
-
-      /* 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.  Note
-        that the protocol list can have a different lifetime than T!  
*/
-      SET_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) = NULL_TREE;
-
-      type = t;
-    }
-
-  return type;
-}
+/* Construct a PROTOCOLS-qualified variant of INTERFACE, where 
INTERFACE may
+   either name an Objective-C class, or refer to the special 'id' or 
'Class'
+   types.  If INTERFACE is not a valid ObjC type, just return it 
unchanged.  */

-/* Return a declaration corresponding to a protocol list qualified 
'id'. */
  tree
-get_protocol_reference (tree protocols)
+objc_get_protocol_qualified_type (tree interface, tree protocols)
  {
-  tree type_decl = lookup_name (objc_id_id);
    tree type;

-  if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
+  if (!interface)
+    type = objc_object_type;
+  else if (!(type = objc_is_id (interface)))
      {
-      type = TREE_TYPE (type_decl);
-      if (TYPE_MAIN_VARIANT (type) != objc_id_type)
-       warning ("unexpected type for `id' (%s)",
-                gen_declaration (type, errbuf));
-    }
-  else
-    {
-      error ("undefined type `id', please import <objc/objc.h>");
-      return error_mark_node;
-    }
+      type = objc_is_class_name (interface);

-  /* This clause creates a new pointer type that is qualified with
-     the protocol specification...this info is used later to do more
-     elaborate type checking.  */
+      if (type)
+       type = xref_tag (RECORD_TYPE, type);
+      else
+        return interface;
+    }

    if (protocols)
      {
@@ -1016,7 +1178,8 @@ get_protocol_reference (tree protocols)
        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!  
*/
        SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols 
(protocols));

        /* This forces a new pointer type to be created later
@@ -1027,6 +1190,7 @@ get_protocol_reference (tree protocols)

        type = t;
      }
+
    return type;
  }

@@ -1079,24 +1243,44 @@ lookup_and_install_protocols (tree proto
    return return_value;
  }

-/* Create and push a decl for a built-in external variable or field 
NAME.
-   CODE says which.
-   TYPE is its data type.  */
+/* Create a declaration for field NAME of a given TYPE.  */

  static tree
-create_builtin_decl (enum tree_code code, tree type, const char *name)
+create_field_decl (tree type, const char *name)
  {
-  tree decl = build_decl (code, get_identifier (name), type);
+  return build_decl (FIELD_DECL, get_identifier (name), type);
+}

-  if (code == VAR_DECL)
-    {
-      TREE_STATIC (decl) = 1;
-      make_decl_rtl (decl);
-      pushdecl (decl);
-      DECL_ARTIFICIAL (decl) = 1;
-    }
+/* Create a global, static declaration for variable NAME of a given 
TYPE.  The
+   finish_var_decl() routine will need to be called on it afterwards.  
*/

-  return decl;
+static tree
+start_var_decl (tree type, const char *name)
+{
+  tree var = build_decl (VAR_DECL, get_identifier (name), type);
+
+  TREE_STATIC (var) = 1;
+  DECL_INITIAL (var) = error_mark_node;  /* A real initializer is 
coming... */
+  DECL_IGNORED_P (var) = 1;
+  DECL_ARTIFICIAL (var) = 1;
+  DECL_CONTEXT (var) = NULL_TREE;
+#ifdef OBJCPLUS
+  DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
+#endif
+
+  return var;
+}
+
+/* Finish off the variable declaration created by start_var_decl().  */
+
+static void
+finish_var_decl (tree var, tree initializer)
+{
+  finish_decl (var, initializer, NULL_TREE);
+  /* Ensure that the variable actually gets output.  */
+  mark_decl_referenced (var);
+  /* Mark the decl to avoid "defined but not used" warning.  */
+  TREE_USED (var) = 1;
  }

  /* Find the decl for the constant string class.  */
@@ -1136,22 +1320,50 @@ setup_string_decl (void)
  static void
  synth_module_prologue (void)
  {
-  tree temp_type;
+  tree type;
+  enum debug_info_type save_write_symbols = write_symbols;
+  const struct gcc_debug_hooks *const save_hooks = debug_hooks;
+
+  /* Suppress outputting debug symbols, because
+     dbxout_init hasn'r been called yet.  */
+  write_symbols = NO_DEBUG;
+  debug_hooks = &do_nothing_debug_hooks;
+
+#ifdef OBJCPLUS
+  push_lang_context (lang_name_c); /* extern "C" */
+#endif
+
+  /* The following are also defined in <objc/objc.h> and friends.  */

-  /* Defined in `objc.h' */
    objc_object_id = get_identifier (TAG_OBJECT);
+  objc_class_id = get_identifier (TAG_CLASS);

    objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
+  objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
+
+  objc_object_type = build_pointer_type (objc_object_reference);
+  objc_class_type = build_pointer_type (objc_class_reference);

-  objc_id_type = build_pointer_type (objc_object_reference);
+  objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
+  objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);

-  objc_id_id = get_identifier (TYPE_ID);
-  objc_class_id = get_identifier (TAG_CLASS);
+  /* Declare the 'id' and 'Class' typedefs.  */

-  objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, 
objc_class_id));
-  temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
-  objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
-  objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, 
temp_type));
+  type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+                                               objc_object_name,
+                                               objc_object_type));
+  DECL_IN_SYSTEM_HEADER (type) = 1;
+  type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+                                               objc_class_name,
+                                               objc_class_type));
+  DECL_IN_SYSTEM_HEADER (type) = 1;
+
+  /* Forward-declare '@interface Protocol'.  */
+
+  type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
+  objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
+  objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
+                                type));

    /* Declare type of selector-objects that represent an operation 
name.  */

@@ -1185,38 +1397,36 @@ synth_module_prologue (void)
        /* id objc_msgSendNonNil (id, SEL, ...); */
        /* id objc_msgSend_stret (id, SEL, ...); */
        /* id objc_msgSendNonNil_stret (id, SEL, ...); */
-      temp_type
-       = build_function_type (objc_id_type,
-                              tree_cons (NULL_TREE, objc_id_type,
-                                         tree_cons (NULL_TREE,
-                                                    objc_selector_type,
+      type
+       = build_function_type (objc_object_type,
+                              tree_cons (NULL_TREE, objc_object_type,
+                                         tree_cons (NULL_TREE, 
objc_selector_type,
                                                      NULL_TREE)));
        umsg_decl = builtin_function (TAG_MSGSEND,
-                                   temp_type, 0, NOT_BUILT_IN,
+                                   type, 0, NOT_BUILT_IN,
                                     NULL, NULL_TREE);
        umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
-                                          temp_type, 0, NOT_BUILT_IN,
+                                          type, 0, NOT_BUILT_IN,
                                            NULL, NULL_TREE);
        umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
-                                         temp_type, 0, NOT_BUILT_IN,
+                                         type, 0, NOT_BUILT_IN,
                                           NULL, NULL_TREE);
        umsg_nonnil_stret_decl = builtin_function 
(TAG_MSGSEND_NONNIL_STRET,
-                                                temp_type, 0, 
NOT_BUILT_IN,
+                                                type, 0, NOT_BUILT_IN,
                                                  NULL, NULL_TREE);

        /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
        /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
-      temp_type
-       = build_function_type (objc_id_type,
+      type
+       = build_function_type (objc_object_type,
                                tree_cons (NULL_TREE, objc_super_type,
-                                         tree_cons (NULL_TREE,
-                                                    objc_selector_type,
+                                         tree_cons (NULL_TREE, 
objc_selector_type,
                                                      NULL_TREE)));
        umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
-                                         temp_type, 0, NOT_BUILT_IN,
+                                         type, 0, NOT_BUILT_IN,
                                           NULL, NULL_TREE);
        umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
-                                               temp_type, 0, 
NOT_BUILT_IN, 0,
+                                               type, 0, NOT_BUILT_IN, 
0,
                                                 NULL_TREE);
      }
    else
@@ -1226,86 +1436,73 @@ synth_module_prologue (void)
        /* typedef id (*IMP)(id, SEL, ...); */
        tree IMP_type
         = build_pointer_type
-         (build_function_type (objc_id_type,
-                               tree_cons (NULL_TREE, objc_id_type,
-                                          tree_cons (NULL_TREE,
-                                                     
objc_selector_type,
+         (build_function_type (objc_object_type,
+                               tree_cons (NULL_TREE, objc_object_type,
+                                          tree_cons (NULL_TREE, 
objc_selector_type,
                                                       NULL_TREE))));

        /* IMP objc_msg_lookup (id, SEL); */
-      temp_type
+      type
          = build_function_type (IMP_type,
-                               tree_cons (NULL_TREE, objc_id_type,
-                                          tree_cons (NULL_TREE,
-                                                    objc_selector_type,
-                                                     void_list_node)));
+                              tree_cons (NULL_TREE, objc_object_type,
+                                         tree_cons (NULL_TREE, 
objc_selector_type,
+                                                    
OBJC_VOID_AT_END)));
        umsg_decl = builtin_function (TAG_MSGSEND,
-                                   temp_type, 0, NOT_BUILT_IN,
+                                   type, 0, NOT_BUILT_IN,
                                     NULL, NULL_TREE);

        /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
-      temp_type
+      type
          = build_function_type (IMP_type,
-                               tree_cons (NULL_TREE, objc_super_type,
-                                          tree_cons (NULL_TREE,
-                                                    objc_selector_type,
-                                                     void_list_node)));
+                              tree_cons (NULL_TREE, objc_super_type,
+                                         tree_cons (NULL_TREE, 
objc_selector_type,
+                                                    
OBJC_VOID_AT_END)));
        umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
-                                         temp_type, 0, NOT_BUILT_IN,
+                                         type, 0, NOT_BUILT_IN,
                                           NULL, NULL_TREE);
+
+      /* The following GNU runtime entry point is called to initialize
+        each module:
+
+        __objc_exec_class (void *); */
+      type
+       = build_function_type (void_type_node,
+                              tree_cons (NULL_TREE, ptr_type_node,
+                                         OBJC_VOID_AT_END));
+      execclass_decl = builtin_function (TAG_EXECCLASS,
+                                        type, 0, NOT_BUILT_IN,
+                                        NULL, NULL_TREE);
      }

    /* id objc_getClass (const char *); */

-  temp_type = build_function_type (objc_id_type,
+  type = build_function_type (objc_object_type,
                                    tree_cons (NULL_TREE,
                                               const_string_type_node,
-                                             void_list_node));
+                                             OBJC_VOID_AT_END));

    objc_get_class_decl
-    = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
+    = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
                         NULL, NULL_TREE);

    /* id objc_getMetaClass (const char *); */

    objc_get_meta_class_decl
-    = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
+    = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, 
NULL_TREE);

+  build_class_template ();
    build_super_template ();
+  build_protocol_template ();
+  build_category_template ();
    build_objc_exception_stuff ();
+
    if (flag_next_runtime)
      build_next_objc_exception_stuff ();

    /* static SEL _OBJC_SELECTOR_TABLE[]; */

    if (! flag_next_runtime)
-    {
-      if (flag_typed_selectors)
-       {
-         /* Suppress outputting debug symbols, because
-            dbxout_init hasn'r been called yet.  */
-         enum debug_info_type save_write_symbols = write_symbols;
-         const struct gcc_debug_hooks *const 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 (objc_selector_type, NULL_TREE);
-
-      layout_type (temp_type);
-      UOBJC_SELECTOR_TABLE_decl
-       = create_builtin_decl (VAR_DECL, temp_type,
-                              "_OBJC_SELECTOR_TABLE");
-
-      /* Avoid warning when not sending messages.  */
-      TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1;
-    }
+    build_selector_table_decl ();

    /* Forward declare constant_string_id and constant_string_type.  */
    if (!constant_string_class_name)
@@ -1320,7 +1517,14 @@ synth_module_prologue (void)
  #ifndef OBJCPLUS
    /* The C++ front-end does not appear to grok 
__attribute__((__unused__)).  */
    unused_list = build_tree_list (get_identifier ("__unused__"), 
NULL_TREE);
-#endif
+#endif
+
+#ifdef OBJCPLUS
+  pop_lang_context ();
+#endif
+
+  write_symbols = save_write_symbols;
+  debug_hooks = save_hooks;
  }

  /* Ensure that the ivar list for NSConstantString/NXConstantString
@@ -1369,6 +1573,33 @@ my_build_string (int len, const char *st
    return fix_string_type (build_string (len, str));
  }

+
+static hashval_t
+string_hash (const void *ptr)
+{
+  tree str = ((struct string_descriptor *)ptr)->literal;
+  const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER 
(str);
+  int i, len = TREE_STRING_LENGTH (str);
+  hashval_t h = len;
+
+  for (i = 0; i < len; i++)
+    h = ((h * 613) + p[i]);
+
+  return h;
+}
+
+static int
+string_eq (const void *ptr1, const void *ptr2)
+{
+  tree str1 = ((struct string_descriptor *)ptr1)->literal;
+  tree str2 = ((struct string_descriptor *)ptr2)->literal;
+  int len1 = TREE_STRING_LENGTH (str1);
+
+  return (len1 == TREE_STRING_LENGTH (str2)
+         && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER 
(str2),
+                     len1));
+}
+
  /* 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
@@ -1377,13 +1608,29 @@ my_build_string (int len, const char *st
     NXConstantString class object.  */

  tree
-build_objc_string_object (tree string)
+objc_build_string_object (tree string)
  {
    tree initlist, constructor, constant_string_class;
    int length;
    tree fields;
+  struct string_descriptor *desc, key;
+  void **loc;

    string = fix_string_type (string);
+  TREE_SET_CODE (string, STRING_CST);
+  length = TREE_STRING_LENGTH (string) - 1;
+
+  /* Perhaps we already constructed a constant string just like this 
one? */
+  key.literal = string;
+  loc = htab_find_slot (string_htab, &key, INSERT);
+  desc = *loc;
+
+  if (desc)
+    return desc->constructor;
+
+  *loc = desc = ggc_alloc (sizeof (*desc));
+  desc->literal = string;
+  desc->constructor = error_mark_node;  /* For now.  */

    constant_string_class = lookup_interface (constant_string_id);
    if (!constant_string_class
@@ -1395,37 +1642,35 @@ build_objc_string_object (tree string)
        return error_mark_node;
      }

-  /* Call to 'combine_strings' has been moved above.  */
-  TREE_SET_CODE (string, STRING_CST);
-  length = TREE_STRING_LENGTH (string) - 1;
-
    if (!string_layout_checked)
      {
-      /* The NSConstantString/NXConstantString ivar layout is now
-        known.  */
+      /* The NSConstantString/NXConstantString ivar layout is now 
known.  */
        if (!check_string_class_template ())
         {
           error ("interface `%s' does not have valid constant string 
layout",
                  IDENTIFIER_POINTER (constant_string_id));
           return error_mark_node;
         }
+
        add_class_reference (constant_string_id);
      }
+
    fields = TYPE_FIELDS (constant_string_type);

    /* & ((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
         (fields,
          copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
@@ -1446,6 +1691,7 @@ build_objc_string_object (tree string)
    initlist = tree_cons (fields, build_int_cst (NULL_TREE, length, 0), 
initlist);
    constructor = objc_build_constructor (constant_string_type,
                                         nreverse (initlist));
+  TREE_INVARIANT (constructor) = true;

    if (!flag_next_runtime)
      {
@@ -1455,7 +1701,10 @@ build_objc_string_object (tree string)

    constructor = build_unary_op (ADDR_EXPR, constructor, 1);
    TREE_CONSTANT (constructor) = true;
-  return constructor;
+  TREE_INVARIANT (constructor) = true;
+  TREE_STATIC (constructor) = true;
+
+  return (desc->constructor = constructor);
  }

  /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. 
  */
@@ -1504,36 +1753,20 @@ objc_add_static_instance (tree construct
  static tree
  objc_build_constructor (tree type, 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 && f; 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));
-    }
+  tree constructor = build_constructor (type, elts);

-  constructor = build_constructor (type, elts);
    TREE_CONSTANT (constructor) = 1;
    TREE_STATIC (constructor) = 1;
    TREE_READONLY (constructor) = 1;

  #ifdef OBJCPLUS
-  /* zlaski 2001-Apr-02: mark this as a call to a constructor, as 
required by
-     build_unary_op (wasn't true in 2.7.2.1 days) */
+  /* Adjust for impedance mismatch.  We should figure out how to build
+     CONSTRUCTORs that consistently please both the C and C++ gods.  */
+  if (!TREE_PURPOSE (elts))
+    TREE_TYPE (constructor) = NULL_TREE;
    TREE_HAS_CONSTRUCTOR (constructor) = 1;
  #endif
+
    return constructor;
  }


@@ -1559,31 +1792,21 @@ build_objc_symtab_template (void)
      = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));

    /* long sel_ref_cnt; */
-
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   long_integer_type_node,
-                                   "sel_ref_cnt");
+  field_decl = create_field_decl (long_integer_type_node, 
"sel_ref_cnt");
    field_decl_chain = field_decl;

    /* SEL *refs; */
-
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   build_pointer_type 
(objc_selector_type),
-                                   "refs");
+  field_decl = create_field_decl (build_pointer_type 
(objc_selector_type),
+                                 "refs");
    chainon (field_decl_chain, field_decl);

    /* short cls_def_cnt; */
-
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   short_integer_type_node,
-                                   "cls_def_cnt");
+  field_decl = create_field_decl (short_integer_type_node, 
"cls_def_cnt");
    chainon (field_decl_chain, field_decl);

    /* short cat_def_cnt; */
-
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   short_integer_type_node,
-                                   "cat_def_cnt");
+  field_decl = create_field_decl (short_integer_type_node,
+                                 "cat_def_cnt");
    chainon (field_decl_chain, field_decl);

    if (imp_count || cat_count || !flag_next_runtime)
@@ -1592,9 +1815,8 @@ build_objc_symtab_template (void)
        /* NB: The index is one less than the size of the array.  */
        int index = imp_count + cat_count
                 + (flag_next_runtime? -1: 0);
-      field_decl = create_builtin_decl
-                  (FIELD_DECL,
-                   build_array_type
+      field_decl = create_field_decl
+                  (build_array_type
                     (ptr_type_node,
                      build_index_type (build_int_cst (NULL_TREE, index, 
0))),
                     "defs");
@@ -1665,10 +1887,12 @@ init_objc_symtab (tree type)
    if (flag_next_runtime || ! sel_ref_chain)
      initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), 
initlist);
    else
-    initlist = tree_cons (NULL_TREE,
-                         build_unary_op (ADDR_EXPR,
-                                         UOBJC_SELECTOR_TABLE_decl, 1),
-                         initlist);
+    initlist
+      = tree_cons (NULL_TREE,
+                  convert (build_pointer_type (objc_selector_type),
+                           build_unary_op (ADDR_EXPR,
+                                           UOBJC_SELECTOR_TABLE_decl, 
1)),
+                  initlist);

    /* cls_def_cnt = { ..., 5, ... } */

@@ -1699,17 +1923,13 @@ init_objc_symtab (tree type)
  static tree
  build_metadata_decl (const char *name, tree type)
  {
-  tree decl, decl_specs;
-  /* extern struct TYPE NAME_<name>; */
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_EXTERN]);
-  decl_specs = tree_cons (NULL_TREE, type, decl_specs);
-  decl = define_decl (synth_id_with_class_suffix
-                     (name,
-                      objc_implementation_context),
-                     decl_specs);
-  TREE_USED (decl) = 1;
-  DECL_ARTIFICIAL (decl) = 1;
-  TREE_PUBLIC (decl) = 0;
+  tree decl;
+
+  /* struct TYPE NAME_<name>; */
+  decl = start_var_decl (type, synth_id_with_class_suffix
+                              (name,
+                               objc_implementation_context));
+
    return decl;
  }

@@ -1730,7 +1950,7 @@ forward_declare_categories (void)
           objc_implementation_context = impent->imp_context;
           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
-                                                   
objc_category_template);
+                                                   
objc_category_template);
         }
      }
    objc_implementation_context = sav;
@@ -1742,32 +1962,14 @@ forward_declare_categories (void)
  static void
  generate_objc_symtab_decl (void)
  {
-  tree sc_spec;
-
-  if (!objc_category_template)
-    build_category_template ();
-
    /* forward declare categories */
    if (cat_count)
      forward_declare_categories ();

-  if (!objc_symtab_template)
-    build_objc_symtab_template ();
-
-  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
-
-  UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"),
-                                  tree_cons (NULL_TREE,
-                                             objc_symtab_template, 
sc_spec),
-                                  1,
-                                  NULL_TREE);
-
-  TREE_USED (UOBJC_SYMBOLS_decl) = 1;
-  DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1;
-  DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1;
-  finish_decl (UOBJC_SYMBOLS_decl,
-              init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)),
-              NULL_TREE);
+  build_objc_symtab_template ();
+  UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, 
"_OBJC_SYMBOLS");
+  finish_var_decl (UOBJC_SYMBOLS_decl,
+                  init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
  }


  static tree
@@ -1780,7 +1982,7 @@ init_module_descriptor (tree type)
    expr = build_int_cst (NULL_TREE, OBJC_VERSION, 0);
    initlist = build_tree_list (NULL_TREE, expr);

-  /* size = { ..., sizeof (struct objc_module), ... } */
+  /* size = { ..., sizeof (struct _objc_module), ... } */

    expr = size_in_bytes (objc_module_template);
    initlist = tree_cons (NULL_TREE, expr, initlist);
@@ -1802,132 +2004,124 @@ init_module_descriptor (tree 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 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 = { ... };   */
+   struct _objc_module { ... } _OBJC_MODULE = { ... };   */

-static rtx
+static void
  build_module_descriptor (void)
  {
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;
+
+#ifdef OBJCPLUS
+  push_lang_context (lang_name_c); /* extern "C" */
+#endif

    objc_module_template
      = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));

-  /* Long version; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_LONG]);
-  field_decl = get_identifier ("version");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* long version; */
+  field_decl = create_field_decl (long_integer_type_node, "version");
    field_decl_chain = field_decl;

-  /* long  size; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_LONG]);
-  field_decl = get_identifier ("size");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* long size; */
+  field_decl = create_field_decl (long_integer_type_node, "size");
    chainon (field_decl_chain, field_decl);

-  /* char  *name; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("name"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* char *name; */
+  field_decl = create_field_decl (string_type_node, "name");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_symtab *symtab; */
-
-  decl_specs = get_identifier (UTAG_SYMTAB);
-  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, 
decl_specs));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("symtab"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_symtab *symtab; */
+  field_decl
+    = create_field_decl (build_pointer_type
+                        (xref_tag (RECORD_TYPE,
+                                   get_identifier (UTAG_SYMTAB))),
+                        "symtab");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_module_template, field_decl_chain, NULL_TREE);

-  /* Create an instance of "objc_module".  */
+  /* Create an instance of "_objc_module".  */
+  UOBJC_MODULES_decl = start_var_decl (objc_module_template, 
"_OBJC_MODULES");
+  finish_var_decl (UOBJC_MODULES_decl,
+                  init_module_descriptor (TREE_TYPE 
(UOBJC_MODULES_decl)));

-  decl_specs = tree_cons (NULL_TREE, objc_module_template,
-                         build_tree_list (NULL_TREE,
-                                          ridpointers[(int) 
RID_STATIC]));
-
-  UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"),
-                                  decl_specs, 1, 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);
+#ifdef OBJCPLUS
+  pop_lang_context ();
+#endif
+}

-  /* Mark the decl to avoid "defined but not used" warning.  */
-  DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
-
-  mark_decl_referenced (UOBJC_MODULES_decl);
+/* The GNU runtime requires us to provide a static initializer function
+   for each module:

-  /* Generate a constructor call for the module descriptor.
-     This code was generated by reading the grammar rules
-     of c-parse.in;  Therefore, it may not be the most efficient
-     way of generating the requisite code.  */
+   static void __objc_gnu_init (void) {
+     __objc_exec_class (&L_OBJC_MODULES);
+   }  */

-  if (flag_next_runtime)
-    return NULL_RTX;
+static void
+build_module_initializer_routine (void)
+{
+  tree body;
+
+#ifdef OBJCPLUS
+  push_lang_context (lang_name_c); /* extern "C" */
+#endif
+
+  objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
+  objc_start_function (get_identifier (TAG_GNUINIT),
+                      build_function_type (void_type_node,
+                                           OBJC_VOID_AT_END),
+                      NULL_TREE, objc_get_parm_info (0));
+
+  body = c_begin_compound_stmt (true);
+  add_stmt (build_function_call
+           (execclass_decl,
+            build_tree_list
+            (NULL_TREE,
+             build_unary_op (ADDR_EXPR,
+                             UOBJC_MODULES_decl, 0))));
+  add_stmt (c_end_compound_stmt (body, true));
+
+  TREE_PUBLIC (current_function_decl) = 0;
+  DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
+  GNU_INIT_decl = current_function_decl;
+  finish_function ();
+
+#ifdef OBJCPLUS
+    pop_lang_context ();
+#endif
+}

-  {
-    tree parms, execclass_decl, decelerator, void_list_node_1;
-    tree init_function_name, init_function_decl, compound;
-
-    /* Declare void __objc_execClass (void *); */
-
-    void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
-    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)));
-
-    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);
-    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_nt (CALL_EXPR, init_function_name,
-                             tree_cons (NULL_TREE, NULL_TREE,
-                                        void_list_node),
-                             NULL_TREE),
-                   NULL_TREE);
-    store_parm_decls ();
-    compound = c_begin_compound_stmt (true);
-
-    init_function_decl = current_function_decl;
-    TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
-    TREE_USED (init_function_decl) = 1;
-    /* Don't let this one be deferred.  */
-    DECL_INLINE (init_function_decl) = 0;
-    DECL_UNINLINABLE (init_function_decl) = 1;
-
-    parms
-      = build_tree_list (NULL_TREE,
-                        build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 
0));
-    decelerator = build_function_call (execclass_decl, parms);
+/* Return 1 if the __objc_gnu_init function has been synthesized and 
needs
+   to be called by the module initializer routine.  */

-    add_stmt (decelerator);
-    add_stmt (c_end_compound_stmt (compound, true));
+int
+objc_static_init_needed_p (void)
+{
+  return (GNU_INIT_decl != NULL_TREE);
+}

-    finish_function ();
+/* Generate a call to the __objc_gnu_init initializer function.  The 
routine
+   below gets called from within the bowels of C or C++, with a list of
+   initializer functions, from which we must remove __objc_gnu_init.  
*/

-    return XEXP (DECL_RTL (init_function_decl), 0);
-  }
+tree
+objc_generate_static_init_call (tree ctors)
+{
+  tree *ctor_ptr = &ctors;
+
+  add_stmt (build_stmt (EXPR_STMT,
+                       build_function_call (GNU_INIT_decl, 
NULL_TREE)));
+
+  while (*ctor_ptr)
+    {
+      if (TREE_VALUE (*ctor_ptr) == GNU_INIT_decl)
+       *ctor_ptr = TREE_CHAIN (*ctor_ptr);
+      else
+       ctor_ptr = &TREE_CHAIN (*ctor_ptr);
+    }
+
+  return ctors;
  }

  /* Return the DECL of the string IDENT in the SECTION.  */
@@ -1960,9 +2154,10 @@ get_objc_string_decl (tree ident, enum s
  static void
  generate_static_references (void)
  {
-  tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = 
NULL_TREE;
+  tree decls = NULL_TREE, expr = NULL_TREE;
    tree class_name, class, decl, initlist;
-  tree cl_chain, in_chain;
+  tree cl_chain, in_chain, type
+    = build_array_type (build_pointer_type (void_type_node), 
NULL_TREE);
    int num_inst, num_class;
    char buf[256];

@@ -1976,16 +2171,7 @@ generate_static_references (void)
            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));

        sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
-      ident = get_identifier (buf);
-
-      expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, 
NULL_TREE);
-      decl_spec = tree_cons (NULL_TREE, build_pointer_type 
(void_type_node),
-                            build_tree_list (NULL_TREE,
-                                             ridpointers[(int) 
RID_STATIC]));
-      decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
-      DECL_CONTEXT (decl) = 0;
-      DECL_ARTIFICIAL (decl) = 1;
-      TREE_USED (decl) = 1;
+      decl = start_var_decl (type, buf);

        /* Output {class_name, ...}.  */
        class = TREE_VALUE (cl_chain);
@@ -2005,26 +2191,15 @@ generate_static_references (void)
        initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 
0), initlist);

        expr = objc_build_constructor (TREE_TYPE (decl), nreverse 
(initlist));
-      finish_decl (decl, expr, NULL_TREE);
+      finish_var_decl (decl, expr);
        decls
         = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), 
decls);
      }

    decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), 
decls);
-  ident = get_identifier ("_OBJC_STATIC_INSTANCES");
-  expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, 
NULL_TREE);
-  decl_spec = tree_cons (NULL_TREE, build_pointer_type 
(void_type_node),
-                        build_tree_list (NULL_TREE,
-                                         ridpointers[(int) 
RID_STATIC]));
-  static_instances_decl
-    = start_decl (expr_decl, decl_spec, 1, NULL_TREE);
-  TREE_USED (static_instances_decl) = 1;
-  DECL_CONTEXT (static_instances_decl) = 0;
-  DECL_ARTIFICIAL (static_instances_decl) = 1;
-  expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
-                           nreverse (decls));
-  finish_decl (static_instances_decl, expr, NULL_TREE);
-  rest_of_decl_compilation (static_instances_decl, 0, 0);
+  expr = objc_build_constructor (type, nreverse (decls));
+  static_instances_decl = start_var_decl (type, 
"_OBJC_STATIC_INSTANCES");
+  finish_var_decl (static_instances_decl, expr);
  }

  /* Output all strings.  */
@@ -2032,56 +2207,46 @@ generate_static_references (void)
  static void
  generate_strings (void)
  {
-  tree sc_spec, decl_specs, expr_decl;
    tree chain, string_expr;
-  tree string, decl;
+  tree string, decl, type;

    for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
      {
        string = TREE_VALUE (chain);
        decl = TREE_PURPOSE (chain);
-      sc_spec
-       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], 
sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
-                           NULL_TREE, NULL_TREE);
-      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
-      DECL_CONTEXT (decl) = NULL_TREE;
+      type = build_array_type
+            (char_type_node,
+             build_index_type (build_int_2 (IDENTIFIER_LENGTH 
(string), 0)));
+      decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME 
(decl)));
        string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                      IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULL_TREE);
+      finish_var_decl (decl, string_expr);
      }

    for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
      {
        string = TREE_VALUE (chain);
        decl = TREE_PURPOSE (chain);
-      sc_spec
-       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], 
sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
-                           NULL_TREE, NULL_TREE);
-      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
-      DECL_CONTEXT (decl) = NULL_TREE;
+      type = build_array_type
+            (char_type_node,
+             build_index_type (build_int_2 (IDENTIFIER_LENGTH 
(string), 0)));
+      decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME 
(decl)));
        string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                      IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULL_TREE);
+      finish_var_decl (decl, string_expr);
      }

    for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
      {
        string = TREE_VALUE (chain);
        decl = TREE_PURPOSE (chain);
-      sc_spec
-       = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-      decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], 
sc_spec);
-      expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
-                           NULL_TREE, NULL_TREE);
-      decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
-      DECL_CONTEXT (decl) = NULL_TREE;
+      type = build_array_type
+            (char_type_node,
+             build_index_type (build_int_2 (IDENTIFIER_LENGTH 
(string), 0)));
+      decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME 
(decl)));
        string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
-                               IDENTIFIER_POINTER (string));
-      finish_decl (decl, string_expr, NULL_TREE);
+                                    IDENTIFIER_POINTER (string));
+      finish_var_decl (decl, string_expr);
      }
  }

@@ -2090,24 +2255,29 @@ static GTY(()) int selector_reference_id
  static tree
  build_selector_reference_decl (void)
  {
-  tree decl, ident;
+  tree decl;
    char buf[256];

    sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", 
selector_reference_idx++);
+  decl = start_var_decl (objc_selector_type, buf);

-  ident = get_identifier (buf);
+  return decl;
+}

-  decl = build_decl (VAR_DECL, ident, objc_selector_type);
-  DECL_EXTERNAL (decl) = 1;
-  TREE_PUBLIC (decl) = 0;
-  TREE_USED (decl) = 1;
-  DECL_ARTIFICIAL (decl) = 1;
-  DECL_CONTEXT (decl) = 0;
+static void
+build_selector_table_decl (void)
+{
+  tree temp;

-  make_decl_rtl (decl);
-  pushdecl_top_level (decl);
+  if (flag_typed_selectors)
+    {
+      build_selector_template ();
+      temp = build_array_type (objc_selector_template, NULL_TREE);
+    }
+  else
+    temp = build_array_type (objc_selector_type, NULL_TREE);

-  return decl;
+  UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, 
"_OBJC_SELECTOR_TABLE");
  }

  /* Just a handy wrapper for add_objc_string.  */
@@ -2115,20 +2285,16 @@ build_selector_reference_decl (void)
  static tree
  build_selector (tree ident)
  {
-  tree expr = add_objc_string (ident, meth_var_names);
-  if (flag_typed_selectors)
-    return expr;
-  else
-    return build_c_cast (objc_selector_type, expr); /* cast! */
+  return convert (objc_selector_type,
+                 add_objc_string (ident, meth_var_names));
  }

  static void
  build_selector_translation_table (void)
  {
-  tree sc_spec, decl_specs;
    tree chain, initlist = NULL_TREE;
    int offset = 0;
-  tree decl = NULL_TREE, var_decl, name;
+  tree decl = NULL_TREE;

    for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
      {
@@ -2161,28 +2327,14 @@ build_selector_translation_table (void)
        }

        expr = build_selector (TREE_VALUE (chain));
-
-      if (flag_next_runtime)
-       {
-         name = DECL_NAME (TREE_PURPOSE (chain));
-
-         sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_STATIC]);
-
-         /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
-         decl_specs = tree_cons (NULL_TREE, objc_selector_type, 
sc_spec);
-
-         var_decl = name;
-
-         /* 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 );
-       }
-
        /* add one for the '\0' character */
        offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;

        if (flag_next_runtime)
-       finish_decl (decl, expr, NULL_TREE);
+       {
+         decl = TREE_PURPOSE (chain);
+         finish_var_decl (decl, expr);
+       }
        else
         {
           if (flag_typed_selectors)
@@ -2194,13 +2346,25 @@ build_selector_translation_table (void)
               expr = objc_build_constructor (objc_selector_template,
                                              nreverse (eltlist));
             }
-         initlist = tree_cons (NULL_TREE, expr, initlist);

+         initlist = tree_cons (NULL_TREE, expr, initlist);
         }
      }

    if (! flag_next_runtime)
      {
+      /* Cause the selector table (previously forward-declared)
+        to be actually output.  */
+      initlist = tree_cons (NULL_TREE,
+                           flag_typed_selectors
+                           ? objc_build_constructor
+                             (objc_selector_template,
+                              tree_cons (NULL_TREE,
+                                         build_int_cst (NULL_TREE, 0, 
0),
+                                         tree_cons (NULL_TREE,
+                                                    build_int_cst 
(NULL_TREE, 0, 0),
+                                                    NULL_TREE)))
+                           : build_int_cst (NULL_TREE, 0, 0), 
initlist);
        /* Cause the variable and its initial value to be actually 
output.  */
        DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0;
        TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1;
@@ -2209,8 +2373,7 @@ build_selector_translation_table (void)
        DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
        initlist = objc_build_constructor (TREE_TYPE 
(UOBJC_SELECTOR_TABLE_decl),
                                          nreverse (initlist));
-      finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
-      current_function_decl = NULL_TREE;
+      finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
      }
  }

@@ -2260,7 +2423,7 @@ build_typed_selector_reference (tree ide
                          build_array_ref (UOBJC_SELECTOR_TABLE_decl,
                                           build_int_cst (NULL_TREE, 
index, 0)),
                          1);
-  return build_c_cast (objc_selector_type, expr);
+  return convert (objc_selector_type, expr);
  }

  static tree
@@ -2282,7 +2445,7 @@ build_selector_reference (tree ident)
        chain = &TREE_CHAIN (*chain);
      }

-  expr = build_selector_reference_decl ();
+  expr = (flag_next_runtime ? build_selector_reference_decl (): 
NULL_TREE);

    *chain = tree_cons (expr, ident, NULL_TREE);

@@ -2297,22 +2460,11 @@ static GTY(()) int class_reference_idx;
  static tree
  build_class_reference_decl (void)
  {
-  tree decl, ident;
+  tree decl;
    char buf[256];

    sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
-
-  ident = get_identifier (buf);
-
-  decl = build_decl (VAR_DECL, ident, objc_class_type);
-  DECL_EXTERNAL (decl) = 1;
-  TREE_PUBLIC (decl) = 0;
-  TREE_USED (decl) = 1;
-  DECL_CONTEXT (decl) = 0;
-  DECL_ARTIFICIAL (decl) = 1;
-
-  make_decl_rtl (decl);
-  pushdecl_top_level (decl);
+  decl = start_var_decl (objc_class_type, buf);

    return decl;
  }
@@ -2349,7 +2501,7 @@ add_class_reference (tree ident)
     reference variable.  */

  tree
-get_class_reference (tree ident)
+objc_get_class_reference (tree ident)
  {
    tree orig_ident;

@@ -2362,7 +2514,7 @@ get_class_reference (tree ident)
  #endif
    orig_ident = ident;

-  if (!(ident = is_class_name (ident)))
+  if (!(ident = objc_is_class_name (ident)))
      {
        error ("`%s' is not an Objective-C class name or alias",
              IDENTIFIER_POINTER (orig_ident));
@@ -2422,7 +2574,8 @@ add_objc_string (tree ident, enum string
    while (*chain)
      {
        if (TREE_VALUE (*chain) == ident)
-       return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
+       return convert (string_type_node,
+                       build_unary_op (ADDR_EXPR, TREE_PURPOSE 
(*chain), 1));

        chain = &TREE_CHAIN (*chain);
      }
@@ -2431,7 +2584,7 @@ add_objc_string (tree ident, enum string

    *chain = tree_cons (decl, ident, NULL_TREE);

-  return build_unary_op (ADDR_EXPR, decl, 1);
+  return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 
1));
  }

  static GTY(()) int class_names_idx;
@@ -2460,6 +2613,9 @@ build_objc_string_decl (enum string_sect
    TREE_CONSTANT (decl) = 1;
    DECL_CONTEXT (decl) = 0;
    DECL_ARTIFICIAL (decl) = 1;
+#ifdef OBJCPLUS
+  DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
+#endif

    make_decl_rtl (decl);
    pushdecl_top_level (decl);
@@ -2479,9 +2635,9 @@ objc_declare_alias (tree alias_ident, tr
    }
  #endif /* OBJCPLUS */

-  if (!(underlying_class = is_class_name (class_ident)))
+  if (!(underlying_class = objc_is_class_name (class_ident)))
      warning ("cannot find class `%s'", IDENTIFIER_POINTER 
(class_ident));
-  else if (is_class_name (alias_ident))
+  else if (objc_is_class_name (alias_ident))
      warning ("class `%s' already exists", IDENTIFIER_POINTER 
(alias_ident));
    else
      alias_chain = tree_cons (underlying_class, alias_ident, 
alias_chain);
@@ -2501,7 +2657,7 @@ objc_declare_class (tree ident_list)
      {
        tree ident = TREE_VALUE (list);

-      if (! is_class_name (ident))
+      if (! objc_is_class_name (ident))
         {
           tree record = lookup_name (ident);

@@ -2521,7 +2677,7 @@ objc_declare_class (tree ident_list)
  }

  tree
-is_class_name (tree ident)
+objc_is_class_name (tree ident)
  {
    tree chain;

@@ -2529,11 +2685,11 @@ is_class_name (tree ident)
        && identifier_global_value (ident))
      ident = identifier_global_value (ident);
    while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE 
(ident))
-    ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
+    ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));

  #ifdef OBJCPLUS
    if (ident && TREE_CODE (ident) == RECORD_TYPE)
-    ident = TYPE_NAME (ident);
+    ident = OBJC_TYPE_NAME (ident);
    if (ident && TREE_CODE (ident) == TYPE_DECL)
      ident = DECL_NAME (ident);
  #endif
@@ -2558,6 +2714,25 @@ is_class_name (tree ident)
    return 0;
  }

+/* Check whether TYPE is either 'id' or 'Class'.  */
+
+tree
+objc_is_id (tree type)
+{
+  if (type && TREE_CODE (type) == IDENTIFIER_NODE
+      && identifier_global_value (type))
+    type = identifier_global_value (type);
+
+  if (type && TREE_CODE (type) == TYPE_DECL)
+    type = TREE_TYPE (type);
+
+  /* NB: This function may be called before the ObjC front-end has
+     been initialized, in which case OBJC_OBJECT_TYPE will (still) be 
NULL.  */
+  return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type))
+         ? type
+         : NULL_TREE);
+}
+
  /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
     class instance.  This is needed by other parts of the compiler to
     handle ObjC types gracefully.  */
@@ -2565,19 +2740,20 @@ is_class_name (tree ident)
  tree
  objc_is_object_ptr (tree type)
  {
+  tree ret;
+
    type = TYPE_MAIN_VARIANT (type);
-  if (!type || TREE_CODE (type) != POINTER_TYPE)
+  if (!POINTER_TYPE_P (type))
      return 0;
-  /* NB: This function may be called before the ObjC front-end has
-     been initialized, in which case OBJC_ID_TYPE will be NULL.  */
-  if (objc_id_type && type && TYPE_P (type)
-      && (IS_ID (type)
-         || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
-    return type;
-  return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
+
+  ret = objc_is_id (type);
+  if (!ret)
+    ret = objc_is_class_name (TREE_TYPE (type));
+
+  return ret;
  }

-tree
+static tree
  lookup_interface (tree ident)
  {
    tree chain;
@@ -2597,88 +2773,40 @@ lookup_interface (tree ident)
  /* Implement @defs (<classname>) within struct bodies.  */

  tree
-get_class_ivars_from_name (tree class_name)
+objc_get_class_ivars (tree class_name)
  {
    tree interface = lookup_interface (class_name);
-  tree field, fields = NULL_TREE;

    if (interface)
-    {
-      tree raw_ivar = get_class_ivars (interface, 1);
+    return get_class_ivars (interface);

-      /* Regenerate the FIELD_DECLs for the enclosing struct.  */
-      for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
-       {
-         field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
-                            TREE_PURPOSE (raw_ivar),
-                            TREE_VALUE (TREE_VALUE (raw_ivar)));
-#ifdef OBJCPLUS
-         finish_member_declaration (field);
-#else
-         fields = chainon (fields, field);
-#endif
-       }
-    }
-  else
-    error ("cannot find interface declaration for `%s'",
-          IDENTIFIER_POINTER (class_name));
+  error ("cannot find interface declaration for `%s'",
+        IDENTIFIER_POINTER (class_name));

-  return fields;
+  return error_mark_node;
  }

  /* Used by: build_private_template, continue_class,
     and for @defs constructs.  */

  static tree
-get_class_ivars (tree interface, int raw)
+get_class_ivars (tree interface)
  {
-  tree my_name, super_name, ivar_chain;
-
-  my_name = CLASS_NAME (interface);
-  super_name = CLASS_SUPER_NAME (interface);
-  if (raw)
-    ivar_chain = CLASS_RAW_IVARS (interface);
-  else
-    {
-      ivar_chain = CLASS_IVARS (interface);
-      /* Save off a pristine copy of the leaf ivars (i.e, those not
-        inherited from a super class).  */
-      if (!CLASS_OWN_IVARS (interface))
-       CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
-    }
-
-  while (super_name)
-    {
-      tree op1;
-      tree super_interface = lookup_interface (super_name);
-
-      if (!super_interface)
-        {
-         /* fatal did not work with 2 args...should fix */
-         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_error ("circular inheritance in interface declaration for 
`%s'",
-                    IDENTIFIER_POINTER (super_name));
-
-      interface = super_interface;
-      my_name = CLASS_NAME (interface);
-      super_name = CLASS_SUPER_NAME (interface);
+  tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));

-      op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS 
(interface));
-      if (op1)
-        {
-         tree head = copy_list (op1);
-
-         /* Prepend super class ivars...make a copy of the list, we
-            do not want to alter the original.  */
-         chainon (head, ivar_chain);
-         ivar_chain = head;
-        }
+  /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars 
declared
+     by the current class (i.e., they do not include super-class 
ivars).
+     However, the CLASS_IVARS list will be side-effected by a call to
+     finish_struct(), which will fill in field offsets.  */
+  if (!CLASS_IVARS (interface))
+    CLASS_IVARS (interface) = ivar_chain;
+
+  while (CLASS_SUPER_NAME (interface))
+    {
+      /* Prepend super-class ivars.  */
+      interface = lookup_interface (CLASS_SUPER_NAME (interface));
+      ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
+                           ivar_chain);
      }

    return ivar_chain;
@@ -2739,11 +2867,13 @@ static struct objc_try_context *cur_try_
     that represents TYPE.  For Objective-C, this is just the class 
name.  */
  /* ??? Isn't there a class object or some such?  Is it easy to get?  */

+#ifndef OBJCPLUS
  static tree
  objc_eh_runtime_type (tree type)
  {
    return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), 
class_names);
  }
+#endif

  /* Initialize exception handling.  */

@@ -2755,12 +2885,16 @@ objc_init_exceptions (void)
      return;
    done = true;

-  /* Why?  */
-  if (!flag_objc_exceptions)
-    warning ("use %<-fobjc-exceptions%> to enable Objective-C "
-            "exception syntax");
-
-  if (!flag_objc_sjlj_exceptions)
+  if (flag_objc_sjlj_exceptions)
+    {
+      /* On Darwin, ObjC exceptions require a sufficiently recent
+        version of the runtime, so the user must ask for them 
explicitly.  */
+      if (!flag_objc_exceptions)
+       warning ("use %<-fobjc-exceptions%> to enable Objective-C "
+                "exception syntax");
+    }
+#ifndef OBJCPLUS
+  else
      {
        c_eh_initialized_p = true;
        eh_personality_libfunc
@@ -2770,6 +2904,7 @@ objc_init_exceptions (void)
        using_eh_for_cleanups ();
        lang_eh_runtime_type = objc_eh_runtime_type;
      }
+#endif
  }

  /* Build an EXC_PTR_EXPR, or the moral equivalent.  In the case of 
Darwin,
@@ -2784,13 +2919,13 @@ objc_build_exc_ptr (void)
        tree var = cur_try_context->caught_decl;
        if (!var)
         {
-         var = objc_create_temporary_var (objc_id_type);
+         var = objc_create_temporary_var (objc_object_type);
           cur_try_context->caught_decl = var;
         }
        return var;
      }
    else
-    return build (EXC_PTR_EXPR, objc_id_type);
+    return build (EXC_PTR_EXPR, objc_object_type);
  }

  /* Build "objc_exception_try_exit(&_stack)".  */
@@ -2895,7 +3030,7 @@ next_sjlj_build_catch_list (void)
           else
             {
               args = tree_cons (NULL, cur_try_context->caught_decl, 
NULL);
-             t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE 
(type)));
+             t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE 
(type)));
               args = tree_cons (NULL, t, args);
               t = build_function_call (objc_exception_match_decl, args);
               cond = lang_hooks.truthvalue_conversion (t);
@@ -2970,7 +3105,7 @@ next_sjlj_build_try_catch_finally (void)
    stack_decl = objc_create_temporary_var (t);
    cur_try_context->stack_decl = stack_decl;

-  rethrow_decl = objc_create_temporary_var (objc_id_type);
+  rethrow_decl = objc_create_temporary_var (objc_object_type);
    cur_try_context->rethrow_decl = rethrow_decl;
    TREE_THIS_VOLATILE (rethrow_decl) = 1;
    TREE_CHAIN (rethrow_decl) = stack_decl;
@@ -2982,7 +3117,7 @@ next_sjlj_build_try_catch_finally (void)

    /* Initialize rethrow_decl.  */
    t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
-            convert (objc_id_type, null_pointer_node));
+            convert (objc_object_type, null_pointer_node));
    annotate_with_locus (t, cur_try_context->try_locus);
    append_to_statement_list (t, &BIND_EXPR_BODY (bind));

@@ -3056,20 +3191,20 @@ objc_begin_try_stmt (location_t try_locu
  }

  /* Called just after parsing "@catch (parm)".  Open a binding level,
-   enter PARM into the binding level, and initialize it.  Leave the
+   enter DECL into the binding level, and initialize it.  Leave the
     binding level open while the body of the compound statement is 
parsed.  */

  void
-objc_begin_catch_clause (tree parm)
+objc_begin_catch_clause (tree decl)
  {
-  tree compound, decl, type, t;
+  tree compound, type, t;

    /* Begin a new scope that the entire catch clause will live in.  */
-  compound = c_begin_compound_stmt (1);
+  compound = c_begin_compound_stmt (true);

-  /* Turn the raw declarator/declspecs into a decl in the current 
scope.  */
-  decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
-                     TREE_PURPOSE (TREE_PURPOSE (parm)));
+  /* The parser passed in a PARM_DECL, but what we really want is a 
VAR_DECL.  */
+  decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+  lang_hooks.decls.pushdecl (decl);

    /* Since a decl is required here by syntax, don't warn if its 
unused.  */
    /* ??? As opposed to __attribute__((unused))?  Anyway, this appears 
to
@@ -3102,7 +3237,7 @@ objc_begin_catch_clause (tree parm)
               warning ("exception of type %<%T%> will be caught",
                        TREE_TYPE (type));
               warning ("%H   by earlier handler for %<%T%>",
-                      EXPR_LOCUS (stmt), TREE_TYPE (t ? t : 
objc_id_type));
+                      EXPR_LOCUS (stmt), TREE_TYPE (t ? t : 
objc_object_type));
               break;
             }
         }
@@ -3264,31 +3399,21 @@ build_next_objc_exception_stuff (void)
  {
    tree field_decl, field_decl_chain, index, temp_type;

-  /* Suppress outputting debug symbols, because
-     dbxout_init hasn't been called yet.  */
-  enum debug_info_type save_write_symbols = write_symbols;
-  const struct gcc_debug_hooks *save_hooks = debug_hooks;
-
-  write_symbols = NO_DEBUG;
-  debug_hooks = &do_nothing_debug_hooks;
-
    objc_exception_data_template
      = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));

    /* int buf[_JBLEN]; */

    index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1, 0));
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   build_array_type 
(integer_type_node, index),
-                                   "buf");
+  field_decl = create_field_decl (build_array_type (integer_type_node, 
index),
+                                 "buf");
    field_decl_chain = field_decl;

    /* void *pointers[4]; */

    index = build_index_type (build_int_cst (NULL_TREE, 4 - 1, 0));
-  field_decl = create_builtin_decl (FIELD_DECL,
-                                   build_array_type (ptr_type_node, 
index),
-                                   "pointers");
+  field_decl = create_field_decl (build_array_type (ptr_type_node, 
index),
+                                 "pointers");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_exception_data_template, field_decl_chain, 
NULL_TREE);
@@ -3302,10 +3427,10 @@ build_next_objc_exception_stuff (void)

    /* id objc_exception_extract(struct _objc_exception_data *); */
    temp_type
-    = build_function_type (objc_id_type,
+    = build_function_type (objc_object_type,
                            tree_cons (NULL_TREE,
                                       build_pointer_type 
(objc_exception_data_template),
-                                     void_list_node));
+                                     OBJC_VOID_AT_END));
    objc_exception_extract_decl
      = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, 
NOT_BUILT_IN, NULL, NULL_TREE);
    /* void objc_exception_try_enter(struct _objc_exception_data *); */
@@ -3314,7 +3439,7 @@ build_next_objc_exception_stuff (void)
      = build_function_type (void_type_node,
                            tree_cons (NULL_TREE,
                                       build_pointer_type 
(objc_exception_data_template),
-                                     void_list_node));
+                                     OBJC_VOID_AT_END));
    objc_exception_try_enter_decl
      = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, 
NOT_BUILT_IN, NULL, NULL_TREE);
    objc_exception_try_exit_decl
@@ -3323,14 +3448,11 @@ build_next_objc_exception_stuff (void)
    /* int objc_exception_match(id, id); */
    temp_type
      = build_function_type (integer_type_node,
-                          tree_cons (NULL_TREE, objc_id_type,
-                                     tree_cons (NULL_TREE, 
objc_id_type,
+                          tree_cons (NULL_TREE, objc_object_type,
+                                     tree_cons (NULL_TREE, 
objc_object_type,
                                                  void_list_node)));
    objc_exception_match_decl
      = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, 
NOT_BUILT_IN, NULL, NULL_TREE);
-
-  write_symbols = save_write_symbols;
-  debug_hooks = save_hooks;
  }

  static void
@@ -3345,8 +3467,8 @@ build_objc_exception_stuff (void)
    /* void objc_sync_enter(id); */
    /* void objc_sync_exit(id); */
    temp_type = build_function_type (void_type_node,
-                                  tree_cons (NULL_TREE, objc_id_type,
-                                             void_list_node));
+                                  tree_cons (NULL_TREE, 
objc_object_type,
+                                             OBJC_VOID_AT_END));
    objc_exception_throw_decl
      = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, 
NOT_BUILT_IN, NULL,
                         noreturn_list);
@@ -3360,7 +3482,7 @@ build_objc_exception_stuff (void)


  /* struct <classname> {
-     struct objc_class *isa;
+     struct _objc_class *isa;
       ...
     };  */

@@ -3377,7 +3499,7 @@ build_private_template (tree class)
    else
      {
        uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
-      ivar_context = get_class_ivars (class, 0);
+      ivar_context = get_class_ivars (class);

        finish_struct (uprivate_record, ivar_context, NULL_TREE);

@@ -3387,80 +3509,64 @@ build_private_template (tree class)
        TREE_STATIC_TEMPLATE (uprivate_record) = 1;
      }

-  objc_instance_type
-    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
-                                                     uprivate_record),
-                                    build1 (INDIRECT_REF, NULL_TREE,
-                                            NULL_TREE)));
+  objc_instance_type = build_pointer_type (uprivate_record);

    return ivar_context;
  }


  /* Begin code generation for protocols...  */

-/* struct objc_protocol {
+/* struct _objc_protocol {
+     struct _objc_class *isa;
       char *protocol_name;
-     struct objc_protocol **protocol_list;
-     struct objc_method_desc *instance_methods;
-     struct objc_method_desc *class_methods;
+     struct _objc_protocol **protocol_list;
+     struct _objc__method_prototype_list *instance_methods;
+     struct _objc__method_prototype_list *class_methods;
     };  */

-static tree
+static void
  build_protocol_template (void)
  {
-  tree decl_specs, field_decl, field_decl_chain;
-  tree template;
-
-  template = start_struct (RECORD_TYPE, get_identifier 
(UTAG_PROTOCOL));
+  tree field_decl, field_decl_chain;

-  /* struct objc_class *isa; */
+  objc_protocol_template = start_struct (RECORD_TYPE,
+                                        get_identifier 
(UTAG_PROTOCOL));

-  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
-                                       get_identifier (UTAG_CLASS)));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("isa"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_class *isa; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier 
(UTAG_CLASS))),
+                                 "isa");
    field_decl_chain = field_decl;

    /* char *protocol_name; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("protocol_name"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "protocol_name");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_protocol **protocol_list; */
-
-  decl_specs = build_tree_list (NULL_TREE, template);
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("protocol_list"));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_protocol **protocol_list; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (build_pointer_type
+                                  (objc_protocol_template)),
+                                 "protocol_list");
    chainon (field_decl_chain, field_decl);

    /* struct objc_method_list *instance_methods; */
-
-  decl_specs
-    = build_tree_list (NULL_TREE,
-                      xref_tag (RECORD_TYPE,
-                                get_identifier 
(UTAG_METHOD_PROTOTYPE_LIST)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("instance_methods"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            
(UTAG_METHOD_PROTOTYPE_LIST))),
+                                 "instance_methods");
    chainon (field_decl_chain, field_decl);

    /* struct objc_method_list *class_methods; */
-
-  decl_specs
-    = build_tree_list (NULL_TREE,
-                      xref_tag (RECORD_TYPE,
-                                get_identifier 
(UTAG_METHOD_PROTOTYPE_LIST)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("class_methods"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            
(UTAG_METHOD_PROTOTYPE_LIST))),
+                                 "class_methods");
    chainon (field_decl_chain, field_decl);

-  return finish_struct (template, field_decl_chain, NULL_TREE);
+  finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
  }

  static tree
@@ -3506,25 +3612,22 @@ static tree
  build_method_prototype_list_template (tree list_type, int size)
  {
    tree objc_ivar_list_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    /* Generate an unnamed struct definition.  */

    objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

    /* int method_count; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
-  field_decl = get_identifier ("method_count");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (integer_type_node, "method_count");
    field_decl_chain = field_decl;

    /* struct objc_method method_list[]; */
-
-  decl_specs = build_tree_list (NULL_TREE, list_type);
-  field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
-                        build_int_cst (NULL_TREE, size, 0), NULL_TREE, 
NULL_TREE);
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_array_type
+                                 (list_type,
+                                  build_index_type
+                                  (build_int_cst (NULL_TREE, size - 1, 
0))),
+                                 "method_list");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -3536,22 +3639,17 @@ static tree
  build_method_prototype_template (void)
  {
    tree proto_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    proto_record
      = start_struct (RECORD_TYPE, get_identifier 
(UTAG_METHOD_PROTOTYPE));

-  /* 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"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* SEL _cmd; */
+  field_decl = create_field_decl (objc_selector_type, "_cmd");
    field_decl_chain = field_decl;

-  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], 
NULL_TREE);
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("method_types"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* char *method_types; */
+  field_decl = create_field_decl (string_type_node, "method_types");
    chainon (field_decl_chain, field_decl);

    finish_struct (proto_record, field_decl_chain, NULL_TREE);
@@ -3562,7 +3660,7 @@ build_method_prototype_template (void)
  static tree
  objc_method_parm_type (tree type)
  {
-  type = groktypename (TREE_TYPE (type));
+  type = TREE_VALUE (TREE_TYPE (type));
    if (TREE_CODE (type) == TYPE_DECL)
      type = TREE_TYPE (type);
    return TYPE_MAIN_VARIANT (type);
@@ -3575,9 +3673,7 @@ objc_encoded_type_size (tree type)

    /* Make all integer and enum types at least as large
       as an int.  */
-  if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
-                || TREE_CODE (type) == BOOLEAN_TYPE
-                || TREE_CODE (type) == ENUMERAL_TYPE))
+  if (sz > 0 && INTEGRAL_TYPE_P (type))
      sz = MAX (sz, int_size_in_bytes (integer_type_node));
    /* Treat arrays as pointers, since that's how they're
       passed in.  */
@@ -3660,20 +3756,14 @@ static tree
  generate_descriptor_table (tree type, const char *name, int size, tree 
list,
                            tree proto)
  {
-  tree sc_spec, decl_specs, decl, initlist;
-
-  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+  tree decl, initlist;

-  decl = start_decl (synth_id_with_class_suffix (name, proto),
-                    decl_specs, 1, NULL_TREE);
-  DECL_CONTEXT (decl) = NULL_TREE;
+  decl = start_var_decl (type, synth_id_with_class_suffix (name, 
proto));

    initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 
size, 0));
    initlist = tree_cons (NULL_TREE, list, initlist);

-  finish_decl (decl, objc_build_constructor (type, nreverse 
(initlist)),
-              NULL_TREE);
+  finish_var_decl (decl, objc_build_constructor (type, nreverse 
(initlist)));

    return decl;
  }
@@ -3682,17 +3772,14 @@ static void
  generate_method_descriptors (tree protocol)
  {
    tree initlist, chain, method_list_template;
-  tree cast, variable_length_type;
+  tree variable_length_type
+    = xref_tag (RECORD_TYPE,
+               get_identifier (UTAG_METHOD_PROTOTYPE_LIST));
    int size;

    if (!objc_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))),
-                         NULL_TREE);
-  variable_length_type = groktypename (cast);
-
    chain = PROTOCOL_CLS_METHODS (protocol);
    if (chain)
      {
@@ -3801,12 +3888,8 @@ static void
  generate_protocols (void)
  {
    tree p, encoding;
-  tree sc_spec, decl_specs, decl;
+  tree decl;
    tree initlist, protocol_name_expr, refs_decl, refs_expr;
-  tree cast_type2;
-
-  if (! objc_protocol_template)
-    objc_protocol_template = build_protocol_template ();

    /* If a protocol was directly referenced, pull in indirect 
references.  */
    for (p = protocol_chain; p; p = TREE_CHAIN (p))
@@ -3819,7 +3902,9 @@ generate_protocols (void)
        tree cls_methods = PROTOCOL_CLS_METHODS (p);

        /* If protocol wasn't referenced, don't generate any code.  */
-      if (! PROTOCOL_FORWARD_DECL (p))
+      decl = PROTOCOL_FORWARD_DECL (p);
+
+      if (!decl)
         continue;

        /* Make sure we link in the Protocol class.  */
@@ -3853,31 +3938,12 @@ generate_protocols (void)
         refs_decl = 0;

        /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
-
-      sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
-                          NULL_TREE);
-      decl_specs = tree_cons (NULL_TREE, objc_protocol_template, 
sc_spec);
-
-      decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", 
p),
-                        decl_specs, 1, NULL_TREE);
-
-      DECL_CONTEXT (decl) = NULL_TREE;
-
        protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), 
class_names);

        if (refs_decl)
-       {
-         cast_type2
-           = groktypename
-               (build_tree_list (build_tree_list (NULL_TREE,
-                                                  
objc_protocol_template),
-                                 build1 (INDIRECT_REF, NULL_TREE,
-                                         build1 (INDIRECT_REF, 
NULL_TREE,
-                                                 NULL_TREE))));
-
-         refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0);
-         TREE_TYPE (refs_expr) = cast_type2;
-       }
+       refs_expr = convert (build_pointer_type (build_pointer_type
+                                                
(objc_protocol_template)),
+                            build_unary_op (ADDR_EXPR, refs_decl, 0));
        else
         refs_expr = build_int_cst (NULL_TREE, 0, 0);

@@ -3887,10 +3953,7 @@ generate_protocols (void)
                                              protocol_name_expr, 
refs_expr,
                                              
UOBJC_INSTANCE_METHODS_decl,
                                              UOBJC_CLASS_METHODS_decl);
-      finish_decl (decl, initlist, NULL_TREE);
-
-      /* Mark the decl as used to avoid "defined but not used" 
warning.  */
-      TREE_USED (decl) = 1;
+      finish_var_decl (decl, initlist);
      }
  }

@@ -3900,20 +3963,14 @@ build_protocol_initializer (tree type, t
                             tree class_methods)
  {
    tree initlist = NULL_TREE, expr;
-  tree 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)));
+  tree cast_type = build_pointer_type
+                  (xref_tag (RECORD_TYPE,
+                             get_identifier (UTAG_CLASS)));

    /* Filling the "isa" in with one allows the runtime system to
       detect that the version change...should remove before final 
release.  */

-  expr = build_int_cst (NULL_TREE, PROTOCOL_VERSION, 0);
-  TREE_TYPE (expr) = cast_type;
+  expr = convert (cast_type, build_int_cst (NULL_TREE, 
PROTOCOL_VERSION, 0));
    initlist = tree_cons (NULL_TREE, expr, initlist);
    initlist = tree_cons (NULL_TREE, protocol_name, initlist);
    initlist = tree_cons (NULL_TREE, protocol_list, initlist);
@@ -3937,72 +3994,58 @@ build_protocol_initializer (tree type, t
    return objc_build_constructor (type, nreverse (initlist));
  }


-/* struct objc_category {
+/* struct _objc_category {
       char *category_name;
       char *class_name;
-     struct objc_method_list *instance_methods;
-     struct objc_method_list *class_methods;
-     struct objc_protocol_list *protocols;
+     struct _objc_method_list *instance_methods;
+     struct _objc_method_list *class_methods;
+     struct _objc_protocol_list *protocols;
     };   */

  static void
  build_category_template (void)
  {
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_category_template = start_struct (RECORD_TYPE,
                                          get_identifier 
(UTAG_CATEGORY));
-  /* char *category_name; */

-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("category_name"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* char *category_name; */
+  field_decl = create_field_decl (string_type_node, "category_name");
    field_decl_chain = field_decl;

    /* char *class_name; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("class_name"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "class_name");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_method_list *instance_methods; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_METHOD_LIST)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("instance_methods"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_method_list *instance_methods; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            (UTAG_METHOD_LIST))),
+                                 "instance_methods");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_method_list *class_methods; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_METHOD_LIST)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("class_methods"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_method_list *class_methods; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            (UTAG_METHOD_LIST))),
+                                 "class_methods");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_protocol **protocol_list; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_PROTOCOL)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("protocol_list"));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_protocol **protocol_list; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (build_pointer_type
+                                  (objc_protocol_template)),
+                                 "protocol_list");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
  }

-/* struct objc_selector {
-     void *sel_id;
+/* struct _objc_selector {
+     SEL sel_id;
       char *sel_type;
     }; */

@@ -4010,47 +4053,42 @@ static void
  build_selector_template (void)
  {

-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_selector_template
      = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));

-  /* void *sel_id; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_VOID]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("sel_id"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* SEL sel_id; */
+  field_decl = create_field_decl (objc_selector_type, "sel_id");
    field_decl_chain = field_decl;

    /* char *sel_type; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("sel_type"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "sel_type");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
  }

-/* struct objc_class {
-     struct objc_class *isa;
-     struct objc_class *super_class;
+/* struct _objc_class {
+     struct _objc_class *isa;
+     struct _objc_class *super_class;
       char *name;
       long version;
       long info;
       long instance_size;
-     struct objc_ivar_list *ivars;
-     struct objc_method_list *methods;
-     if (flag_next_runtime)
+     struct _objc_ivar_list *ivars;
+     struct _objc_method_list *methods;
+     #ifdef __NEXT_RUNTIME__
         struct objc_cache *cache;
-     else {
+     #else
         struct sarray *dtable;
-       struct objc_class *subclass_list;
-       struct objc_class *sibling_class;
-     }
-     struct objc_protocol_list *protocols;
-     if (flag_next_runtime)
+       struct _objc_class *subclass_list;
+       struct _objc_class *sibling_class;
+     #endif
+     struct _objc_protocol_list *protocols;
+     #ifdef __NEXT_RUNTIME__
         void *sel_id;
+     #endif
       void *gc_object_type;
     };  */

@@ -4062,139 +4100,106 @@ build_selector_template (void)
  static void
  build_class_template (void)
  {
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_class_template
      = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));

-  /* struct objc_class *isa; */
-
-  decl_specs = build_tree_list (NULL_TREE, objc_class_template);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("isa"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_class *isa; */
+  field_decl = create_field_decl (build_pointer_type 
(objc_class_template),
+                                 "isa");
    field_decl_chain = field_decl;

-  /* struct objc_class *super_class; */
-
-  decl_specs = build_tree_list (NULL_TREE, objc_class_template);
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_class *super_class; */
+  field_decl = create_field_decl (build_pointer_type 
(objc_class_template),
+                                 "super_class");
    chainon (field_decl_chain, field_decl);

    /* char *name; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("name"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "name");
    chainon (field_decl_chain, field_decl);

    /* long version; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_LONG]);
-  field_decl = get_identifier ("version");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (long_integer_type_node, "version");
    chainon (field_decl_chain, field_decl);

    /* long info; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_LONG]);
-  field_decl = get_identifier ("info");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (long_integer_type_node, "info");
    chainon (field_decl_chain, field_decl);

    /* long instance_size; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_LONG]);
-  field_decl = get_identifier ("instance_size");
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (long_integer_type_node, 
"instance_size");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_ivar_list *ivars; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_IVAR_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("ivars"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_ivar_list *ivars; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            (UTAG_IVAR_LIST))),
+                                 "ivars");
    chainon (field_decl_chain, field_decl);

-  /* struct objc_method_list *methods; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_METHOD_LIST)));
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("methods"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_method_list *methods; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            (UTAG_METHOD_LIST))),
+                                 "methods");
    chainon (field_decl_chain, field_decl);

    if (flag_next_runtime)
      {
        /* struct objc_cache *cache; */
-
-      decl_specs = build_tree_list (NULL_TREE,
-                                   xref_tag (RECORD_TYPE,
-                                             get_identifier 
("objc_cache")));
-      field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("cache"));
-      field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+      field_decl = create_field_decl (build_pointer_type
+                                     (xref_tag (RECORD_TYPE,
+                                                get_identifier
+                                                ("objc_cache"))),
+                                     "cache");
        chainon (field_decl_chain, field_decl);
      }
    else
      {
        /* struct sarray *dtable; */
-
-      decl_specs = build_tree_list (NULL_TREE,
-                                   xref_tag (RECORD_TYPE,
-                                             get_identifier 
("sarray")));
-      field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("dtable"));
-      field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+      field_decl = create_field_decl (build_pointer_type
+                                     (xref_tag (RECORD_TYPE,
+                                                get_identifier
+                                                ("sarray"))),
+                                     "dtable");
        chainon (field_decl_chain, field_decl);

        /* struct objc_class *subclass_list; */
-
-      decl_specs = build_tree_list (NULL_TREE, objc_class_template);
-      field_decl
-       = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("subclass_list"));
-      field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+      field_decl = create_field_decl (build_pointer_type
+                                     (objc_class_template),
+                                     "subclass_list");
        chainon (field_decl_chain, field_decl);

        /* struct objc_class *sibling_class; */
-
-      decl_specs = build_tree_list (NULL_TREE, objc_class_template);
-      field_decl
-       = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("sibling_class"));
-      field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+      field_decl = create_field_decl (build_pointer_type
+                                     (objc_class_template),
+                                     "sibling_class");
        chainon (field_decl_chain, field_decl);
      }

-  /* struct objc_protocol **protocol_list; */
-
-  decl_specs = build_tree_list (NULL_TREE,
-                               xref_tag (RECORD_TYPE,
-                                         get_identifier 
(UTAG_PROTOCOL)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("protocol_list"));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, field_decl);
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_protocol **protocol_list; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (build_pointer_type
+                                  (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            (UTAG_PROTOCOL)))),
+                                 "protocol_list");
    chainon (field_decl_chain, field_decl);

    if (flag_next_runtime)
      {
        /* void *sel_id; */
-
-      decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_VOID]);
-      field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("sel_id"));
-      field_decl
-       = grokfield (field_decl, decl_specs, NULL_TREE);
+      field_decl = create_field_decl (build_pointer_type 
(void_type_node),
+                                     "sel_id");
        chainon (field_decl_chain, field_decl);
      }

    /* void *gc_object_type; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_VOID]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("gc_object_type"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_pointer_type (void_type_node),
+                                 "gc_object_type");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
@@ -4209,14 +4214,11 @@ synth_forward_declarations (void)

    /* static struct objc_class _OBJC_CLASS_<my_name>; */
    UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
-                                                 objc_class_template);
+                                         objc_class_template);

    /* static struct objc_class _OBJC_METACLASS_<my_name>; */
    UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
                                                   objc_class_template);
-
-  mark_decl_referenced (UOBJC_CLASS_decl);
-  mark_decl_referenced (UOBJC_METACLASS_decl);

    /* Pre-build the following entities - for speed/convenience.  */

@@ -4226,20 +4228,18 @@ synth_forward_declarations (void)
  }

  static void
-error_with_ivar (const char *message, tree decl, tree rawdecl)
+error_with_ivar (const char *message, tree decl)
  {
    error ("%J%s `%s'", decl,
-         message, gen_declaration (rawdecl, errbuf));
+         message, gen_declaration (decl, errbuf));

  }

  static void
  check_ivars (tree inter, tree imp)
  {
-  tree intdecls = CLASS_IVARS (inter);
-  tree impdecls = CLASS_IVARS (imp);
-  tree rawintdecls = CLASS_RAW_IVARS (inter);
-  tree rawimpdecls = CLASS_RAW_IVARS (imp);
+  tree intdecls = CLASS_RAW_IVARS (inter);
+  tree impdecls = CLASS_RAW_IVARS (imp);

    while (1)
      {
@@ -4259,26 +4259,16 @@ check_ivars (tree inter, tree imp)

        t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);

-      if (TREE_VALUE (TREE_VALUE (rawimpdecls)))
-       {
-         /* t1 is the bit-field type, so t2 must be converted to the
-            bit-field type for comparison as well.  */
-         unsigned HOST_WIDE_INT width
-           = tree_low_cst (TREE_VALUE (TREE_VALUE (rawimpdecls)), 1);
-         if (width != TYPE_PRECISION (t2))
-           t2 = build_nonstandard_integer_type (width, TYPE_UNSIGNED 
(t2));
-       }
-
        if (!comptypes (t1, t2)
-         || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
-                                 TREE_VALUE (TREE_VALUE 
(rawimpdecls))))
+         || !tree_int_cst_equal (DECL_INITIAL (intdecls),
+                                 DECL_INITIAL (impdecls)))
         {
           if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
             {
               error_with_ivar ("conflicting instance variable type",
-                              impdecls, rawimpdecls);
+                              impdecls);
               error_with_ivar ("previous declaration of",
-                              intdecls, rawintdecls);
+                              intdecls);
             }
           else                  /* both the type and the name don't 
match */
             {
@@ -4290,68 +4280,44 @@ check_ivars (tree inter, tree imp)
        else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
         {
           error_with_ivar ("conflicting instance variable name",
-                          impdecls, rawimpdecls);
+                          impdecls);
           error_with_ivar ("previous declaration of",
-                          intdecls, rawintdecls);
+                          intdecls);
         }

        intdecls = TREE_CHAIN (intdecls);
        impdecls = TREE_CHAIN (impdecls);
-      rawintdecls = TREE_CHAIN (rawintdecls);
-      rawimpdecls = TREE_CHAIN (rawimpdecls);
      }
  }

  /* Set 'objc_super_template' to the data type node for 'struct 
_objc_super'.
     This needs to be done just once per compilation.  */

+/* struct _objc_super {
+     struct _objc_object *self;
+     struct _objc_class *super_class;
+   };  */
+
  static void
  build_super_template (void)
  {
-  tree decl_specs, field_decl, field_decl_chain;
-
-  /* Suppress outputting debug symbols, because
-     dbxout_init hasn't been called yet.  */
-  enum debug_info_type save_write_symbols = write_symbols;
-  const struct gcc_debug_hooks *save_hooks = debug_hooks;
-
-  write_symbols = NO_DEBUG;
-  debug_hooks = &do_nothing_debug_hooks;
+  tree field_decl, field_decl_chain;

    objc_super_template = start_struct (RECORD_TYPE, get_identifier 
(UTAG_SUPER));

-  /* struct objc_object *self; */
-
-  decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
-  field_decl = get_identifier ("self");
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_object *self; */
+  field_decl = create_field_decl (objc_object_type, "self");
    field_decl_chain = field_decl;

-#ifdef OBJCPLUS
-  /* struct objc_class *super_class; */
-#else
-  /* struct objc_class *class; */
-#endif
-
-  decl_specs = get_identifier (UTAG_CLASS);
-  decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, 
decl_specs));
-#ifdef OBJCPLUS
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("super_class"));
-#else
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("class"));
-#endif
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc_class *super_class; */
+  field_decl = create_field_decl (build_pointer_type 
(objc_class_template),
+                                 "super_class");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
-
-  write_symbols = save_write_symbols;
-  debug_hooks = save_hooks;
  }

-/* struct objc_ivar {
+/* struct _objc_ivar {
       char *ivar_name;
       char *ivar_type;
       int ivar_offset;
@@ -4361,33 +4327,21 @@ static tree
  build_ivar_template (void)
  {
    tree objc_ivar_id, objc_ivar_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_ivar_id = get_identifier (UTAG_IVAR);
    objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);

    /* char *ivar_name; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("ivar_name"));
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "ivar_name");
    field_decl_chain = field_decl;

    /* char *ivar_type; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_CHAR]);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("ivar_type"));
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (string_type_node, "ivar_type");
    chainon (field_decl_chain, field_decl);

    /* int ivar_offset; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
-  field_decl = get_identifier ("ivar_offset");
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (integer_type_node, "ivar_offset");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
@@ -4404,25 +4358,20 @@ static tree
  build_ivar_list_template (tree list_type, int size)
  {
    tree objc_ivar_list_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

    /* int ivar_count; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
-  field_decl = get_identifier ("ivar_count");
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (integer_type_node, "ivar_count");
    field_decl_chain = field_decl;

    /* struct objc_ivar ivar_list[]; */
-
-  decl_specs = build_tree_list (NULL_TREE, list_type);
-  field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
-                        build_int_cst (NULL_TREE, size, 0), NULL_TREE, 
NULL_TREE);
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_array_type
+                                 (list_type,
+                                  build_index_type
+                                  (build_int_cst (NULL_TREE, size - 1, 
0))),
+                                 "ivar_list");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -4431,7 +4380,7 @@ build_ivar_list_template (tree list_type
  }

  /* struct {
-     int method_next;
+     struct _objc__method_prototype_list *method_next;
       int method_count;
       struct objc_method method_list[method_count];
     };  */
@@ -4440,37 +4389,28 @@ static tree
  build_method_list_template (tree list_type, int size)
  {
    tree objc_ivar_list_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);

-  /* int method_next; */
-
-  decl_specs
-    = build_tree_list
-      (NULL_TREE,
-       xref_tag (RECORD_TYPE,
-                get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
-  field_decl
-    = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* struct _objc__method_prototype_list *method_next; */
+  field_decl = create_field_decl (build_pointer_type
+                                 (xref_tag (RECORD_TYPE,
+                                            get_identifier
+                                            
(UTAG_METHOD_PROTOTYPE_LIST))),
+                                 "method_next");
    field_decl_chain = field_decl;

    /* int method_count; */
-
-  decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
-  field_decl = get_identifier ("method_count");
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (integer_type_node, "method_count");
    chainon (field_decl_chain, field_decl);

    /* struct objc_method method_list[]; */
-
-  decl_specs = build_tree_list (NULL_TREE, list_type);
-  field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
-                        build_int_cst (NULL_TREE, size, 0), NULL_TREE, 
NULL_TREE);
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_array_type
+                                 (list_type,
+                                  build_index_type
+                                  (build_int_cst (NULL_TREE, size - 1, 
0))),
+                                 "method_list");
    chainon (field_decl_chain, field_decl);

    finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -4530,20 +4470,17 @@ build_ivar_list_initializer (tree type,
  static tree
  generate_ivars_list (tree type, const char *name, int size, tree list)
  {
-  tree sc_spec, decl_specs, decl, initlist;
+  tree decl, initlist;

-  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, 
objc_implementation_context),
-                    decl_specs, 1, NULL_TREE);
+  decl = start_var_decl (type, synth_id_with_class_suffix
+                              (name, objc_implementation_context));

    initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 
size, 0));
    initlist = tree_cons (NULL_TREE, list, initlist);

-  finish_decl (decl,
-              objc_build_constructor (TREE_TYPE (decl), nreverse 
(initlist)),
-              NULL_TREE);
+  finish_var_decl (decl,
+                  objc_build_constructor (TREE_TYPE (decl),
+                                          nreverse (initlist)));

    return decl;
  }
@@ -4565,7 +4502,8 @@ static void
  generate_ivar_lists (void)
  {
    tree initlist, ivar_list_template, chain;
-  tree cast, variable_length_type;
+  tree variable_length_type
+    = xref_tag (RECORD_TYPE, get_identifier (UTAG_IVAR_LIST));
    int size;

    generating_instance_variables = 1;
@@ -4573,13 +4511,6 @@ generate_ivar_lists (void)
    if (!objc_ivar_template)
      objc_ivar_template = build_ivar_template ();

-  cast
-    = build_tree_list
-      (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
-                                        get_identifier 
(UTAG_IVAR_LIST))),
-       NULL_TREE);
-  variable_length_type = groktypename (cast);
-
    /* Only generate class variables for the root of the inheritance
       hierarchy since these will be the same for every class.  */

@@ -4640,10 +4571,12 @@ build_dispatch_table_initializer (tree t
                                              meth_var_types),
                             elemlist);

-      elemlist = tree_cons (NULL_TREE,
-                           build_unary_op (ADDR_EXPR,
-                                           METHOD_DEFINITION 
(entries), 1),
-                           elemlist);
+      elemlist
+       = tree_cons (NULL_TREE,
+                    convert (ptr_type_node,
+                             build_unary_op (ADDR_EXPR,
+                                             METHOD_DEFINITION 
(entries), 1)),
+                    elemlist);

        initlist = tree_cons (NULL_TREE,
                             objc_build_constructor (type, nreverse 
(elemlist)),
@@ -4669,31 +4602,21 @@ static tree
  build_method_template (void)
  {
    tree _SLT_record;
-  tree decl_specs, field_decl, field_decl_chain;
+  tree field_decl, field_decl_chain;

    _SLT_record = start_struct (RECORD_TYPE, get_identifier 
(UTAG_METHOD));

-  /* 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"));
-
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* SEL _cmd; */
+  field_decl = create_field_decl (objc_selector_type, "_cmd");
    field_decl_chain = field_decl;

-  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], 
NULL_TREE);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE,
-                      get_identifier ("method_types"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  /* char *method_types; */
+  field_decl = create_field_decl (string_type_node, "method_types");
    chainon (field_decl_chain, field_decl);

    /* void *_imp; */
-
-  decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], 
NULL_TREE);
-  field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier 
("_imp"));
-  field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+  field_decl = create_field_decl (build_pointer_type (void_type_node),
+                                 "_imp");
    chainon (field_decl_chain, field_decl);

    finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
@@ -4705,21 +4628,18 @@ build_method_template (void)
  static tree
  generate_dispatch_table (tree type, const char *name, int size, tree 
list)
  {
-  tree sc_spec, decl_specs, decl, initlist;
-
-  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
+  tree decl, initlist;

-  decl = start_decl (synth_id_with_class_suffix (name, 
objc_implementation_context),
-                    decl_specs, 1, NULL_TREE);
+  decl = start_var_decl (type, synth_id_with_class_suffix
+                              (name, objc_implementation_context));

    initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0, 
0));
    initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size, 0), 
initlist);
    initlist = tree_cons (NULL_TREE, list, initlist);

-  finish_decl (decl,
-              objc_build_constructor (TREE_TYPE (decl), nreverse 
(initlist)),
-              NULL_TREE);
+  finish_var_decl (decl,
+                  objc_build_constructor (TREE_TYPE (decl),
+                                          nreverse (initlist)));

    return decl;
  }
@@ -4752,21 +4672,13 @@ static void
  generate_dispatch_tables (void)
  {
    tree initlist, chain, method_list_template;
-  tree cast, variable_length_type;
+  tree variable_length_type
+    = xref_tag (RECORD_TYPE, get_identifier (UTAG_METHOD_LIST));
    int size;

    if (!objc_method_template)
      objc_method_template = build_method_template ();

-  cast
-    = build_tree_list
-      (build_tree_list (NULL_TREE,
-                       xref_tag (RECORD_TYPE,
-                                 get_identifier (UTAG_METHOD_LIST))),
-       NULL_TREE);
-
-  variable_length_type = groktypename (cast);
-
    chain = CLASS_CLS_METHODS (objc_implementation_context);
    if (chain)
      {
@@ -4819,10 +4731,10 @@ generate_dispatch_tables (void)
  static tree
  generate_protocol_list (tree i_or_p)
  {
-  tree initlist, decl_specs, sc_spec;
-  tree refs_decl, expr_decl, lproto, e, plist;
-  tree cast_type;
+  tree initlist;
+  tree refs_decl, lproto, e, plist;
    int size = 0;
+  const char *ref_name;

    if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
        || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
@@ -4832,13 +4744,6 @@ generate_protocol_list (tree i_or_p)
    else
      abort ();

-  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))
      if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
@@ -4848,8 +4753,8 @@ generate_protocol_list (tree i_or_p)
    /* Build initializer.  */
    initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), 
NULL_TREE);

-  e = build_int_cst (NULL_TREE, size, 0);
-  TREE_TYPE (e) = cast_type;
+  e = convert (build_pointer_type (objc_protocol_template),
+              build_int_cst (NULL_TREE, size, 0));
    initlist = tree_cons (NULL_TREE, e, initlist);

    for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
@@ -4866,38 +4771,23 @@ generate_protocol_list (tree i_or_p)

    /* static struct objc_protocol *refs[n]; */

-  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-  decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
-                                          get_identifier 
(UTAG_PROTOCOL)),
-                         sc_spec);
-
    if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
-    expr_decl = build_nt (ARRAY_REF,
-                         synth_id_with_class_suffix 
("_OBJC_PROTOCOL_REFS",
-                                                     i_or_p),
-                         build_int_cst (NULL_TREE, size + 2, 0), 
NULL_TREE, NULL_TREE);
+    ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", 
i_or_p);
    else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
-    expr_decl = build_nt (ARRAY_REF,
-                         synth_id_with_class_suffix 
("_OBJC_CLASS_PROTOCOLS",
-                                                     i_or_p),
-                         build_int_cst (NULL_TREE, size + 2, 0), 
NULL_TREE, NULL_TREE);
+    ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", 
i_or_p);
    else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
-    expr_decl
-      = build_nt (ARRAY_REF,
-                 synth_id_with_class_suffix 
("_OBJC_CATEGORY_PROTOCOLS",
-                                             i_or_p),
-                 build_int_cst (NULL_TREE, size + 2, 0), NULL_TREE, 
NULL_TREE);
+    ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", 
i_or_p);
    else
      abort ();

-  expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
+  refs_decl = start_var_decl
+             (build_array_type
+              (build_pointer_type (objc_protocol_template),
+               build_index_type (build_int_2 (size + 2, 0))),
+              ref_name);

-  refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
-  DECL_CONTEXT (refs_decl) = NULL_TREE;
-
-  finish_decl (refs_decl, objc_build_constructor (TREE_TYPE 
(refs_decl),
-                                                 nreverse (initlist)),
-              NULL_TREE);
+  finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE 
(refs_decl),
+                                                     nreverse 
(initlist)));

    return refs_decl;
  }
@@ -4931,24 +4821,18 @@ build_category_initializer (tree type, t
    if (!protocol_list)
       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), 
initlist);
    else
-     {
-       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;
-       initlist = tree_cons (NULL_TREE, expr, initlist);
-     }
+    {
+      expr = convert (build_pointer_type
+                     (build_pointer_type
+                      (objc_protocol_template)),
+                     build_unary_op (ADDR_EXPR, protocol_list, 0));
+      initlist = tree_cons (NULL_TREE, expr, initlist);
+    }

    return objc_build_constructor (type, nreverse (initlist));
  }

-/* struct objc_class {
+/* struct _objc_class {
       struct objc_class *isa;
       struct objc_class *super_class;
       char *name;
@@ -5033,20 +4917,13 @@ build_shared_structure_initializer (tree
    if (! protocol_list)
      initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0), 
initlist);
    else
-     {
-       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;
-     initlist = tree_cons (NULL_TREE, expr, initlist);
-     }
+    {
+      expr = convert (build_pointer_type
+                     (build_pointer_type
+                      (objc_protocol_template)),
+                     build_unary_op (ADDR_EXPR, protocol_list, 0));
+      initlist = tree_cons (NULL_TREE, expr, initlist);
+    }

    if (flag_next_runtime)
      /* sel_id = NULL */
@@ -5075,7 +4952,7 @@ lookup_category (tree class, tree cat_na
  static void
  generate_category (tree cat)
  {
-  tree sc_spec, decl_specs, decl;
+  tree decl;
    tree initlist, cat_name_expr, class_name_expr;
    tree protocol_decl, category;

@@ -5095,12 +4972,9 @@ generate_category (tree cat)
    else
      protocol_decl = 0;

-  sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], 
NULL_TREE);
-  decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec);
-
-  decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
-                                                
objc_implementation_context),
-                    decl_specs, 1, NULL_TREE);
+  decl = start_var_decl (objc_category_template,
+                        synth_id_with_class_suffix
+                        ("_OBJC_CATEGORY", 
objc_implementation_context));

    initlist = build_category_initializer (TREE_TYPE (decl),
                                          cat_name_expr, class_name_expr,
@@ -5108,7 +4982,7 @@ generate_category (tree cat)
                                          UOBJC_CLASS_METHODS_decl,
                                          protocol_decl);

-  finish_decl (decl, initlist, NULL_TREE);
+  finish_var_decl (decl, initlist);
  }

  /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
@@ -5146,12 +5020,7 @@ generate_shared_structures (void)
      /* No super class.  */
      my_root_id = CLASS_NAME (implementation_template);

-  cast_type
-    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
-                                                     
objc_class_template),
-                                    build1 (INDIRECT_REF,
-                                            NULL_TREE, NULL_TREE)));
-
+  cast_type = build_pointer_type (objc_class_template);
    name_expr = add_objc_string (CLASS_NAME (implementation_template),
                                class_names);

@@ -5181,8 +5050,9 @@ generate_shared_structures (void)
    sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
    decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);

-  decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1,
-                    NULL_TREE);
+  decl = start_var_decl (objc_class_template,
+                        IDENTIFIER_POINTER
+                        (DECL_NAME (UOBJC_METACLASS_decl)));

    initlist
      = build_shared_structure_initializer
@@ -5194,12 +5064,13 @@ generate_shared_structures (void)
         UOBJC_CLASS_VARIABLES_decl,
         protocol_decl);

-  finish_decl (decl, initlist, NULL_TREE);
+  finish_var_decl (decl, initlist);

    /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */

-  decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
-                    NULL_TREE);
+  decl = start_var_decl (objc_class_template,
+                        IDENTIFIER_POINTER
+                        (DECL_NAME (UOBJC_CLASS_decl)));

    initlist
      = build_shared_structure_initializer
@@ -5214,19 +5085,18 @@ generate_shared_structures (void)
         UOBJC_INSTANCE_VARIABLES_decl,
         protocol_decl);

-  finish_decl (decl, initlist, NULL_TREE);
+  finish_var_decl (decl, initlist);
  }

-static tree
+
+static const char *
  synth_id_with_class_suffix (const char *preamble, tree ctxt)
  {
-  char *string;
+  static char string[BUFSIZE];
+
    if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
        || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
      {
-      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)));
      }
@@ -5238,37 +5108,17 @@ synth_id_with_class_suffix (const char *
         = 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)
-                               + 3);
        sprintf (string, "%s_%s_%s", preamble, class_name, 
class_super_name);
      }
    else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
      {
        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);
      }
    else
      abort ();

-  return get_identifier (string);
-}
-
-static int
-is_objc_type_qualifier (tree node)
-{
-  return (TREE_CODE (node) == IDENTIFIER_NODE
-         && (node == ridpointers [(int) RID_CONST]
-             || node == ridpointers [(int) RID_VOLATILE]
-             || node == ridpointers [(int) RID_IN]
-             || node == ridpointers [(int) RID_OUT]
-             || node == ridpointers [(int) RID_INOUT]
-             || node == ridpointers [(int) RID_BYCOPY]
-              || node == ridpointers [(int) RID_BYREF]
-             || node == ridpointers [(int) RID_ONEWAY]));
+  return string;
  }

  /* If type is empty or only type qualifiers are present, add default
@@ -5277,30 +5127,16 @@ is_objc_type_qualifier (tree node)
  static tree
  adjust_type_for_id_default (tree type)
  {
-  tree declspecs, chain;
-
    if (!type)
-    return build_tree_list (build_tree_list (NULL_TREE, 
objc_object_reference),
-                           build1 (INDIRECT_REF, NULL_TREE, 
NULL_TREE));
+    type = make_node (TREE_LIST);

-  declspecs = TREE_PURPOSE (type);
+  if (!TREE_VALUE (type))
+    TREE_VALUE (type) = objc_object_type;
+  else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
+          && TYPED_OBJECT (TREE_VALUE (type)))
+    error ("can not use an object as parameter to a method");

-  /* Determine if a typespec is present.  */
-  for (chain = declspecs;
-       chain;
-       chain = TREE_CHAIN (chain))
-    {
-      if (TYPED_OBJECT (TREE_VALUE (chain))
-          && !(TREE_VALUE (type)
-               && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
-        error ("can not use an object as parameter to a method\n");
-      if (!is_objc_type_qualifier (TREE_VALUE (chain)))
-       return type;
-    }
-
-  return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
-                                    declspecs),
-                         build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
+  return type;
  }

  /*   Usage:
@@ -5322,7 +5158,7 @@ adjust_type_for_id_default (tree type)
       Out:      an instance of "keyword_decl".  */

  tree
-build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
+objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
  {
    tree keyword_decl;

@@ -5393,7 +5229,7 @@ build_keyword_selector (tree selector)

  /* Used for declarations and definitions.  */

-tree
+static tree
  build_method_decl (enum tree_code code, tree ret_type, tree selector,
                    tree add_args)
  {
@@ -5442,10 +5278,10 @@ get_arg_type_list (tree meth, int contex
    /* Receiver type.  */
    if (flag_next_runtime && superflag)
      arglist = build_tree_list (NULL_TREE, objc_super_type);
-  else if (context == METHOD_DEF)
-    arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
+  else if (context == METHOD_DEF && TREE_CODE (meth) == 
INSTANCE_METHOD_DECL)
+    arglist = build_tree_list (NULL_TREE, objc_instance_type);
    else
-    arglist = build_tree_list (NULL_TREE, objc_id_type);
+    arglist = build_tree_list (NULL_TREE, objc_object_type);

    /* Selector type - will eventually change to `int'.  */
    chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
@@ -5458,23 +5294,29 @@ get_arg_type_list (tree meth, int contex
    /* Build a list of argument types.  */
    for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
      {
-      tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey));
-      chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE 
(arg_decl)));
+      tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+
+      chainon (arglist, build_tree_list (NULL_TREE, arg_type));
      }

-  if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
-    /* We have a `, ...' immediately following the selector,
-       finalize the arglist...simulate get_parm_info (true).  */
-    ;
-  else if (METHOD_ADD_ARGS (meth))
+  if (METHOD_ADD_ARGS (meth))
      {
-      /* we have a variable length selector */
-      tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth));
-      chainon (arglist, add_arg_list);
+      for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
+          akey; akey = TREE_CHAIN (akey))
+       {
+         tree arg_type = TREE_TYPE (TREE_VALUE (akey));
+
+         chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+       }
+
+      if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
+       goto lack_of_ellipsis;
      }
    else
-    /* finalize the arglist...simulate get_parm_info (false) */
-    chainon (arglist, void_list_node);
+    {
+     lack_of_ellipsis:
+      chainon (arglist, OBJC_VOID_AT_END);
+    }

    return arglist;
  }
@@ -5516,7 +5358,7 @@ check_duplicates (hash hsh, int methods,
  }

  /* If RECEIVER is a class reference, return the identifier node for
-   the referenced class.  RECEIVER is created by get_class_reference,
+   the referenced class.  RECEIVER is created by 
objc_get_class_reference,
     so we check the exact form created depending on which runtimes are
     used.  */

@@ -5537,8 +5379,7 @@ receiver_is_class_object (tree receiver,
      {
        /* The receiver is a variable created by
           build_class_reference_decl.  */
-      if (TREE_CODE (receiver) == VAR_DECL
-         && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE 
(objc_class_type))
+      if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE 
(receiver)))
          /* Look up the identifier.  */
         for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
           if (TREE_PURPOSE (chain) == receiver)
@@ -5592,11 +5433,15 @@ objc_message_selector (void)
     (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);  
*/

  tree
-build_message_expr (tree mess)
+objc_build_message_expr (tree mess)
  {
    tree receiver = TREE_PURPOSE (mess);
    tree sel_name;
+#ifdef OBJCPLUS
+  tree args = TREE_PURPOSE (TREE_VALUE (mess));
+#else
    tree args = TREE_VALUE (mess);
+#endif
    tree method_params = NULL_TREE;

    if (TREE_CODE (receiver) == ERROR_MARK)
@@ -5613,6 +5458,9 @@ build_message_expr (tree mess)

    /* Build the parameter list to give to the method.  */
    if (TREE_CODE (args) == TREE_LIST)
+#ifdef OBJCPLUS
+    method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
+#else
      {
        tree chain = args, prev = NULL_TREE;

@@ -5634,6 +5482,7 @@ build_message_expr (tree mess)
          }
        method_params = args;
      }
+#endif

  #ifdef OBJCPLUS
    if (processing_template_decl)
@@ -5642,7 +5491,7 @@ build_message_expr (tree mess)
                          method_params);
  #endif

-  return finish_message_expr (receiver, sel_name, method_params);
+  return objc_finish_message_expr (receiver, sel_name, method_params);
  }

  /* Look up method SEL_NAME that would be suitable for receiver
@@ -5668,13 +5517,13 @@ lookup_method_in_hash_lists (tree sel_na
    return check_duplicates (method_prototype, 1, is_class);
  }

-/* The 'finish_message_expr' routine is called from within
-   'build_message_expr' for non-template functions.  In the case of
+/* The 'objc_finish_message_expr' routine is called from within
+   'objc_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 (tree receiver, tree sel_name, tree method_params)
+objc_finish_message_expr (tree receiver, tree sel_name, tree 
method_params)
  {
    tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
    tree selector, retval, class_tree;
@@ -5687,6 +5536,7 @@ finish_message_expr (tree receiver, tree
    while (TREE_CODE (rtype) == COMPOUND_EXPR
               || TREE_CODE (rtype) == MODIFY_EXPR
               || TREE_CODE (rtype) == NOP_EXPR
+             || TREE_CODE (rtype) == CONVERT_EXPR
               || TREE_CODE (rtype) == COMPONENT_REF)
      rtype = TREE_OPERAND (rtype, 0);
    self = (rtype == self_decl);
@@ -5724,8 +5574,7 @@ finish_message_expr (tree receiver, tree
    /* If receiver is of type `id' or `Class' (or if the @interface for a
       class is not visible), we shall be satisfied with the existence of
       any instance or class method. */
-  if (!rtype || IS_ID (rtype)
-       || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
+  if (!rtype || objc_is_id (rtype))
      {
        if (!rtype)
         rtype = xref_tag (RECORD_TYPE, class_tree);
@@ -5735,7 +5584,10 @@ finish_message_expr (tree receiver, tree
           rtype = NULL_TREE;
         }
        else
-       class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
+       {
+         class_tree = objc_class_name;
+         OBJC_SET_TYPE_NAME (rtype, class_tree);
+       }

        if (rprotos)
         method_prototype
@@ -5753,10 +5605,10 @@ finish_message_expr (tree receiver, tree
        if (TREE_CODE (rtype) == POINTER_TYPE)
         rtype = TREE_TYPE (rtype);
        /* Traverse typedef aliases */
-      while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
-            && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
-            && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
-       rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
+      while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
+            && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
+            && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
+       rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
        saved_rtype = rtype;
        if (TYPED_OBJECT (rtype))
         {
@@ -5800,7 +5652,7 @@ finish_message_expr (tree receiver, tree
        else
         {
           warning ("invalid receiver type `%s'",
-                  gen_declaration (orig_rtype, errbuf));
+                  gen_type_name (orig_rtype, errbuf));
           rtype = rprotos = NULL_TREE;
         }
      }
@@ -5863,15 +5715,15 @@ build_objc_method_call (int super_flag,
                  (!flag_next_runtime || flag_nil_receivers
                   ? umsg_decl
                   : umsg_nonnil_decl));
-  tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
+  tree rcv_p = (super_flag ? objc_super_type : objc_object_type);

    /* If a prototype for the method to be called exists, then cast
       the sender's return type and arguments to match that of the 
method.
       Otherwise, leave sender as is.  */
    tree ret_type
      = (method_prototype
-       ? groktypename (TREE_TYPE (method_prototype))
-       : objc_id_type);
+       ? TREE_VALUE (TREE_TYPE (method_prototype))
+       : objc_object_type);
    tree sender_cast
      = build_pointer_type
        (build_function_type
@@ -5933,29 +5785,13 @@ build_objc_method_call (int super_flag,
  static void
  build_protocol_reference (tree p)
  {
-  tree decl, ident, ptype;
+  tree decl;
+  const char *proto_name;

-  /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
+  /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */

-  ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
-  ptype
-    = groktypename (build_tree_list (build_tree_list (NULL_TREE,
-                                                     
objc_protocol_template),
-                                    NULL_TREE));
-
-  if (identifier_global_value (ident))
-    decl = identifier_global_value (ident); /* Set by pushdecl.  */
-  else
-    {
-      decl = build_decl (VAR_DECL, ident, ptype);
-      DECL_EXTERNAL (decl) = 1;
-      TREE_PUBLIC (decl) = 0;
-      TREE_USED (decl) = 1;
-      DECL_ARTIFICIAL (decl) = 1;
-
-      make_decl_rtl (decl);
-      pushdecl_top_level (decl);
-   }
+  proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
+  decl = start_var_decl (objc_protocol_template, proto_name);

    PROTOCOL_FORWARD_DECL (p) = decl;
  }
@@ -5963,7 +5799,7 @@ build_protocol_reference (tree p)
  /* This function is called by the parser when (and only when) a
     @protocol() expression is found, in order to compile it.  */
  tree
-build_protocol_expr (tree protoname)
+objc_build_protocol_expr (tree protoname)
  {
    tree expr;
    tree p = lookup_protocol (protoname);
@@ -6035,7 +5871,7 @@ build_protocol_expr (tree protoname)
     is found, in order to compile it.  It is only called by the parser
     and only to compile a @selector().  */
  tree
-build_selector_expr (tree selnamelist)
+objc_build_selector_expr (tree selnamelist)
  {
    tree selname;

@@ -6081,7 +5917,7 @@ build_selector_expr (tree selnamelist)
  }

  tree
-build_encode_expr (tree type)
+objc_build_encode_expr (tree type)
  {
    tree result;
    const char *string;
@@ -6097,7 +5933,7 @@ build_encode_expr (tree type)
    return result;
  }

-tree
+static tree
  build_ivar_reference (tree id)
  {
    if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
@@ -6113,7 +5949,7 @@ build_ivar_reference (tree id)
          paradigm.  */
        warning ("instance variable `%s' accessed in class method",
                IDENTIFIER_POINTER (id));
-      TREE_TYPE (self_decl) = objc_instance_type; /* cast */
+      self_decl = convert (objc_instance_type, self_decl); /* cast */
      }

    return build_component_ref (build_indirect_ref (self_decl, "->"), 
id);
@@ -6140,6 +5976,10 @@ hash_init (void)
      = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
    cls_method_hash_list
      = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
+
+  /* Initialize the hash table used to hold the constant string 
objects.  */
+  string_htab = htab_create_ggc (31, string_hash,
+                                  string_eq, NULL);
  }

  /* WARNING!!!!  hash_enter is called with a method, and will peek
@@ -6288,12 +6128,14 @@ add_method_to_hash_list (hash *hash_list
      }
  }

-tree
+static tree
  objc_add_method (tree class, tree method, int is_class)
  {
    tree mth;

-  if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : 
CLASS_NST_METHODS (class), method)))
+  if (!(mth = lookup_method (is_class
+                            ? CLASS_CLS_METHODS (class)
+                            : CLASS_NST_METHODS (class), method)))
      {
        /* put method on list in reverse order */
        if (is_class)
@@ -6318,7 +6160,8 @@ objc_add_method (tree class, tree method
            || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
           && !comp_proto_with_proto (method, mth))
         error ("duplicate declaration of method `%c%s'",
-               is_class ? '+' : '-', IDENTIFIER_POINTER 
(METHOD_SEL_NAME (mth)));
+               is_class ? '+' : '-',
+               IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
      }

    if (is_class)
@@ -6374,16 +6217,13 @@ add_category (tree class, tree category)

     PUBLIC is 1 for public, 0 for protected, and 2 for private.  */

-tree
-add_instance_variable (tree class, int public, tree declarator,
-                      tree declspecs, tree width)
+static tree
+add_instance_variable (tree class, int public, tree field_decl)
  {
-  tree field_decl = grokfield (declarator, declspecs, width);
    tree field_type = TREE_TYPE (field_decl);
    const char *ivar_name = DECL_NAME (field_decl)
                           ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
                           : "<unnamed>";
-  tree raw_decl;

  #ifdef OBJCPLUS
    if (TREE_CODE (field_type) == REFERENCE_TYPE)
@@ -6396,13 +6236,8 @@ add_instance_variable (tree class, int p
  #endif

    if (field_type == error_mark_node || !TYPE_SIZE (field_type)
-      || TYPE_SIZE (field_type) == error_mark_node
+      || TYPE_SIZE (field_type) == error_mark_node)
        /* 'type[0]' is allowed, but 'type[]' is not! */
-#ifdef OBJCPLUS
-      || (TYPE_SIZE (field_type) == bitsize_zero_node
-         && !TREE_OPERAND (declarator, 1))
-#endif
-      )
      {
        error ("instance variable `%s' has unknown size", ivar_name);
        /* Return class as is without adding this ivar.  */
@@ -6457,13 +6292,12 @@ add_instance_variable (tree class, int p

      }

-  raw_decl = build_tree_list (declspecs, build_tree_list (declarator, 
width));
-  CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), 
raw_decl);
-  CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
+  CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), 
field_decl);
+
    return class;
  }


-tree
+static tree
  is_ivar (tree decl_chain, tree ident)
  {
    for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
@@ -6474,7 +6308,7 @@ is_ivar (tree decl_chain, tree ident)

  /* True if the ivar is private and we are not in its implementation.  
*/

-int
+static int
  is_private (tree decl)
  {
    return (TREE_PRIVATE (decl)
@@ -6546,7 +6380,7 @@ objc_is_public (tree expr, tree identifi

        else if (objc_implementation_context && (basetype == 
objc_object_reference))
         {
-         TREE_TYPE (expr) = uprivate_record;
+         expr = convert (uprivate_record, expr);
           warning ("static access to object of type `id'");
         }
      }
@@ -6752,7 +6586,7 @@ check_protocols (tree proto_list, const
     It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
     CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.  */

-tree
+static tree
  start_class (enum tree_code code, tree class_name, tree super_name,
              tree protocol_list)
  {
@@ -6775,17 +6609,27 @@ start_class (enum tree_code code, tree c
    class = make_node (code);
    TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);

+  /* Check for existence of the super class, if one was specified.  */
+  if ((code == CLASS_INTERFACE_TYPE || code == 
CLASS_IMPLEMENTATION_TYPE)
+      && super_name && !objc_is_class_name (super_name))
+    {
+      error ("cannot find interface declaration for `%s', superclass 
of `%s'",
+            IDENTIFIER_POINTER (super_name),
+            IDENTIFIER_POINTER (class_name));
+      super_name = NULL_TREE;
+    }
+
    CLASS_NAME (class) = class_name;
    CLASS_SUPER_NAME (class) = super_name;
    CLASS_CLS_METHODS (class) = NULL_TREE;

-  if (! is_class_name (class_name)
+  if (! objc_is_class_name (class_name)
        && (decl = lookup_name (class_name)))
      {
        error ("`%s' redeclared as different kind of symbol",
              IDENTIFIER_POINTER (class_name));
        error ("%Jprevious declaration of '%D'",
-             decl, decl);
+            decl, decl);
      }

    if (code == CLASS_IMPLEMENTATION_TYPE)
@@ -6899,7 +6743,7 @@ start_class (enum tree_code code, tree c
    return class;
  }

-tree
+static tree
  continue_class (tree class)
  {
    if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
@@ -6910,15 +6754,16 @@ continue_class (tree class)

        /* Check consistency of the instance variables.  */

-      if (CLASS_IVARS (class))
+      if (CLASS_RAW_IVARS (class))
         check_ivars (implementation_template, class);

        /* code generation */

-      ivar_context = build_private_template (implementation_template);
+#ifdef OBJCPLUS
+      push_lang_context (lang_name_c);
+#endif

-      if (!objc_class_template)
-       build_class_template ();
+      ivar_context = build_private_template (implementation_template);

        imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct 
imp_entry));

@@ -6937,21 +6782,33 @@ continue_class (tree class)
        else
         cat_count++;

+#ifdef OBJCPLUS
+      pop_lang_context ();
+#endif /* OBJCPLUS */
+
        return ivar_context;
      }

    else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
      {
+#ifdef OBJCPLUS
+      push_lang_context (lang_name_c);
+#endif /* OBJCPLUS */
+
        if (!CLASS_STATIC_TEMPLATE (class))
         {
           tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
-         finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
+         finish_struct (record, get_class_ivars (class), NULL_TREE);
           CLASS_STATIC_TEMPLATE (class) = record;

           /* Mark this record as a class template for static typing.  */
           TREE_STATIC_TEMPLATE (record) = 1;
         }

+#ifdef OBJCPLUS
+      pop_lang_context ();
+#endif /* OBJCPLUS */
+
        return NULL_TREE;
      }

@@ -6961,7 +6818,7 @@ continue_class (tree class)

  /* This is called once we see the "@end" in an 
interface/implementation.  */

-void
+static void
  finish_class (tree class)
  {
    if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
@@ -7004,7 +6861,7 @@ finish_class (tree class)

    else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
      {
-      tree decl_specs;
+      tree decl;
        const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
        char *string = (char *) alloca (strlen (class_name) + 3);

@@ -7012,10 +6869,11 @@ finish_class (tree class)

        sprintf (string, "_%s", class_name);

-      decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) 
RID_EXTERN]);
-      decl_specs = tree_cons (NULL_TREE, objc_object_reference, 
decl_specs);
-      define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier 
(string)),
-                  decl_specs);
+      decl = build_decl (VAR_DECL, get_identifier (string),
+                        build_pointer_type (objc_object_reference));
+      DECL_EXTERNAL (decl) = 1;
+      lang_hooks.decls.pushdecl (decl);
+      finish_decl (decl, NULL_TREE, NULL_TREE);
      }
  }

@@ -7073,7 +6931,7 @@ objc_declare_protocols (tree names)
      }
  }

-tree
+static tree
  start_protocol (enum tree_code code, tree name, tree list)
  {
    tree protocol;
@@ -7084,11 +6942,6 @@ start_protocol (enum tree_code code, tre
    }
  #endif /* OBJCPLUS */

-  /* 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 = lookup_protocol (name);

    if (!protocol)
@@ -7119,11 +6972,6 @@ start_protocol (enum tree_code code, tre
    return protocol;
  }

-void
-finish_protocol (tree protocol ATTRIBUTE_UNUSED)
-{
-}
-


  /* "Encode" a data type into a string, which grows in util_obstack.
     ??? What is the FORMAT?  Someone please document this!  */
@@ -7135,9 +6983,7 @@ encode_type_qualifiers (tree declspecs)

    for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
      {
-      if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec))
-       obstack_1grow (&util_obstack, 'r');
-      else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
+      if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
         obstack_1grow (&util_obstack, 'n');
        else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
         obstack_1grow (&util_obstack, 'N');
@@ -7208,6 +7054,11 @@ encode_pointer (tree type, int curtype,

        if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), 
"BOOL"))
         {
+         /* It appears that "r*" means "const char *" rather than
+            "char *const".  */
+         if (TYPE_READONLY (pointer_to))
+           obstack_1grow (&util_obstack, 'r');
+
           obstack_1grow (&util_obstack, '*');
           return;
         }
@@ -7234,9 +7085,9 @@ encode_array (tree type, int curtype, in
        return;
      }

-  sprintf (buffer, "[%ld",
-          (long) (TREE_INT_CST_LOW (an_int_cst)
-                  / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+  sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
+                  (TREE_INT_CST_LOW (an_int_cst)
+                   / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));

    obstack_grow (&util_obstack, buffer, strlen (buffer));
    encode_type (array_of, curtype, format);
@@ -7357,6 +7208,9 @@ encode_type (tree type, int curtype, int
    enum tree_code code = TREE_CODE (type);
    char c;

+  if (TYPE_READONLY (type))
+    obstack_1grow (&util_obstack, 'r');
+
    if (code == INTEGER_TYPE)
      {
        switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
@@ -7494,110 +7348,124 @@ encode_field_decl (tree field_decl, int
      encode_type (TREE_TYPE (field_decl), curtype, format);
  }

+static GTY(()) tree objc_parmlist = NULL_TREE;
+
+/* Append PARM to a list of formal parameters of a method, making a 
necessary
+   array-to-pointer adjustment along the way.  */
+
+static void
+objc_push_parm (tree parm)
+{
+  /* Convert array parameters of unknown size into pointers.  */
+  if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
+      && !TYPE_SIZE (TREE_TYPE (parm)))
+    TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE 
(parm)));
+
+  objc_parmlist = chainon (objc_parmlist, parm);
+}
+
+/* Retrieve the formal paramter list constructed via preceding calls to
+   objc_push_parm().  */
+
  static tree
-objc_expr_last (tree complex_expr)
+#ifdef OBJCPLUS
+objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
+#else
+objc_get_parm_info (int have_ellipsis)
+#endif
  {
-  tree next;
+  tree parm_info = objc_parmlist;

-  if (complex_expr)
-    while ((next = TREE_OPERAND (complex_expr, 0)))
-      complex_expr = next;
+#ifndef OBJCPLUS
+  /* The C front-end requires an elaborate song and dance at
+     this point.  */
+  push_scope ();
+  declare_parm_level ();
+  while (parm_info)
+    {
+      tree next = TREE_CHAIN (parm_info);

-  return complex_expr;
+      TREE_CHAIN (parm_info) = NULL_TREE;
+      pushdecl (parm_info);
+      parm_info = next;
+    }
+  parm_info = get_parm_info (have_ellipsis);
+  pop_scope ();
+#endif
+  objc_parmlist = NULL_TREE;
+
+  return parm_info;
  }

+/* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed 
for ObjC
+   method definitions.  In the case of instance methods, we can be more
+   specific as to the type of 'self'.  */
+
  static void
  synth_self_and_ucmd_args (void)
  {
-  tree decl_specs;
+  tree self_type;

    if (objc_method_context
        && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
-    decl_specs = build_tree_list (NULL_TREE, uprivate_record);
+    self_type = objc_instance_type;
    else
      /* Really a `struct objc_class *'. However, we allow people to
         assign to self, which changes its type midstream.  */
-    decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
+    self_type = objc_object_type;
+
+  /* id self; */
+  objc_push_parm (build_decl (PARM_DECL, self_id, self_type));

-  push_parm_decl (build_tree_list
-                 (build_tree_list (decl_specs,
-                                   build1 (INDIRECT_REF, NULL_TREE, 
self_id)),
-                  unused_list));
-
-  decl_specs = build_tree_list (NULL_TREE, TREE_TYPE 
(objc_selector_type));
-  push_parm_decl (build_tree_list
-                 (build_tree_list (decl_specs,
-                                   build1 (INDIRECT_REF, NULL_TREE, 
ucmd_id)),
-                  unused_list));
+  /* SEL _cmd; */
+  objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
  }

-/* Transform a method definition into a function definition as follows:
-   - synthesize the first two arguments, "self" and "_cmd".  */
+/* Transform an Objective-C method definition into a static C function
+   definition, synthesizing the first two arguments, "self" and "_cmd",
+   in the process.  */

-void
+static void
  start_method_def (tree method)
  {
+  tree parmlist;
+  int have_ellipsis = 0;
+
    /* Required to implement _msgSuper.  */
    objc_method_context = method;
    UOBJC_SUPER_decl = NULL_TREE;

-  /* Must be called BEFORE start_function.  */
-  push_scope ();
-  declare_parm_level ();
-
    /* Generate prototype declarations for arguments..."new-style".  */
    synth_self_and_ucmd_args ();

    /* Generate argument declarations if a keyword_decl.  */
-  if (METHOD_SEL_ARGS (method))
+  parmlist = METHOD_SEL_ARGS (method);
+  while (parmlist)
      {
-      tree arglist = METHOD_SEL_ARGS (method);
-      do
-       {
-         tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist));
-         tree arg_decl = TREE_VALUE (TREE_TYPE (arglist));
-
-         if (arg_decl)
-           {
-             tree last_expr = objc_expr_last (arg_decl);
+      tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
+                             TREE_VALUE (TREE_TYPE (parmlist)));

-             /* Unite the abstract decl with its name.  */
-             TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
-             push_parm_decl (build_tree_list
-                             (build_tree_list (arg_spec, arg_decl),
-                              NULL_TREE));
-
-#ifndef OBJCPLUS
-             /* Unhook: restore the abstract declarator.  */
-             TREE_OPERAND (last_expr, 0) = NULL_TREE;
-#endif
-           }
-
-         else
-           push_parm_decl (build_tree_list
-                           (build_tree_list (arg_spec,
-                                             KEYWORD_ARG_NAME 
(arglist)),
-                            NULL_TREE));
-
-         arglist = TREE_CHAIN (arglist);
-       }
-      while (arglist);
+      objc_push_parm (parm);
+      parmlist = TREE_CHAIN (parmlist);
      }

-  if (METHOD_ADD_ARGS (method) != NULL_TREE
-      && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
+  if (METHOD_ADD_ARGS (method))
      {
-      /* We have a variable length selector - in "prototype" format.  
*/
-      tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
-      while (akey)
+      tree akey;
+
+      for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
+          akey; akey = TREE_CHAIN (akey))
         {
-         /* This must be done prior to calling pushdecl.  pushdecl is
-            going to change our chain on us.  */
-         tree nextkey = TREE_CHAIN (akey);
-         pushdecl (akey);
-         akey = nextkey;
+         objc_push_parm (TREE_VALUE (akey));
         }
+
+      if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
+       have_ellipsis = 1;
      }
+
+  parmlist = objc_get_parm_info (have_ellipsis);
+
+  really_start_method (objc_method_context, parmlist);
  }

  static void
@@ -7608,34 +7476,22 @@ warn_with_method (const char *message, i
             message, mtype, gen_method_decl (method, errbuf));
  }

-/* Return 1 if METHOD is consistent with PROTO.  */
-
-static int
-comp_method_with_proto (tree method, tree proto)
-{
-  /* 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 (function1_template)
-    = get_arg_type_list (proto, METHOD_DEF, 0);
-
-  /* install return type */
-  TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
-
-  return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), 
function1_template);
-}
-
-/* Return 1 if TYPE1 is equivalent to TYPE2.  */
+/* Return 1 if TYPE1 is equivalent to TYPE2
+   for purposes of method overloading.  */

  static int
  objc_types_are_equivalent (tree type1, tree type2)
  {
    if (type1 == type2)
      return 1;
+
+  /* Strip away indirections.  */
+  while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == 
POINTER_TYPE)
+        && (TREE_CODE (type1) == TREE_CODE (type2)))
+    type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
    if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
      return 0;
+
    type1 = TYPE_PROTOCOL_LIST (type1);
    type2 = TYPE_PROTOCOL_LIST (type2);
    if (list_length (type1) == list_length (type2))
@@ -7648,7 +7504,8 @@ objc_types_are_equivalent (tree type1, t
    return 0;
  }

-/* Return 1 if PROTO1 is equivalent to PROTO2.  */
+/* Return 1 if PROTO1 is equivalent to PROTO2
+   for purposes of method overloading.  */

  static int
  comp_proto_with_proto (tree proto1, tree proto2)
@@ -7661,8 +7518,8 @@ comp_proto_with_proto (tree proto1, tree
      return 0;

    /* Compare return types.  */
-  type1 = groktypename (TREE_TYPE (proto1));
-  type2 = groktypename (TREE_TYPE (proto2));
+  type1 = TREE_VALUE (TREE_TYPE (proto1));
+  type2 = TREE_VALUE (TREE_TYPE (proto2));

    if (!objc_types_are_equivalent (type1, type2))
      return 0;
@@ -7680,6 +7537,36 @@ comp_proto_with_proto (tree proto1, tree
    return (!type1 && !type2);
  }

+static void
+objc_start_function (tree name, tree type, tree attrs, tree params)
+{
+  tree fndecl = build_decl (FUNCTION_DECL, name, type);
+
+  DECL_ARGUMENTS (fndecl) = params;
+  DECL_INITIAL (fndecl) = error_mark_node;
+  DECL_EXTERNAL (fndecl) = 0;
+  TREE_STATIC (fndecl) = 1;
+
+#ifdef OBJCPLUS
+  retrofit_lang_decl (fndecl);
+  cplus_decl_attributes (&fndecl, attrs, 0);
+  start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
+#else
+  decl_attributes (&fndecl, attrs, 0);
+  announce_function (fndecl);
+  current_function_decl = pushdecl (fndecl);
+  push_scope ();
+  declare_parm_level ();
+  DECL_RESULT (current_function_decl)
+    = build_decl (RESULT_DECL, NULL_TREE,
+                 TREE_TYPE (TREE_TYPE (current_function_decl)));
+  start_fname_decls ();
+  store_parm_decls ();
+#endif
+
+  TREE_USED (current_function_decl) = 1;
+}
+
  /* - Generate an identifier for the function. the format is "_n_cls",
       where 1 <= n <= nMethods, and cls is the name the implementation 
we
       are processing.
@@ -7689,15 +7576,13 @@ comp_proto_with_proto (tree proto1, tree
  static void
  really_start_method (tree method, tree parmlist)
  {
-  tree sc_spec, ret_spec, ret_decl, decl_specs;
-  tree method_decl, method_id;
+  tree ret_type, meth_type;
+  tree method_id;
    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);
-  ret_spec = TREE_PURPOSE (TREE_TYPE (method));
-  decl_specs = chainon (sc_spec, ret_spec);
+  ret_type = TREE_VALUE (TREE_TYPE (method));

    sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
    class_name = IDENTIFIER_POINTER (CLASS_NAME 
(objc_implementation_context));
@@ -7722,49 +7607,18 @@ really_start_method (tree method, tree p
    push_lang_context (lang_name_c);
  #endif

-  method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
-
-  /* Check the declarator portion of the return type for the method.  
*/
-  if ((ret_decl = TREE_VALUE (TREE_TYPE (method))))
-    {
-      /* Unite the complex decl (specified in the abstract decl) with 
the
-        function decl just synthesized..(int *), (int (*)()), (int 
(*)[]).  */
-      tree save_expr = objc_expr_last (ret_decl);
-
-      TREE_OPERAND (save_expr, 0) = method_decl;
-      method_decl = ret_decl;
-
-      /* Fool the parser into thinking it is starting a function.  */
-      start_function (decl_specs, method_decl, NULL_TREE);
+  meth_type
+    = build_function_type (ret_type,
+                          get_arg_type_list (method, METHOD_DEF, 0));
+  objc_start_function (method_id, meth_type, NULL_TREE, parmlist);

-      /* Unhook: this has the effect of restoring the abstract 
declarator.  */
-      TREE_OPERAND (save_expr, 0) = NULL_TREE;
-    }
-
-  else
-    {
-      TREE_VALUE (TREE_TYPE (method)) = method_decl;
-
-      /* Fool the parser into thinking it is starting a function.  */
-      start_function (decl_specs, method_decl, NULL_TREE);
-
-      /* Unhook: this has the effect of restoring the abstract 
declarator.  */
-      TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
-    }
-
-#ifdef OBJCPLUS
-  /* set self_decl from the first argument...this global is used by
-   * build_ivar_reference().build_indirect_ref().
-   */
+  /* Set self_decl from the first argument.  */
    self_decl = DECL_ARGUMENTS (current_function_decl);

-  /* snaroff (3/28/96): when compiling with -Wall, this suppresses
-   * the following: warning:unused parameter `struct objc_selector * 
_cmd'
-   */
+  /* Suppress unused warnings.  */
    TREE_USED (self_decl) = 1;
    TREE_USED (TREE_CHAIN (self_decl)) = 1;
-  /* Ditto for the underlying (static) C function.  */
-  TREE_USED (current_function_decl) = 1;
+#ifdef OBJCPLUS
    pop_lang_context ();
  #endif

@@ -7781,7 +7635,7 @@ really_start_method (tree method, tree p

        if (proto)
         {
-         if (!comp_method_with_proto (method, proto))
+         if (!comp_proto_with_proto (method, proto))
             {
               char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? 
'-' : '+');

@@ -7811,33 +7665,6 @@ really_start_method (tree method, tree p
      }
  }

-/* The following routine is always called...this "architecture" is to
-   accommodate "old-style" variable length selectors.
-
-   - a:a b:b // prototype  ; id c; id d; // old-style.  */
-
-void
-continue_method_def (void)
-{
-  tree parmlist;
-
-  if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
-    /* We have a `, ...' immediately following the selector.  */
-    parmlist = get_parm_info (/*ellipsis=*/true);
-  else
-    parmlist = get_parm_info (/*ellipsis=*/false);
-
-#ifndef OBJCPLUS
-  /* Set self_decl from the first argument...this global is used by
-     build_ivar_reference calling build_indirect_ref.  */
-  self_decl = TREE_PURPOSE (parmlist);
-#endif /* !OBJCPLUS */
-
-  pop_scope ();
-  really_start_method (objc_method_context, parmlist);
-  store_parm_decls ();
-}
-
  static void *UOBJC_SUPER_scope = 0;

  /* _n_Method (id self, SEL sel, ...)
@@ -7846,7 +7673,7 @@ static void *UOBJC_SUPER_scope = 0;
         _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
       }  */

-tree
+static tree
  get_super_receiver (void)
  {
    if (objc_method_context)
@@ -7855,18 +7682,13 @@ get_super_receiver (void)

        if (!UOBJC_SUPER_decl)
        {
-       UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
-                                      build_tree_list (NULL_TREE,
-                                      objc_super_template),
-                                      0, NULL_TREE);
-
-       finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
-
+       UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier 
(TAG_SUPER),
+                                      objc_super_template);
         /* This prevents `unused variable' warnings when compiling with 
-Wall.  */
         TREE_USED (UOBJC_SUPER_decl) = 1;
-       DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
-
-       UOBJC_SUPER_scope = get_current_scope ();
+       lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
+        finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
+       UOBJC_SUPER_scope = objc_get_current_scope ();
        }

        /* Set receiver to self.  */
@@ -7875,13 +7697,8 @@ get_super_receiver (void)
        super_expr_list = super_expr;

        /* Set class to begin searching.  */
-#ifdef OBJCPLUS
        super_expr = build_component_ref (UOBJC_SUPER_decl,
                                         get_identifier ("super_class"));
-#else
-      super_expr = build_component_ref (UOBJC_SUPER_decl,
-                                       get_identifier ("class"));
-#endif

        if (TREE_CODE (objc_implementation_context) == 
CLASS_IMPLEMENTATION_TYPE)
         {
@@ -7911,7 +7728,7 @@ get_super_receiver (void)

           if (flag_next_runtime && !flag_zero_link)
             {
-             super_class = get_class_reference (super_name);
+             super_class = objc_get_class_reference (super_name);
               if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
                 /* If we are in a class method, we must retrieve the
                    _metaclass_ for the current class, pointed at by
@@ -7964,38 +7781,28 @@ void
  objc_clear_super_receiver (void)
  {
    if (objc_method_context
-      && UOBJC_SUPER_scope == get_current_scope ()) {
+      && UOBJC_SUPER_scope == objc_get_current_scope ()) {
      UOBJC_SUPER_decl = 0;
      UOBJC_SUPER_scope = 0;
    }
  }

-static void
-objc_expand_function_end (void)
-{
-  /* This routine may also get called for C functions, including those
-     nested within ObjC methods.  In such cases, method encoding is
-     meaningless.  */
-  if (objc_method_context == NULL_TREE
-      || DECL_INITIAL (objc_method_context) != current_function_decl)
-    return;
-
-  METHOD_ENCODING (objc_method_context)
-    = encode_method_prototype (objc_method_context);
-}
-
  void
-finish_method_def (void)
+objc_finish_method_definition (tree fndecl)
  {
-  lang_expand_function_end = objc_expand_function_end;
    /* We cannot validly inline ObjC methods, at least not without a 
language
       extension to declare that a method need not be dynamically
       dispatched, so suppress all thoughts of doing so.  */
-  DECL_INLINE (current_function_decl) = 0;
-  DECL_UNINLINABLE (current_function_decl) = 1;
+  DECL_INLINE (fndecl) = 0;
+  DECL_UNINLINABLE (fndecl) = 1;

+#ifndef OBJCPLUS
+  /* The C++ front-end will have called finish_function() for us.  */
    finish_function ();
-  lang_expand_function_end = NULL;
+#endif
+
+  METHOD_ENCODING (objc_method_context)
+    = encode_method_prototype (objc_method_context);

    /* Required to implement _msgSuper. This must be done AFTER 
finish_function,
       since the optimizer may find "may be used before set" errors.  */
@@ -8018,567 +7825,77 @@ lang_report_error_function (tree decl)
  }
  #endif

-static int
-is_complex_decl (tree type)
-{
-  return (TREE_CODE (type) == ARRAY_TYPE
-         || TREE_CODE (type) == FUNCTION_TYPE
-         || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type)));
-}
-
-

-/* Code to convert a decl node into text for a declaration in C.  */
-
-static char tmpbuf[256];
-
-static void
-adorn_decl (tree decl, char *str)
-{
-  enum tree_code code = TREE_CODE (decl);
-
-  if (code == ARRAY_REF)
-    {
-      tree an_int_cst = TREE_OPERAND (decl, 1);
-
-      if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST)
-       sprintf (str + strlen (str), "[%ld]",
-                (long) TREE_INT_CST_LOW (an_int_cst));
-      else
-       strcat (str, "[]");
-    }
-
-  else if (code == ARRAY_TYPE)
-    {
-      tree an_int_cst = TYPE_SIZE (decl);
-      tree array_of = TREE_TYPE (decl);
-
-      if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE)
-       sprintf (str + strlen (str), "[%ld]",
-                (long) (TREE_INT_CST_LOW (an_int_cst)
-                        / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
-      else
-       strcat (str, "[]");
-    }
-
-  else if (code == CALL_EXPR)
-    {
-      tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1));
-
-      strcat (str, "(");
-      while (chain)
-       {
-         gen_declaration_1 (chain, str);
-         chain = TREE_CHAIN (chain);
-         if (chain)
-           strcat (str, ", ");
-       }
-      strcat (str, ")");
-    }
-
-  else if (code == FUNCTION_TYPE)
-    {
-      tree chain  = TYPE_ARG_TYPES (decl);
-
-      strcat (str, "(");
-      while (chain && TREE_VALUE (chain) != void_type_node)
-       {
-         gen_declaration_1 (TREE_VALUE (chain), str);
-         chain = TREE_CHAIN (chain);
-         if (chain && TREE_VALUE (chain) != void_type_node)
-           strcat (str, ", ");
-       }
-      strcat (str, ")");
-    }
-
-  else if (code == INDIRECT_REF)
-    {
-      strcpy (tmpbuf, "*");
-      if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == 
TREE_LIST)
-       {
-         tree chain;
-
-         for (chain = nreverse (copy_list (TREE_TYPE (decl)));
-              chain;
-              chain = TREE_CHAIN (chain))
-           {
-             if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE)
-               {
-                 strcat (tmpbuf, " ");
-                 strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE 
(chain)));
-               }
-           }
-         if (str[0])
-           strcat (tmpbuf, " ");
-       }
-      strcat (tmpbuf, str);
-      strcpy (str, tmpbuf);
-    }
-
-  else if (code == POINTER_TYPE)
-    {
-      strcpy (tmpbuf, "*");
-      if (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
-       {
-         if (TYPE_READONLY (decl))
-           strcat (tmpbuf, " const");
-         if (TYPE_VOLATILE (decl))
-           strcat (tmpbuf, " volatile");
-         if (str[0])
-           strcat (tmpbuf, " ");
-       }
-      strcat (tmpbuf, str);
-      strcpy (str, tmpbuf);
-    }
-}
+/* Given a tree DECL node, produce a printable description of it in 
the given
+   buffer, overwriting the buffer.  */

  static char *
-gen_declarator (tree decl, char *buf, const char *name)
+gen_declaration (tree decl, char *buf)
  {
-  if (decl)
-    {
-      enum tree_code code = TREE_CODE (decl);
-      char *str;
-      tree op;
-      int wrap = 0;
-
-      switch (code)
-       {
-       case ARRAY_REF:
-       case INDIRECT_REF:
-       case CALL_EXPR:
-         op = TREE_OPERAND (decl, 0);
-
-         /* We have a pointer to a function or array...(*)(), (*)[] */
-         if ((code == ARRAY_REF || code == CALL_EXPR)
-             && op && TREE_CODE (op) == INDIRECT_REF)
-           wrap = 1;
-
-         str = gen_declarator (op, buf, name);
-
-         if (wrap)
-           {
-             strcpy (tmpbuf, "(");
-             strcat (tmpbuf, str);
-             strcat (tmpbuf, ")");
-             strcpy (str, tmpbuf);
-           }
-
-         adorn_decl (decl, str);
-         break;
-
-       case ARRAY_TYPE:
-       case FUNCTION_TYPE:
-       case POINTER_TYPE:
-         strcpy (buf, name);
-         str = buf;
-
-         /* This clause is done iteratively rather than recursively.  
*/
-         do
-           {
-             op = (is_complex_decl (TREE_TYPE (decl))
-                   ? TREE_TYPE (decl) : NULL_TREE);
-
-             adorn_decl (decl, str);
-
-             /* We have a pointer to a function or array...(*)(), 
(*)[] */
-             if (code == POINTER_TYPE
-                 && op && (TREE_CODE (op) == FUNCTION_TYPE
-                           || TREE_CODE (op) == ARRAY_TYPE))
-               {
-                 strcpy (tmpbuf, "(");
-                 strcat (tmpbuf, str);
-                 strcat (tmpbuf, ")");
-                 strcpy (str, tmpbuf);
-               }
-
-             decl = (is_complex_decl (TREE_TYPE (decl))
-                     ? TREE_TYPE (decl) : NULL_TREE);
-           }
-
-         while (decl && (code = TREE_CODE (decl)))
-           ;
-
-         break;
-
-       case IDENTIFIER_NODE:
-         /* Will only happen if we are processing a "raw" expr-decl.  
*/
-         strcpy (buf, IDENTIFIER_POINTER (decl));
-         return buf;
-
-       default:
-         abort ();
-       }
-
-      return str;
-    }
-
-  else
-    /* We have an abstract declarator or a _DECL node.  */
-    {
-      strcpy (buf, name);
-      return buf;
-    }
-}
+  buf[0] = '\0';

-static void
-gen_declspecs (tree declspecs, char *buf, int raw)
-{
-  if (raw)
+  if (DECL_P (decl))
      {
-      tree chain;
+      gen_type_name (TREE_TYPE (decl), buf);

-      for (chain = nreverse (copy_list (declspecs));
-          chain; chain = TREE_CHAIN (chain))
+      if (DECL_NAME (decl))
         {
-         tree aspec = TREE_VALUE (chain);
-
-         if (TREE_CODE (aspec) == IDENTIFIER_NODE)
-           strcat (buf, IDENTIFIER_POINTER (aspec));
-         else if (TREE_CODE (aspec) == RECORD_TYPE)
-           {
-             if (OBJC_TYPE_NAME (aspec))
-               {
-                 tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
-
-                 if (! TREE_STATIC_TEMPLATE (aspec))
-                   strcat (buf, "struct ");
-                 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(aspec)));
-
-                 /* NEW!!! */
-                 if (protocol_list)
-                   {
-                     tree chain = protocol_list;
-
-                     strcat (buf, " <");
-                     while (chain)
-                       {
-                         strcat (buf,
-                                 IDENTIFIER_POINTER
-                                 (PROTOCOL_NAME (TREE_VALUE (chain))));
-                         chain = TREE_CHAIN (chain);
-                         if (chain)
-                           strcat (buf, ", ");
-                       }
-                     strcat (buf, ">");
-                   }
-               }
-
-             else
-               strcat (buf, "untagged struct");
-           }
-
-         else if (TREE_CODE (aspec) == UNION_TYPE)
-           {
-             if (OBJC_TYPE_NAME (aspec))
-               {
-                 if (! TREE_STATIC_TEMPLATE (aspec))
-                   strcat (buf, "union ");
-                 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(aspec)));
-               }
-             else
-               strcat (buf, "untagged union");
-           }
-
-         else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
-           {
-             if (OBJC_TYPE_NAME (aspec))
-               {
-                 if (! TREE_STATIC_TEMPLATE (aspec))
-                   strcat (buf, "enum ");
-                 strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(aspec)));
-               }
-             else
-               strcat (buf, "untagged enum");
-           }
-
-         else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec))
-           strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec)));
-
-         else if (IS_ID (aspec))
-           {
-             tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
-
-             strcat (buf, "id");
-             if (protocol_list)
-               {
-                 tree chain = protocol_list;
-
-                 strcat (buf, " <");
-                 while (chain)
-                   {
-                     strcat (buf,
-                             IDENTIFIER_POINTER
-                             (PROTOCOL_NAME (TREE_VALUE (chain))));
-                     chain = TREE_CHAIN (chain);
-                     if (chain)
-                       strcat (buf, ", ");
-                   }
-                 strcat (buf, ">");
-               }
-           }
-         if (TREE_CHAIN (chain))
+         if (!POINTER_TYPE_P (TREE_TYPE (decl)))
             strcat (buf, " ");
-       }
-    }
-  else
-    {
-      /* Type qualifiers.  */
-      if (TYPE_READONLY (declspecs))
-       strcat (buf, "const ");
-      if (TYPE_VOLATILE (declspecs))
-       strcat (buf, "volatile ");
-
-      switch (TREE_CODE (declspecs))
-       {
-         /* Type specifiers.  */
-
-       case INTEGER_TYPE:
-         declspecs = TYPE_MAIN_VARIANT (declspecs);
-
-         /* Signed integer types.  */
-
-         if (declspecs == short_integer_type_node)
-           strcat (buf, "short int ");
-         else if (declspecs == integer_type_node)
-           strcat (buf, "int ");
-         else if (declspecs == long_integer_type_node)
-           strcat (buf, "long int ");
-         else if (declspecs == long_long_integer_type_node)
-           strcat (buf, "long long int ");
-         else if (declspecs == signed_char_type_node
-                  || declspecs == char_type_node)
-           strcat (buf, "char ");

-         /* Unsigned integer types.  */
-
-         else if (declspecs == short_unsigned_type_node)
-           strcat (buf, "unsigned short ");
-         else if (declspecs == unsigned_type_node)
-           strcat (buf, "unsigned int ");
-         else if (declspecs == long_unsigned_type_node)
-           strcat (buf, "unsigned long ");
-         else if (declspecs == long_long_unsigned_type_node)
-           strcat (buf, "unsigned long long ");
-         else if (declspecs == unsigned_char_type_node)
-           strcat (buf, "unsigned char ");
-         break;
-
-       case REAL_TYPE:
-         declspecs = TYPE_MAIN_VARIANT (declspecs);
-
-         if (declspecs == float_type_node)
-           strcat (buf, "float ");
-         else if (declspecs == double_type_node)
-           strcat (buf, "double ");
-         else if (declspecs == long_double_type_node)
-           strcat (buf, "long double ");
-         break;
-
-       case RECORD_TYPE:
-         if (OBJC_TYPE_NAME (declspecs)
-             && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == 
IDENTIFIER_NODE)
-           {
-             tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
-
-             if (! TREE_STATIC_TEMPLATE (declspecs))
-               strcat (buf, "struct ");
-             strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(declspecs)));
-
-             if (protocol_list)
-               {
-                 tree chain = protocol_list;
-
-                 strcat (buf, " <");
-                 while (chain)
-                   {
-                     strcat (buf,
-                             IDENTIFIER_POINTER
-                             (PROTOCOL_NAME (TREE_VALUE (chain))));
-                     chain = TREE_CHAIN (chain);
-                     if (chain)
-                       strcat (buf, ", ");
-                   }
-                 strcat (buf, ">");
-               }
-           }
-
-         else
-           strcat (buf, "untagged struct");
-
-         strcat (buf, " ");
-         break;
-
-       case UNION_TYPE:
-         if (OBJC_TYPE_NAME (declspecs)
-             && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == 
IDENTIFIER_NODE)
-           {
-             strcat (buf, "union ");
-             strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(declspecs)));
-             strcat (buf, " ");
-           }
-
-         else
-           strcat (buf, "untagged union ");
-         break;
-
-       case ENUMERAL_TYPE:
-         if (OBJC_TYPE_NAME (declspecs)
-             && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == 
IDENTIFIER_NODE)
-           {
-             strcat (buf, "enum ");
-             strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME 
(declspecs)));
-             strcat (buf, " ");
-           }
-
-         else
-           strcat (buf, "untagged enum ");
-         break;
-
-       case VOID_TYPE:
-         strcat (buf, "void ");
-         break;
-
-       case POINTER_TYPE:
-         {
-           tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
-
-           strcat (buf, "id");
-           if (protocol_list)
-             {
-               tree chain = protocol_list;
-
-               strcat (buf, " <");
-               while (chain)
-                 {
-                   strcat (buf,
-                           IDENTIFIER_POINTER
-                           (PROTOCOL_NAME (TREE_VALUE (chain))));
-                   chain = TREE_CHAIN (chain);
-                   if (chain)
-                     strcat (buf, ", ");
-                 }
-
-               strcat (buf, ">");
-             }
-         }
-         break;
-
-       default:
-         break;
+         strcat (buf, IDENTIFIER_POINTER (DECL_NAME (decl)));
         }
+
+      if (DECL_INITIAL (decl)
+         && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
+       sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_DEC,
+                TREE_INT_CST_LOW (DECL_INITIAL (decl)));
      }
+
+  return buf;
  }

-/* Given a tree node, produce a printable description of it in the 
given
+/* Given a tree TYPE node, produce a printable description of it in 
the given
     buffer, overwriting the buffer.  */

  static char *
-gen_declaration (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 (tree atype_or_adecl, char *buf)
+gen_type_name (tree type, char *buf)
  {
-  char declbuf[256];
+  tree orig = type, proto;

-  if (TREE_CODE (atype_or_adecl) == TREE_LIST)
+  if (TYPE_P (type) && TYPE_NAME (type))
+    type = TYPE_NAME (type);
+  else if (POINTER_TYPE_P (type))
      {
-      tree declspecs;  /* "identifier_node", "record_type" */
-      tree declarator; /* "array_ref", "indirect_ref", "call_expr"...  
*/
-      tree width = NULL_TREE;  /* for bitfields */
-
-      /* We have a "raw", abstract declarator (typename).  */
-      declarator = TREE_VALUE (atype_or_adecl);
-      /* In the case of raw ivars, the declarator itself is a list,
-        and contains bitfield widths.  */
-      if (declarator && TREE_CODE (declarator) == TREE_LIST)
-       {
-         width = TREE_VALUE (declarator);
-         declarator = TREE_PURPOSE (declarator);
-       }
-      declspecs  = TREE_PURPOSE (atype_or_adecl);
+      gen_type_name (TREE_TYPE (type), buf);
+
+      if (!POINTER_TYPE_P (TREE_TYPE (type)))
+       strcat (buf, " ");

-      gen_declspecs (declspecs, buf, 1);
-      if (declarator)
-       {
-         strcat (buf, " ");
-         strcat (buf, gen_declarator (declarator, declbuf, ""));
-       }
-      if (width)
-       sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
-                TREE_INT_CST_LOW (width));
+      strcat (buf, "*");
+      goto exit_function;
      }

-  else
-    {
-      tree atype;
-      tree declspecs;  /* "integer_type", "real_type", 
"record_type"...  */
-      tree declarator; /* "array_type", "function_type", 
"pointer_type".  */
-
-      if (TREE_CODE (atype_or_adecl) == FIELD_DECL
-         || TREE_CODE (atype_or_adecl) == PARM_DECL
-         || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
-       atype = TREE_TYPE (atype_or_adecl);
-      else
-       /* Assume we have a *_type node.  */
-       atype = atype_or_adecl;
+  if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
+    type = DECL_NAME (type);

-      if (is_complex_decl (atype))
-       {
-         tree chain;
-
-         /* Get the declaration specifier; it is at the end of the 
list.  */
-         declarator = chain = atype;
-         do
-           chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */
-         while (is_complex_decl (chain));
-         declspecs = chain;
-       }
+  strcat (buf, IDENTIFIER_POINTER (type));
+  proto = TYPE_PROTOCOL_LIST (orig);

-      else
-       {
-         declspecs = atype;
-         declarator = NULL_TREE;
-       }
-
-      gen_declspecs (declspecs, buf, 0);
-
-      if (TREE_CODE (atype_or_adecl) == FIELD_DECL
-         || TREE_CODE (atype_or_adecl) == PARM_DECL
-         || TREE_CODE (atype_or_adecl) == FUNCTION_DECL)
-       {
-         const char *const decl_name =
-           (DECL_NAME (atype_or_adecl)
-            ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) : "");
-
-         if (declarator)
-           {
-             strcat (buf, " ");
-             strcat (buf, gen_declarator (declarator, declbuf, 
decl_name));
-           }
+  if (proto)
+    {
+      strcat (buf, " <");

-         else if (decl_name[0])
-           {
-             strcat (buf, " ");
-             strcat (buf, decl_name);
-           }
-       }
-      else if (declarator)
-       {
-         strcat (buf, " ");
-         strcat (buf, gen_declarator (declarator, declbuf, ""));
-       }
+      while (proto) {
+       strcat (buf,
+               IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE 
(proto))));
+       proto = TREE_CHAIN (proto);
+       strcat (buf, proto ? ", " : ">");
+      }
      }
-}

-#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE 
(meth))))
+ exit_function:
+  return buf;
+}

  /* Given a method tree, put a printable description into the given
     buffer (overwriting) and return a pointer to the buffer.  */
@@ -8588,13 +7905,9 @@ gen_method_decl (tree method, char *buf)
  {
    tree chain;

-  buf[0] = '\0';
-  if (RAW_TYPESPEC (method) != objc_object_reference)
-    {
-      strcat (buf, "(");
-      gen_declaration_1 (TREE_TYPE (method), buf);
-      strcat (buf, ")");
-    }
+  strcpy (buf, "(");  /* NB: Do _not_ call strcat() here.  */
+  gen_type_name (TREE_VALUE (TREE_TYPE (method)), buf);
+  strcat (buf, ")");

    chain = METHOD_SEL_ARGS (method);
    if (chain)
@@ -8605,13 +7918,9 @@ gen_method_decl (tree method, char *buf)
           if (KEYWORD_KEY_NAME (chain))
             strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));

-         strcat (buf, ":");
-         if (RAW_TYPESPEC (chain) != objc_object_reference)
-           {
-             strcat (buf, "(");
-             gen_declaration_1 (TREE_TYPE (chain), buf);
-             strcat (buf, ")");
-           }
+         strcat (buf, ":(");
+         gen_type_name (TREE_VALUE (TREE_TYPE (chain)), buf);
+         strcat (buf, ")");

           strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
           if ((chain = TREE_CHAIN (chain)))
@@ -8619,20 +7928,20 @@ gen_method_decl (tree method, char *buf)
          }
        while (chain);

-      if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
-        strcat (buf, ", ...");
-      else if (METHOD_ADD_ARGS (method))
-        {
-         /* We have a tree list node as generate by get_parm_info.  */
-         chain  = TREE_PURPOSE (METHOD_ADD_ARGS (method));
+      if (METHOD_ADD_ARGS (method))
+       {
+         chain = TREE_CHAIN (METHOD_ADD_ARGS (method));

-          /* Know we have a chain of parm_decls.  */
-          while (chain)
-            {
+         /* Know we have a chain of parm_decls.  */
+         while (chain)
+           {
               strcat (buf, ", ");
-             gen_declaration_1 (chain, buf);
+             gen_type_name (TREE_TYPE (TREE_VALUE (chain)), buf);
               chain = TREE_CHAIN (chain);
-            }
+           }
+
+         if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
+           strcat (buf, ", ...");
         }
      }

@@ -8855,13 +8164,14 @@ finish_objc (void)
    if (flag_replace_objc_classes && imp_list)
      generate_objc_image_info ();

+  /* Arrange for ObjC data structures to be initialized at run time.  
*/
    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.  */
-      rtx init_sym = build_module_descriptor ();
-      if (init_sym && targetm.have_ctors_dtors)
-       (* targetm.asm_out.constructor) (init_sym, 
DEFAULT_INIT_PRIORITY);
+      build_module_descriptor ();
+
+      if (!flag_next_runtime)
+       build_module_initializer_routine ();
      }

    /* Dump the class references.  This forces the appropriate classes
@@ -8908,26 +8218,17 @@ finish_objc (void)
  static void
  generate_classref_translation_entry (tree chain)
  {
-  tree expr, name, decl_specs, decl, sc_spec;
-  tree type;
+  tree expr, decl, type;

-  type = TREE_TYPE (TREE_PURPOSE (chain));
+  decl = TREE_PURPOSE (chain);
+  type = TREE_TYPE (decl);

    expr = add_objc_string (TREE_VALUE (chain), class_names);
-  expr = build_c_cast (type, expr); /* cast! */
+  expr = convert (type, expr); /* cast! */

-  name = DECL_NAME (TREE_PURPOSE (chain));
-
-  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
-
-  /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
-  decl_specs = tree_cons (NULL_TREE, type, sc_spec);
-
-  /* The decl that is returned from start_decl is the one that we
+  /* The decl that is the one that we
       forward declared in build_class_reference.  */
-  decl = start_decl (name, decl_specs, 1, NULL_TREE);
-  DECL_CONTEXT (decl) = NULL_TREE;
-  finish_decl (decl, expr, NULL_TREE);
+  finish_var_decl (decl, expr);
    return;
  }

@@ -9042,32 +8343,24 @@ handle_impent (struct imp_entry *impent)
  static void
  generate_objc_image_info (void)
  {
-  tree sc_spec, decl, initlist;
+  tree decl, initlist;

-  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
-  decl
-   = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
-                tree_cons (NULL_TREE,
-                           build_array_type
-                           (integer_type_node,
-                            build_index_type (build_int_cst 
(NULL_TREE, 1, 0))),
-                           sc_spec),
-                1,
-                NULL_TREE);
+  decl = start_var_decl (build_array_type
+                        (integer_type_node,
+                         build_index_type (build_int_cst (NULL_TREE, 
1, 0))),
+                        "_OBJC_IMAGE_INFO");

    initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0, 
0));
    initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1, 0), 
initlist);
-  initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+  initlist = objc_build_constructor (TREE_TYPE (decl), nreverse 
(initlist));

-  TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 
1;
-  TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
-  finish_decl (decl, initlist, NULL_TREE);
+  finish_var_decl (decl, initlist);
  }

  /* Look up ID as an instance variable.  */

  tree
-lookup_objc_ivar (tree id)
+objc_lookup_ivar (tree id)
  {
    tree decl;

Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.27
diff -u -3 -p -r1.27 objc-act.h
--- gcc/objc/objc-act.h 15 Aug 2004 21:47:32 -0000      1.27
+++ gcc/objc/objc-act.h 16 Aug 2004 04:35:42 -0000
@@ -28,61 +28,12 @@ bool objc_init (void);
  const char *objc_printable_name (tree, int);
  void objc_finish_file (void);

-/* used by yyparse */
-
-tree start_class (enum tree_code, tree, tree, tree);
-tree continue_class (tree);
-void finish_class (tree);
-void start_method_def (tree);
-void continue_method_def (void);
-void finish_method_def (void);
-tree start_protocol (enum tree_code, tree, tree);
-void finish_protocol (tree);
-
-tree objc_build_throw_stmt (tree);
-void objc_begin_try_stmt (location_t, tree);
-void objc_begin_catch_clause (tree);
-void objc_finish_catch_clause (void);
-void objc_build_finally_clause (location_t, tree);
-void objc_finish_try_stmt (void);
-void objc_build_synchronized (location_t, tree, tree);
-
-tree is_ivar (tree, tree);
-int is_private (tree);
-int objc_is_public (tree, tree);
-tree add_instance_variable (tree, int, tree, tree, tree);
-tree objc_add_method (tree, tree, int);
-tree get_super_receiver (void);
-void objc_clear_super_receiver (void);
-tree get_class_ivars_from_name (tree);
-tree get_class_reference (tree);
-tree get_static_reference (tree, tree);
-tree get_protocol_reference (tree);
-tree build_message_expr (tree);
-tree finish_message_expr (tree, tree, tree);
-tree build_selector_expr (tree);
-tree build_ivar_reference (tree);
-tree build_keyword_decl (tree, tree, tree);
-tree build_method_decl (enum tree_code, tree, tree, tree);
-tree build_protocol_expr (tree);
-tree build_objc_string_object (tree);
-
-void objc_declare_alias (tree, tree);
-void objc_declare_class (tree);
-void objc_declare_protocols (tree);
-
-/* the following routines are used to implement statically typed 
objects */
-
-int objc_comptypes (tree, tree, int);
-void objc_check_decl (tree);
-
-/* NeXT extensions */
-
-tree build_encode_expr (tree);
+/* NB: The remaining public functions are prototyped in c-common.h, 
for the
+   benefit of stub-objc.c and objc-act.c.  */

  /* Objective-C structures */

-#define CLASS_LANG_SLOT_ELTS           6
+#define CLASS_LANG_SLOT_ELTS           5
  #define PROTOCOL_LANG_SLOT_ELTS                2

  /* KEYWORD_DECL */
@@ -108,13 +59,13 @@ tree build_encode_expr (tree);
  #define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 
(CLASS), 2)
  #define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 
(CLASS), 3)
  #define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 
(CLASS), 4)
-#define CLASS_OWN_IVARS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 
5)
  #define PROTOCOL_NAME(CLASS) ((CLASS)->type.name)
  #define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 0)
  #define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
  #define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
  #define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 
(CLASS), 1)
  #define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
+
  /* We need to distinguish TYPE_PROTOCOL_LISTs from TYPE_CONTEXTs, both 
of which
     are stored in the same accessor slot.  */
  #define TYPE_PROTOCOL_LIST(TYPE)                               \
@@ -123,12 +74,11 @@ tree build_encode_expr (tree);
          ? (TYPE)->type.context : NULL_TREE)
  #define SET_TYPE_PROTOCOL_LIST(TYPE, P) (TYPE_CHECK 
(TYPE)->type.context = (P))

-/* Set by `continue_class' and checked by `objc_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))
  #define OBJC_TYPE_NAME(type) TYPE_NAME(type)
+#define OBJC_SET_TYPE_NAME(type, name) (TYPE_NAME (type) = name)

  /* Define the Objective-C or Objective-C++ language-specific tree 
codes.  */

@@ -182,8 +132,11 @@ struct imp_entry GTY(())
  };

  extern GTY(()) struct imp_entry *imp_list;
-extern int imp_count;  /* `@implementation' */
-extern int cat_count;  /* `@category' */
+extern GTY(()) int imp_count;  /* `@implementation' */
+extern GTY(()) int cat_count;  /* `@category' */
+
+extern GTY(()) enum tree_code objc_inherit_code;
+extern GTY(()) int objc_public_flag;

  /* Objective-C/Objective-C++ global tree enumeration.  */

@@ -194,7 +147,6 @@ enum objc_tree_index
      OCTI_SELF_ID,
      OCTI_UCMD_ID,
      OCTI_UNUSED_LIST,
-    OCTI_ELLIPSIS_NODE,

      OCTI_SELF_DECL,
      OCTI_UMSG_DECL,
@@ -231,6 +183,7 @@ enum objc_tree_index
      OCTI_MCLS_DECL,
      OCTI_SEL_TABLE_DECL,
      OCTI_MODULES_DECL,
+    OCTI_GNU_INIT_DECL,

      OCTI_INTF_CTX,
      OCTI_IMPL_CTX,
@@ -251,13 +204,15 @@ enum objc_tree_index
      OCTI_MODULE_TEMPL,
      OCTI_SUPER_TEMPL,
      OCTI_OBJ_REF,
+    OCTI_CLS_REF,
      OCTI_METH_PROTO_TEMPL,
      OCTI_FUNCTION1_TEMPL,
      OCTI_FUNCTION2_TEMPL,

      OCTI_OBJ_ID,
      OCTI_CLS_ID,
-    OCTI_ID_ID,
+    OCTI_ID_NAME,
+    OCTI_CLASS_NAME,
      OCTI_CNST_STR_ID,
      OCTI_CNST_STR_TYPE,
      OCTI_CNST_STR_GLOB_ID,
@@ -280,6 +235,7 @@ enum objc_tree_index
      OCTI_RETHROW_EXCEPTION_DECL,
      OCTI_EVAL_ONCE_DECL,
      OCTI_CATCH_TYPE,
+    OCTI_EXECCLASS_DECL,

      OCTI_MAX
  };
@@ -297,7 +253,6 @@ extern GTY(()) tree objc_global_trees[OC
  #define self_id                        objc_global_trees[OCTI_SELF_ID]
  #define ucmd_id                        objc_global_trees[OCTI_UCMD_ID]
  #define unused_list            objc_global_trees[OCTI_UNUSED_LIST]
-#define objc_ellipsis_node     objc_global_trees[OCTI_ELLIPSIS_NODE]

  #define self_decl              objc_global_trees[OCTI_SELF_DECL]
  #define umsg_decl              objc_global_trees[OCTI_UMSG_DECL]
@@ -309,8 +264,8 @@ extern GTY(()) tree objc_global_trees[OC
                                 objc_global_trees[OCTI_GET_MCLASS_DECL]

  #define objc_super_type                
objc_global_trees[OCTI_SUPER_TYPE]
-#define objc_selector_type     objc_global_trees[OCTI_SEL_TYPE]
-#define objc_id_type           objc_global_trees[OCTI_ID_TYPE]
+#define objc_selector_type             objc_global_trees[OCTI_SEL_TYPE]
+#define objc_object_type       objc_global_trees[OCTI_ID_TYPE]
  #define objc_class_type                objc_global_trees[OCTI_CLS_TYPE]
  #define objc_instance_type     objc_global_trees[OCTI_NST_TYPE]
  #define objc_protocol_type     objc_global_trees[OCTI_PROTO_TYPE]
@@ -318,11 +273,13 @@ extern GTY(()) tree objc_global_trees[OC
  /* Type checking macros.  */

  #define IS_ID(TYPE) \
-  (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (objc_id_type))
+  (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE 
(objc_object_type))
+#define IS_CLASS(TYPE) \
+  (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE 
(objc_class_type))
  #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
    (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
  #define IS_SUPER(TYPE) \
-  (TREE_CODE (TYPE) == POINTER_TYPE && TREE_TYPE (TYPE) == 
objc_super_template)
+  (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == objc_super_template)

  #define class_chain            objc_global_trees[OCTI_CLS_CHAIN]
  #define alias_chain            objc_global_trees[OCTI_ALIAS_CHAIN]
@@ -355,6 +312,7 @@ extern GTY(()) tree objc_global_trees[OC
  #define UOBJC_METACLASS_decl           
objc_global_trees[OCTI_MCLS_DECL]
  #define UOBJC_SELECTOR_TABLE_decl      
objc_global_trees[OCTI_SEL_TABLE_DECL]
  #define UOBJC_MODULES_decl             
objc_global_trees[OCTI_MODULES_DECL]
+#define GNU_INIT_decl                  
objc_global_trees[OCTI_GNU_INIT_DECL]

  /* The following are used when compiling a class implementation.
     implementation_template will normally be an interface, however if
@@ -400,12 +358,15 @@ extern GTY(()) tree objc_global_trees[OC
  #define objc_eval_once         objc_global_trees[OCTI_EVAL_ONCE_DECL]
  #define objc_catch_type                
objc_global_trees[OCTI_CATCH_TYPE]

+#define execclass_decl         objc_global_trees[OCTI_EXECCLASS_DECL]
+
  #define objc_method_template   objc_global_trees[OCTI_METH_TEMPL]
  #define objc_ivar_template     objc_global_trees[OCTI_IVAR_TEMPL]
  #define objc_symtab_template   objc_global_trees[OCTI_SYMTAB_TEMPL]
  #define objc_module_template   objc_global_trees[OCTI_MODULE_TEMPL]
  #define objc_super_template    objc_global_trees[OCTI_SUPER_TEMPL]
  #define objc_object_reference  objc_global_trees[OCTI_OBJ_REF]
+#define objc_class_reference   objc_global_trees[OCTI_CLS_REF]
  #define objc_method_prototype_template         \
                                 objc_global_trees[OCTI_METH_PROTO_TEMPL]
  #define function1_template     objc_global_trees[OCTI_FUNCTION1_TEMPL]
@@ -413,7 +374,8 @@ extern GTY(()) tree objc_global_trees[OC

  #define objc_object_id         objc_global_trees[OCTI_OBJ_ID]
  #define objc_class_id          objc_global_trees[OCTI_CLS_ID]
-#define objc_id_id             objc_global_trees[OCTI_ID_ID]
+#define objc_object_name               objc_global_trees[OCTI_ID_NAME]
+#define objc_class_name                
objc_global_trees[OCTI_CLASS_NAME]
  #define constant_string_id     objc_global_trees[OCTI_CNST_STR_ID]
  #define constant_string_type   objc_global_trees[OCTI_CNST_STR_TYPE]
  #define constant_string_global_id              \
Index: gcc/testsuite/objc/execute/next_mapping.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc/execute/next_mapping.h,v
retrieving revision 1.3
diff -u -3 -p -r1.3 next_mapping.h
--- gcc/testsuite/objc/execute/next_mapping.h   7 Jun 2004 08:48:31 
-0000       1.3
+++ gcc/testsuite/objc/execute/next_mapping.h   16 Aug 2004 04:35:57 
-0000
@@ -1,6 +1,7 @@
  /* This file "renames" various ObjC GNU runtime entry points
     (and fakes the existence of several others)
     if the NeXT runtime is being used.  */
+
  /* Authors: Ziemowit Laski <zlaski@apple.com>  */
  /*         David Ayers <d.ayers@inode.at>  */

@@ -8,6 +9,8 @@
  #include <objc/objc-class.h>
  #include <objc/Object.h>
  #include <ctype.h>
+#include <stdlib.h>
+#include <string.h>

  #define objc_get_class(C)                      objc_getClass(C)
  #define objc_get_meta_class(C)                 objc_getMetaClass(C)
@@ -45,22 +48,15 @@
  /* The following is necessary to "cover" the bf*.m test cases on NeXT. 
  */

  #undef  MAX
-#define MAX(X, Y)                    \
-  ({ typeof (X) __x = (X), __y = (Y); \
-     (__x > __y ? __x : __y); })
-
+#define MAX(X, Y) ((X > Y) ? X : Y)
  #undef  MIN
-#define MIN(X, Y)                    \
-  ({ typeof (X) __x = (X), __y = (Y); \
-     (__x < __y ? __x : __y); })
-
+#define MIN(X, Y) ((X < Y) ? X : Y)
  #undef  ROUND
-#define ROUND(V, A) \
-  ({ typeof (V) __v = (V); typeof (A) __a = (A); \
-     __a * ((__v+__a - 1)/__a); })
+#define ROUND(V, A) (A * ((V + A - 1) / A))

  #define BITS_PER_UNIT __CHAR_BIT__
-#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char 
a;}))
+typedef struct{char a; } __small_struct;
+#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof 
(__small_struct))

  /* Not sure why the following are missing from NeXT objc headers... */

@@ -104,7 +100,7 @@ struct objc_struct_layout
    unsigned int record_align;
  };

-typedef union {
+typedef union arglist {
    char *arg_ptr;
    char arg_regs[sizeof (char*)];
  } *arglist_t;                   /* argument frame */
@@ -117,6 +113,7 @@ void objc_layout_structure (const char *
  BOOL objc_layout_structure_next_member (struct objc_struct_layout 
*layout);
  void objc_layout_finish_structure (struct objc_struct_layout *layout,
      unsigned int *size, unsigned int *align);
+int objc_aligned_size (const char *type);

  /*
    return the size of an object specified by type
@@ -135,73 +132,53 @@ objc_sizeof_type (const char *type)
    switch (*type) {
    case _C_ID:
      return sizeof (id);
-    break;

    case _C_CLASS:
      return sizeof (Class);
-    break;

    case _C_SEL:
      return sizeof (SEL);
-    break;

    case _C_CHR:
      return sizeof (char);
-    break;

    case _C_UCHR:
      return sizeof (unsigned char);
-    break;

    case _C_SHT:
      return sizeof (short);
-    break;

    case _C_USHT:
      return sizeof (unsigned short);
-    break;

    case _C_INT:
      return sizeof (int);
-    break;

    case _C_UINT:
      return sizeof (unsigned int);
-    break;

    case _C_LNG:
      return sizeof (long);
-    break;

    case _C_ULNG:
      return sizeof (unsigned long);
-    break;

    case _C_LNG_LNG:
      return sizeof (long long);
-    break;

    case _C_ULNG_LNG:
      return sizeof (unsigned long long);
-    break;

    case _C_FLT:
      return sizeof (float);
-    break;

    case _C_DBL:
      return sizeof (double);
-    break;
-
-  case _C_VOID:
-    return sizeof (void);
-    break;

    case _C_PTR:
    case _C_ATOM:
    case _C_CHARPTR:
      return sizeof (char *);
-    break;

    case _C_ARY_B:
      {
@@ -210,7 +187,6 @@ objc_sizeof_type (const char *type)
         ;
        return len * objc_aligned_size (type);
      }
-    break;

    case _C_BFLD:
      {
@@ -252,6 +228,7 @@ objc_sizeof_type (const char *type)
        return max_size;
      }
    }
+
    return 0; /* error */
  }

@@ -269,63 +246,50 @@ objc_alignof_type (const char *type)
        for (type++; *type++ != '"';)
         /* do nothing */;
      }
+
    switch (*type) {
    case _C_ID:
      return __alignof__ (id);
-    break;

    case _C_CLASS:
      return __alignof__ (Class);
-    break;

    case _C_SEL:
      return __alignof__ (SEL);
-    break;

    case _C_CHR:
      return __alignof__ (char);
-    break;

    case _C_UCHR:
      return __alignof__ (unsigned char);
-    break;

    case _C_SHT:
      return __alignof__ (short);
-    break;

    case _C_USHT:
      return __alignof__ (unsigned short);
-    break;

    case _C_INT:
    case _C_BFLD: /* This is for the NeXT only */
      return __alignof__ (int);
-    break;

    case _C_UINT:
      return __alignof__ (unsigned int);
-    break;

    case _C_LNG:
      return __alignof__ (long);
-    break;

    case _C_ULNG:
      return __alignof__ (unsigned long);
-    break;

    case _C_LNG_LNG:
      return __alignof__ (long long);
-    break;

    case _C_ULNG_LNG:
      return __alignof__ (unsigned long long);
-    break;

    case _C_FLT:
      return __alignof__ (float);
-    break;

    case _C_DBL:
      return __alignof__ (double);
@@ -374,6 +338,7 @@ objc_alignof_type (const char *type)
        return maxalign;
      }
    }
+
    return 0; /* error */
  }

@@ -497,7 +462,6 @@ objc_skip_typespec (const char *type)
    case _C_VOID:
    case _C_UNDEF:
      return ++type;
-    break;

    case _C_ARY_B:
      /* skip digits, typespec and closing ']' */
@@ -543,6 +507,7 @@ objc_skip_typespec (const char *type)

      return objc_skip_typespec (++type);
    }
+
    return 0; /* error */
  }

Index: gcc/testsuite/objc.dg/bitfield-2.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/bitfield-2.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 bitfield-2.m
--- gcc/testsuite/objc.dg/bitfield-2.m  25 Sep 2003 01:26:00 -0000      
1.3
+++ gcc/testsuite/objc.dg/bitfield-2.m  16 Aug 2004 04:35:57 -0000
@@ -4,7 +4,7 @@
  /* { dg-options "-fnext-runtime -fsigned-char" } */
  /* { dg-do run { target *-*-darwin* } } */

-struct objc_object { struct objc_class *class_pointer; } *id;
+typedef struct objc_object { struct objc_class *class_pointer; } *id;

  extern void abort(void);
  extern int strcmp(const char *, const char *);
Index: gcc/testsuite/objc.dg/bitfield-4.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/bitfield-4.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 bitfield-4.m
--- gcc/testsuite/objc.dg/bitfield-4.m  25 Sep 2003 01:26:00 -0000      
1.2
+++ gcc/testsuite/objc.dg/bitfield-4.m  16 Aug 2004 04:35:57 -0000
@@ -19,11 +19,10 @@
  @implementation WithBitfields {
    char *isa;  /* { dg-error "conflicting instance variable type .char 
\\*isa." } */
    /* { dg-error "previous declaration of .void \\*isa." "" { target 
*-*-* } 12 } */
-  unsigned a: 5;  /* { dg-error "conflicting instance variable type 
.unsigned a: 5." } */
-  /* { dg-error "previous declaration of .unsigned a: 3." "" { target 
*-*-* } 13 } */
+  unsigned a: 5;  /* { dg-error "conflicting instance variable type 
.unsigned( int)? a: 5." } */
+  /* { dg-error "previous declaration of .unsigned( int)? a: 3." "" { 
target *-*-* } 13 } */
    signed b: 4;  /* This one is fine. */
    int c: 3;  /* { dg-error "conflicting instance variable type .int c: 
3." } */
    /* { dg-error "previous declaration of .int c: 5." "" { target *-*-* 
} 15 } */
  }
  @end
-
Index: gcc/testsuite/objc.dg/const-str-3.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/const-str-3.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 const-str-3.m
--- gcc/testsuite/objc.dg/const-str-3.m 25 Sep 2003 01:26:00 -0000      
1.2
+++ gcc/testsuite/objc.dg/const-str-3.m 16 Aug 2004 04:35:57 -0000
@@ -6,6 +6,8 @@
  /* { dg-do run { target *-*-darwin* } } */

  #include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
  #include <objc/objc.h>
  #include <objc/Object.h>

Index: gcc/testsuite/objc.dg/id-1.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/id-1.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 id-1.m
--- gcc/testsuite/objc.dg/id-1.m        2 Dec 2001 00:04:36 -0000       
1.2
+++ gcc/testsuite/objc.dg/id-1.m        16 Aug 2004 04:35:57 -0000
@@ -1,6 +1,7 @@
-/* Test the id type warning.  */
+/* Test attempt to redefine 'id' in an incompatible fashion.  */
  /* { dg-do compile } */

-typedef int id;
+typedef int id;  /* { dg-error "conflicting types for .id." } */
+/* { dg-error "previous declaration of .id. was here" "" { target 
*-*-* } 0 } */

-id b; /* { dg-warning "nexpected type for `id'" } */
+id b;
Index: gcc/testsuite/objc.dg/method-6.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/method-6.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 method-6.m
--- gcc/testsuite/objc.dg/method-6.m    3 Oct 2003 22:24:03 -0000       
1.3
+++ gcc/testsuite/objc.dg/method-6.m    16 Aug 2004 04:35:57 -0000
@@ -19,7 +19,7 @@ void foo(void) {
    Class receiver;

    [receiver port];  /* { dg-warning "multiple methods named .\\+port. 
found" } */
-       /* { dg-warning "using .\\-\\(unsigned\\)port." "" { target 
*-*-* } 9 } */
+       /* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" { 
target *-*-* } 9 } */
         /* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" { 
target *-*-* } 14 } */

    [receiver starboard];  /* { dg-warning ".Class. may not respond to 
.\\+starboard." } */
Index: gcc/testsuite/objc.dg/proto-qual-1.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/proto-qual-1.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 proto-qual-1.m
--- gcc/testsuite/objc.dg/proto-qual-1.m        29 Jan 2004 03:14:35 
-0000      1.3
+++ gcc/testsuite/objc.dg/proto-qual-1.m        16 Aug 2004 04:35:57 
-0000
@@ -43,10 +43,10 @@ static void scan_initial(const char *pat

  int main(void) {
    meth = [proto descriptionForInstanceMethod: 
@selector(address:with:)];
-  scan_initial("O@%u@%u:%uNR@%uo^^S%u");
+  scan_initial("O@%u@%u:%uRN@%uo^^S%u");
    CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + 
aligned_sizeof(unsigned));
    meth = [proto descriptionForClassMethod: 
@selector(retainArgument:with:)];
-  scan_initial("Vv%u@%u:%uOo@%un^*%u");
+  scan_initial("Vv%u@%u:%uoO@%un^*%u");
    CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + 
aligned_sizeof(char **));
    return 0;
  }
Index: gcc/testsuite/objc.dg/type-size-2.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/type-size-2.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 type-size-2.m
--- gcc/testsuite/objc.dg/type-size-2.m 25 Sep 2003 01:26:01 -0000      
1.2
+++ gcc/testsuite/objc.dg/type-size-2.m 16 Aug 2004 04:35:57 -0000
@@ -1,6 +1,6 @@
  /* Make sure that array arguments to methods are given the size of 
pointers.  */
  /* As in the case of ivars, arrays without size (e.g., 'int []') are
-   encoded as pointers as well.  */
+   encoded as pointers.  */
  /* Contributed by Ziemowit Laski <zlaski@apple.com>.  */
  /* { dg-do run } */

Index: gcc/testsuite/objc.dg/va-meth-1.m
===================================================================
RCS file: gcc/testsuite/objc.dg/va-meth-1.m
diff -N gcc/testsuite/objc.dg/va-meth-1.m
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/objc.dg/va-meth-1.m   16 Aug 2004 04:35:57 -0000
@@ -0,0 +1,69 @@
+/* Based on objc/execute/va_method.m, by Nicola Pero */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Test methods with "C-style" trailing arguments, with or without 
ellipsis. */
+
+@interface MathClass: Object
+/* sum positive numbers; -1 ends the list */
++ (int) sum: (int)firstNumber, int secondNumber, ...;
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber;
++ (int) minimum: (int) firstNumber, ...;
+@end
+
+@implementation MathClass
++ (int) sum: (int)firstNumber, int secondNumber, ...
+{
+  va_list ap;
+  int sum = 0, number = 0;
+
+  va_start (ap, secondNumber);
+  number = firstNumber + secondNumber;
+
+  while (number >= 0)
+    {
+      sum += number;
+      number = va_arg (ap, int);
+    }
+
+  va_end (ap);
+
+  return sum;
+}
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber {
+  return firstNumber * secondNumber * thirdNumber;
+}
++ (int) minimum: (int)firstNumber, ...
+{
+  va_list ap;
+  int minimum = 999, number = 0;
+
+  va_start (ap, firstNumber);
+  number = firstNumber;
+
+  while (number >= 0)
+    {
+      minimum = (minimum < number ? minimum: number);
+      number = va_arg (ap, int);
+    }
+
+  va_end (ap);
+
+  return minimum;
+}
+@end
+
+int main (void)
+{
+  if ([MathClass sum: 1, 2, 3, 4, 5, -1] != 15)
+      abort ();
+  if ([MathClass prod: 4, 5, 6] != 120)
+      abort ();
+  if ([MathClass minimum: 17, 9, 133, 84, 35, -1] != 9)
+      abort ();
+
+  return 0;
+}



More information about the Gcc-patches mailing list