Index: gcc/c-common.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.627
diff -r1.627 c-common.c
298,304d297
< /* Nonzero means that we will allow new ObjC exception syntax (@throw,
<    @try, etc.) in source code.  */
< int flag_objc_exceptions = 0;
< 
< /* Nonzero means that we generate NeXT setjmp based exceptions.  */
< int flag_objc_sjlj_exceptions = -1;
< 
Index: gcc/c-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.289
diff -r1.289 c-common.h
890a891
> extern tree objc_rewrite_function_call (tree, tree);
927c928
< extern void objc_finish_try_stmt (void);
---
> extern tree objc_finish_try_stmt (void);
931c932
< extern void objc_build_synchronized (location_t, tree, tree);
---
> extern tree objc_build_synchronized (location_t, tree, tree);
933a935
> extern tree objc_generate_write_barrier (tree, enum tree_code, tree);
Index: gcc/c-decl.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.652
diff -r1.652 c-decl.c
236,247d235
< /* Each C symbol points to three linked lists of c_binding structures.
<    These describe the values of the identifier in the three different
<    namespaces defined by the language.  */
< 
< struct lang_identifier GTY(())
< {
<   struct c_common_identifier common_id;
<   struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */
<   struct c_binding *tag_binding;    /* struct/union/enum tags */
<   struct c_binding *label_binding;  /* labels */
< };
< 
570,575c558,573
< 	  if (TREE_CODE (b->decl) == VAR_DECL
< 	      || TREE_CODE (b->decl) == PARM_DECL)
< 	    {
< 	      C_DECL_REGISTER (b->decl) = 0;
< 	      DECL_REGISTER (b->decl) = 0;
< 	      TREE_THIS_VOLATILE (b->decl) = 1;
---
> 	  tree decl = b->decl;
> 
> 	  /* Do not mess with variables that are 'static' or (already)
> 	     'volatile'.  */
> 	  if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
> 	      && (TREE_CODE (decl) == VAR_DECL
> 		  || TREE_CODE (decl) == PARM_DECL))
> 	    {
> 	      TREE_TYPE (decl)
> 		= build_qualified_type (TREE_TYPE (decl),
> 					(TYPE_QUALS (TREE_TYPE (decl))
> 					 | TYPE_QUAL_VOLATILE));
> 	      TREE_THIS_VOLATILE (decl) = 1;
> 	      TREE_SIDE_EFFECTS (decl) = 1;
> 	      DECL_REGISTER (decl) = 0;
> 	      C_DECL_REGISTER (decl) = 0;
Index: gcc/c-opts.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.143
diff -r1.143 c-opts.c
702,709d701
<     case OPT_fobjc_exceptions:
<       flag_objc_exceptions = value;
<       break;
< 
<     case OPT_fobjc_sjlj_exceptions:
<       flag_objc_sjlj_exceptions = value;
<       break;
< 
Index: gcc/c-tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.202
diff -r1.202 c-tree.h
27a28,40
> /* Each C symbol points to three linked lists of c_binding structures.
>    These describe the values of the identifier in the three different
>    namespaces defined by the language.  */
> 
> struct lang_identifier GTY(())
> {
>   struct c_common_identifier common_id;
>   struct c_binding *symbol_binding; /* vars, funcs, constants, typedefs */
>   struct c_binding *tag_binding;    /* struct/union/enum tags */
>   struct c_binding *label_binding;  /* labels */
>   tree interface_value;             /* ObjC interface, if any */
> };
> 
31c44
<   (sizeof (struct c_common_identifier) + 3 * sizeof (void *))
---
>   (sizeof (struct c_common_identifier) + 4 * sizeof (void *))
Index: gcc/c-typeck.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.439
diff -r1.439 c-typeck.c
2003a2004,2007
>   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
>      expressions, like those used for ObjC messenger dispatches.  */
>   function = objc_rewrite_function_call (function, params);
> 
3452a3457,3464
>   /* Emit ObjC write barrier, if necessary.  */
>   if (c_dialect_objc () && flag_objc_gc)
>     {
>       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
>       if (result)
> 	return result;
>     }
> 
Index: gcc/c.opt
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c.opt,v
retrieving revision 1.42
diff -r1.42 c.opt
122a123,126
> Wassign-intercept
> ObjC ObjC++ Var(warn_assign_intercept)
> Warn whenever an Objective-C assignment is being intercepted by the garbage collector
> 
364a369,372
> Wstrict-selector-match
> ObjC ObjC++ Var(warn_strict_selector_match)
> Warn if type signatures of candidate methods do not match exactly
> 
566a575,586
> ; Generate special '- .cxx_construct' and '- .cxx_destruct' methods
> ; to initialize any non-POD ivars in Objective-C++ classes.
> fobjc-call-cxx-cdtors
> ObjC++ Var(flag_objc_call_cxx_cdtors)
> Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed
> 
> fobjc-direct-dispatch
> ObjC ObjC++ Var(flag_objc_direct_dispatch)
> Allow fast jumps to the message dispatcher
> 
> ; Nonzero means that we will allow new ObjC exception syntax (@throw,
> ; @try, etc.) in source code.
568c588
< ObjC ObjC++
---
> ObjC ObjC++ Var(flag_objc_exceptions)
570a591,595
> fobjc-gc
> ObjC ObjC++ Var(flag_objc_gc)
> Enable garbage collection (GC) in Objective-C/Objective-C++ programs
> 
> ; Nonzero means that we generate NeXT setjmp based exceptions.
572c597
< ObjC ObjC++
---
> ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1)
Index: gcc/dbxout.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/dbxout.c,v
retrieving revision 1.233
diff -r1.233 dbxout.c
973a974,975
>   else if (strcmp (language_string, "GNU Objective-C++") == 0)
>     return N_SO_OBJCPLUS;
Index: gcc/gengtype.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.73
diff -r1.73 gengtype.c
1240a1241,1249
>   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
> 	   && strcmp (basename + 3, "cp-tree.h") == 0)
>     output_name = "gt-cp-tree.h", for_name = "cp/tree.c";
>   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
> 	   && strcmp (basename + 3, "decl.h") == 0)
>     output_name = "gt-cp-decl.h", for_name = "cp/decl.c";
>   else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
> 	   && strcmp (basename + 3, "name-lookup.h") == 0)
>     output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
Index: gcc/langhooks-def.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.98
diff -r1.98 langhooks-def.h
94a95
> #define LANG_HOOKS_FINISH_FILE		lhd_do_nothing
263a265
>   LANG_HOOKS_FINISH_FILE, \
Index: gcc/langhooks.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.106
diff -r1.106 langhooks.h
255a256,258
>   /* Called at the end of the translation unit.  */
>   void (*finish_file) (void);
> 
Index: gcc/stub-objc.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/stub-objc.c,v
retrieving revision 2.10
diff -r2.10 stub-objc.c
73a74,79
> objc_rewrite_function_call (tree function, tree ARG_UNUSED (params))
> {
>   return function;
> }
> 
> tree
260c266
< objc_get_class_ivars (tree ARG_UNUSED (class_name))
---
> objc_get_class_ivars (tree ARG_UNUSED (name))
266c272
< objc_build_throw_stmt (tree ARG_UNUSED (throw_expr))
---
> objc_build_throw_stmt (tree ARG_UNUSED (expr))
271c277
< void
---
> tree
274a281
>   return 0;
298c305
< void
---
> tree
300a308
>   return 0;
301a310,317
> 
> tree
> objc_generate_write_barrier (tree ARG_UNUSED (lhs),
> 			     enum tree_code ARG_UNUSED (modifycode),
> 			     tree ARG_UNUSED (rhs))
> {
>   return 0;
> }  
Index: gcc/config/darwin.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.118
diff -r1.118 darwin.h
536c536,539
< 	   fputs (&xname[1], FILE);					     \
---
> 	   if (xname[1] != '"' && name_needs_quotes (&xname[1]))	     \
> 	     fprintf (FILE, "\"%s\"", &xname[1]);			     \
> 	   else								     \
> 	     fputs (&xname[1], FILE); 					     \
543a547,548
>        else if (xname[0] != '"' && name_needs_quotes (xname))		     \
> 	 fprintf (FILE, "\"%s\"", xname);				     \
Index: gcc/config/rs6000/darwin.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.84
diff -r1.84 darwin.h
409a410,415
> 
> /* This is the reserved direct dispatch address for Objective-C.  */
> #define OFFS_MSGSEND_FAST		0xFFFEFF00
> 
> /* This is the reserved ivar address Objective-C.  */
> #define OFFS_ASSIGNIVAR_FAST		0xFFFEFEC0
Index: gcc/cp/Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.201
diff -r1.201 Make-lang.in
258c258
<   insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H)
---
>   insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H) debug.h
265c265
< cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h \
---
> cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
Index: gcc/cp/cp-objcp-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/cp-objcp-common.h,v
retrieving revision 1.8
diff -r1.8 cp-objcp-common.h
25,34d24
< /* In cp/cp-objcp-common.c.  */
< 
< extern HOST_WIDE_INT cxx_get_alias_set (tree);
< extern bool cxx_warn_unused_global_decl (tree);
< extern tree cp_expr_size (tree);
< extern size_t cp_tree_size (enum tree_code);
< extern bool cp_var_mod_type_p (tree, tree);
< extern void cxx_initialize_diagnostics (struct diagnostic_context *);
< extern int cxx_types_compatible_p (tree, tree);
< 
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1135
diff -r1.1135 cp-tree.h
197a198
>   tree interface_value; /* ObjC interface, if any */
4066a4068
> extern tree do_poplevel				(tree);
4332a4335,4344
> /* In cp/cp-objcp-common.c.  */
> 
> extern HOST_WIDE_INT cxx_get_alias_set (tree);
> extern bool cxx_warn_unused_global_decl (tree);
> extern tree cp_expr_size (tree);
> extern size_t cp_tree_size (enum tree_code);
> extern bool cp_var_mod_type_p (tree, tree);
> extern void cxx_initialize_diagnostics (struct diagnostic_context *);
> extern int cxx_types_compatible_p (tree, tree);
> 
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1391
diff -r1.1391 decl.c
422c422
<        scope && scope != enclosing_blk && scope->kind == sk_block;
---
>        scope && scope != enclosing_blk;
429,432c429,441
< 	  if (TREE_CODE (decl) == VAR_DECL)
< 	    {
<               DECL_REGISTER (decl) = 0;
<               TREE_THIS_VOLATILE (decl) = 1;
---
> 	  /* Do not mess with variables that are 'static' or (already)
> 	     'volatile'.  */
> 	  if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
> 	      && (TREE_CODE (decl) == VAR_DECL
> 		  || TREE_CODE (decl) == PARM_DECL))
> 	    {
> 	      TREE_TYPE (decl)
> 		= build_qualified_type (TREE_TYPE (decl),
> 					(TYPE_QUALS (TREE_TYPE (decl))
> 					 | TYPE_QUAL_VOLATILE));
> 	      TREE_THIS_VOLATILE (decl) = 1;
> 	      TREE_SIDE_EFFECTS (decl) = 1;
> 	      DECL_REGISTER (decl) = 0;
434c443,447
<         }
---
> 	}
> 
>       /* Do not climb up past the current function.  */
>       if (scope->kind == sk_function_parms)
> 	break;
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.777
diff -r1.777 decl2.c
2611a2612,2620
>   /* For Objective-C++, we may need to initialize metadata found in this module.
>      This must be done _before_ any other static initializations.  */
>   if (c_dialect_objc () && (priority == DEFAULT_INIT_PRIORITY)
>       && constructor_p && objc_static_init_needed_p ())
>     {
>       body = start_objects (function_key, priority);
>       static_ctors = objc_generate_static_init_call (static_ctors);
>     }
> 
Index: gcc/cp/lex.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.357
diff -r1.357 lex.c
177a178
> #define D_OBJC		0x04	/* Objective C++ only */
281a283,307
>   /* The remaining keywords are specific to Objective-C++.  NB:
>      All of them will remain _disabled_, since they are context-
>      sensitive.  */
> 
>   /* These ObjC keywords are recognized only immediately after
>      an '@'.  NB: The following C++ keywords double as
>      ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
>      RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH.  */
>   { "compatibility_alias", RID_AT_ALIAS,	D_OBJC },
>   { "defs",		RID_AT_DEFS,		D_OBJC },
>   { "encode",		RID_AT_ENCODE,		D_OBJC },
>   { "end",		RID_AT_END,		D_OBJC },
>   { "implementation",	RID_AT_IMPLEMENTATION,	D_OBJC },
>   { "interface",	RID_AT_INTERFACE,	D_OBJC },
>   { "protocol",		RID_AT_PROTOCOL,	D_OBJC },
>   { "selector",		RID_AT_SELECTOR,	D_OBJC },
>   { "finally",		RID_AT_FINALLY,		D_OBJC },
>   { "synchronized",	RID_AT_SYNCHRONIZED,	D_OBJC },
>   /* These are recognized only in protocol-qualifier context.  */
>   { "bycopy",		RID_BYCOPY,		D_OBJC },
>   { "byref",		RID_BYREF,		D_OBJC },
>   { "in",		RID_IN,			D_OBJC },
>   { "inout",		RID_INOUT,		D_OBJC },
>   { "oneway",		RID_ONEWAY,		D_OBJC },
>   { "out",		RID_OUT,		D_OBJC },
289a316
> 	      | D_OBJC
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.329
diff -r1.329 parser.c
38a39
> #include "c-common.h"
410a412,428
>   /* Handle Objective-C++ keywords.  */
>   else if (token->type == CPP_AT_NAME)
>     {
>       token->type = CPP_KEYWORD;
>       switch (C_RID_CODE (token->value))
> 	{
> 	/* Map 'class' to '@class', 'private' to '@private', etc.  */
> 	case RID_CLASS: token->keyword = RID_AT_CLASS; break;
> 	case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
> 	case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
> 	case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
> 	case RID_THROW: token->keyword = RID_AT_THROW; break;
> 	case RID_TRY: token->keyword = RID_AT_TRY; break;
> 	case RID_CATCH: token->keyword = RID_AT_CATCH; break;
> 	default: token->keyword = C_RID_CODE (token->value);
> 	}
>     }
1644a1663,1735
> /* Objective-C++ Productions */
> 
> static tree cp_parser_objc_message_receiver
>   (cp_parser *);
> static tree cp_parser_objc_message_args
>   (cp_parser *);
> static tree cp_parser_objc_message_expression
>   (cp_parser *);
> static tree cp_parser_objc_encode_expression
>   (cp_parser *);
> static tree cp_parser_objc_defs_expression 
>   (cp_parser *);
> static tree cp_parser_objc_protocol_expression
>   (cp_parser *);
> static tree cp_parser_objc_selector_expression
>   (cp_parser *);
> static tree cp_parser_objc_expression
>   (cp_parser *);
> static void cp_parser_objc_visibility_spec
>   (cp_parser *);
> static void cp_parser_objc_method_type
>   (cp_parser *);
> static tree cp_parser_objc_protocol_qualifiers
>   (cp_parser *);
> static tree cp_parser_objc_typename
>   (cp_parser *);
> static bool cp_parser_objc_selector_p
>   (enum cpp_ttype);
> static tree cp_parser_objc_selector
>   (cp_parser *);
> static tree cp_parser_objc_method_keyword_params
>   (cp_parser *);
> static tree cp_parser_objc_method_tail_params_opt
>   (cp_parser *);
> static void cp_parser_objc_interstitial_code
>   (cp_parser *);
> static tree cp_parser_objc_method_signature
>   (cp_parser *);
> static void cp_parser_objc_method_prototype_list
>   (cp_parser *);
> static void cp_parser_objc_method_definition_list
>   (cp_parser *);
> static void cp_parser_objc_class_ivars
>   (cp_parser *);
> static tree cp_parser_objc_identifier_list
>   (cp_parser *);
> static void cp_parser_objc_alias_declaration
>   (cp_parser *);
> static void cp_parser_objc_class_declaration
>   (cp_parser *);
> static void cp_parser_objc_protocol_declaration
>   (cp_parser *);
> static tree cp_parser_objc_protocol_refs_opt
>   (cp_parser *);
> static void cp_parser_objc_superclass_or_category
>   (cp_parser *, tree *, tree *);
> static void cp_parser_objc_class_interface
>   (cp_parser *);
> static void cp_parser_objc_class_implementation
>   (cp_parser *);
> static void cp_parser_objc_end_implementation
>   (cp_parser *);
> static void cp_parser_objc_declaration
>   (cp_parser *);
> static tree cp_parser_objc_try_catch_finally_statement
>   (cp_parser *);
> static tree cp_parser_objc_synchronized_statement
>   (cp_parser *);
> static tree cp_parser_objc_throw_statement
>   (cp_parser *);
> static tree cp_parser_objc_statement
>   (cp_parser *);
> 
2654a2746,2750
>    Objective-C++ Extension:
> 
>    primary-expression:
>      objc-expression
> 
2880a2977,2982
> 	  /* Objective-C++ expressions.  */
> 	case RID_AT_ENCODE:
> 	case RID_AT_PROTOCOL:
> 	case RID_AT_SELECTOR:
> 	  return cp_parser_objc_expression (parser);
> 
2928a3031,3035
> 
> 	    /* In Objective-C++, an instance variable (ivar) may be preferred
> 	       to whatever cp_parser_lookup_name() found.  */
> 	    decl = objc_lookup_ivar (decl, id_expression);
> 
2978a3086,3090
>       /* ...unless we have an Objective-C++ message or string literal, that is.  */
>       if (c_dialect_objc () 
> 	  && (token->type == CPP_OPEN_SQUARE || token->type == CPP_OBJC_STRING))
> 	return cp_parser_objc_expression (parser);
> 
5956a6069,6077
> 	  /* Objective-C++ exception-handling constructs.  */
> 	case RID_AT_TRY:
> 	case RID_AT_CATCH:
> 	case RID_AT_FINALLY:
> 	case RID_AT_SYNCHRONIZED:
> 	case RID_AT_THROW:
> 	  statement = cp_parser_objc_statement (parser);
> 	  break;
> 
6858a6980,6982
>   /* Objective-C++ declaration/definition.  */
>   else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword))
>     cp_parser_objc_declaration (parser);
9599c9723,9742
<     cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type));
---
>     {
>       /* As a last-ditch effort, see if TYPE is an Objective-C type.
> 	 If it is, then the '<'...'>' enclose protocol names rather than
> 	 template arguments, and so everything is fine.  */
>       if (c_dialect_objc ()
> 	  && (objc_is_id (type) || objc_is_class_name (type)))
> 	{
> 	  tree protos = cp_parser_objc_protocol_refs_opt (parser);
> 	  tree qual_type = objc_get_protocol_qualified_type (type, protos);
> 
> 	  /* Clobber the "unqualified" type previously entered into
> 	     DECL_SPECS with the new, improved protocol-qualifed version.  */
> 	  if (decl_specs)
> 	    decl_specs->type = qual_type;
> 
> 	  return qual_type;
> 	}
> 
>       cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type));
>     } 
9644a9788,9798
> 
>       if (TREE_CODE (type_decl) != TYPE_DECL
> 	  && (objc_is_id (identifier) || objc_is_class_name (identifier)))
> 	{
> 	  /* See if this is an Objective-C type.  */
> 	  tree protos = cp_parser_objc_protocol_refs_opt (parser);
> 	  tree type = objc_get_protocol_qualified_type (identifier, protos);
> 	  if (type) 
> 	    type_decl = TYPE_NAME (type);
> 	}
> 
11751c11905,11908
< 	  || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
---
> 	  || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
> 	  /* These are for Objective-C++ */
> 	  || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
> 	  || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
13093a13251,13266
>   /* Check for @defs.  */
>   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS))
>     {
>       tree ivar, member;
>       tree ivar_chains = cp_parser_objc_defs_expression (parser);
>       ivar = ivar_chains;
>       while (ivar)
> 	{
> 	  member = ivar;
> 	  ivar = TREE_CHAIN (member);
> 	  TREE_CHAIN (member) = NULL_TREE;
> 	  finish_member_declaration (member);
> 	}
>       return;
>     }
> 
16054a16228,16599
> 
> /* Objective-C++ Productions */
> 
> 
> /* Parse an Objective-C expression, which feeds into a primary-expression
>    above.
> 
>    objc-expression:
>      objc-message-expression
>      objc-string-literal
>      objc-encode-expression
>      objc-protocol-expression
>      objc-selector-expression
> 
>   Returns a tree representation of the expression.  */
> 
> static tree
> cp_parser_objc_expression (cp_parser* parser)
> {
>   /* Try to figure out what kind of declaration is present.  */
>   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
> 
>   switch (kwd->type)
>     {
>     case CPP_OPEN_SQUARE:
>       return cp_parser_objc_message_expression (parser);
> 
>     case CPP_OBJC_STRING:
>       kwd = cp_lexer_consume_token (parser->lexer);
>       return objc_build_string_object (kwd->value);
> 
>     case CPP_KEYWORD:
>       switch (kwd->keyword)
> 	{
> 	case RID_AT_ENCODE:
> 	  return cp_parser_objc_encode_expression (parser);
> 
> 	case RID_AT_PROTOCOL:
> 	  return cp_parser_objc_protocol_expression (parser);
> 
> 	case RID_AT_SELECTOR:
> 	  return cp_parser_objc_selector_expression (parser);
> 
> 	default:
> 	  break;
> 	}
>     default:
>       error ("misplaced `@%D' Objective-C++ construct", kwd->value);
>       cp_parser_skip_to_end_of_block_or_statement (parser);
>     }
> 
>   return error_mark_node;
> }
> 
> /* Parse an Objective-C message expression.
> 
>    objc-message-expression:
>      [ objc-message-receiver objc-message-args ]
> 
>    Returns a representation of an Objective-C message.  */
> 
> static tree
> cp_parser_objc_message_expression (cp_parser* parser)
> {
>   tree receiver, messageargs;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '['.  */
>   receiver = cp_parser_objc_message_receiver (parser);
>   messageargs = cp_parser_objc_message_args (parser);
>   cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
> 
>   return objc_build_message_expr (build_tree_list (receiver, messageargs));
> }
> 
> /* Parse an objc-message-receiver.
> 
>    objc-message-receiver:
>      type-name
>      expression
> 
>   Returns a representation of the type or expression.  */
> 
> static tree
> cp_parser_objc_message_receiver (cp_parser* parser)
> {
>   tree rcv;
>   bool class_scope_p, template_p;
> 
>   /* An Objective-C message receiver may be either (1) a type
>      or (2) an expression.  */
>   cp_parser_parse_tentatively (parser);
>   rcv = cp_parser_expression (parser, false);
> 
>   if (cp_parser_parse_definitely (parser))
>     return rcv;
> 
>   /* Look for the optional `::' operator.  */
>   cp_parser_global_scope_opt (parser, false);
>   /* Look for the nested-name-specifier.  */
>   cp_parser_nested_name_specifier_opt (parser,
> 				       /*typename_keyword_p=*/true,
> 				       /*check_dependency_p=*/true,
> 				       /*type_p=*/true,
> 				       /*is_declaration=*/true);
>   class_scope_p = (parser->scope && TYPE_P (parser->scope));
>   template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
>   /* Finally, look for the class-name.  */
>   rcv = cp_parser_class_name (parser,
> 			       class_scope_p,
> 			       template_p,
> 			       /*type_p=*/true,
> 			       /*check_dependency_p=*/true,
> 			       /*class_head_p=*/false,
> 			       /*is_declaration=*/true);
> 
>   return objc_get_class_reference (rcv);
> }
> 
> /* Parse the arguments and selectors comprising an Objective-C message.
> 
>    objc-message-args:
>      objc-selector
>      objc-selector-args
>      objc-selector-args , objc-comma-args
> 
>    objc-selector-args:
>      objc-selector [opt] : assignment-expression
>      objc-selector-args objc-selector [opt] : assignment-expression
> 
>    objc-comma-args:
>      assignment-expression
>      objc-comma-args , assignment-expression
> 
>    Returns a TREE_LIST, with TREE_PURPOSE containing a list of
>    selector arguments and TREE_VALUE containing a list of comma
>    arguments.  */
> 
> static tree
> cp_parser_objc_message_args (cp_parser* parser)
> {
>   tree sel_args = NULL_TREE, addl_args = NULL_TREE;
>   bool maybe_unary_selector_p = true;
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
>     {
>       tree selector = NULL_TREE, arg;
> 
>       if (token->type != CPP_COLON)
> 	selector = cp_parser_objc_selector (parser);
> 
>       /* Detect if we have a unary selector.  */
>       if (maybe_unary_selector_p
> 	  && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
> 	return build_tree_list (selector, NULL_TREE);
> 
>       maybe_unary_selector_p = false;
>       cp_parser_require (parser, CPP_COLON, "`:'");
>       arg = cp_parser_assignment_expression (parser, false);
> 
>       sel_args
> 	= chainon (sel_args,
> 		   build_tree_list (selector, arg));
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   /* Handle non-selector arguments, if any. */
>   while (token->type == CPP_COMMA)
>     {
>       tree arg;
> 
>       cp_lexer_consume_token (parser->lexer);
>       arg = cp_parser_assignment_expression (parser, false);
> 
>       addl_args
> 	= chainon (addl_args,
> 		   build_tree_list (NULL_TREE, arg));
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   return build_tree_list (sel_args, addl_args);
> }
> 
> /* Parse an Objective-C encode expression.
> 
>    objc-encode-expression:
>      @encode objc-typename
>      
>    Returns an encoded representation of the type argument.  */
> 
> static tree
> cp_parser_objc_encode_expression (cp_parser* parser)
> {
>   tree type;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@encode'.  */
>   cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>   type = complete_type (cp_parser_type_id (parser));
>   cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
> 
>   if (!type)
>     {
>       error ("`@encode' must specify a type as an argument");
>       return error_mark_node;
>     }
> 
>   return objc_build_encode_expr (type);
> }
> 
> /* Parse an Objective-C @defs expression.  */
> 
> static tree
> cp_parser_objc_defs_expression (cp_parser *parser)
> {
>   tree name;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@defs'.  */
>   cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>   name = cp_parser_identifier (parser);
>   cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
> 
>   return objc_get_class_ivars (name);
> }
> 
> /* Parse an Objective-C protocol expression.
> 
>   objc-protocol-expression:
>     @protocol ( identifier )
> 
>   Returns a representation of the protocol expression.  */
> 
> static tree
> cp_parser_objc_protocol_expression (cp_parser* parser)
> {
>   tree proto;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
>   cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>   proto = cp_parser_identifier (parser);
>   cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
> 
>   return objc_build_protocol_expr (proto);
> }
> 
> /* Parse an Objective-C selector expression.
> 
>    objc-selector-expression:
>      @selector ( objc-method-signature )
> 
>    objc-method-signature:
>      objc-selector
>      objc-selector-seq
> 
>    objc-selector-seq:
>      objc-selector :
>      objc-selector-seq objc-selector :
> 
>   Returns a representation of the method selector.  */
> 
> static tree
> cp_parser_objc_selector_expression (cp_parser* parser)
> {
>   tree sel_seq = NULL_TREE;
>   bool maybe_unary_selector_p = true;
>   cp_token *token;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@selector'.  */
>   cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>   token = cp_lexer_peek_token (parser->lexer);
> 
>   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
>     {
>       tree selector = NULL_TREE;
> 
>       if (token->type != CPP_COLON)
> 	selector = cp_parser_objc_selector (parser);
> 
>       /* Detect if we have a unary selector.  */
>       if (maybe_unary_selector_p
> 	  && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
> 	{
> 	  sel_seq = selector;
> 	  goto finish_selector;
> 	}
> 
>       maybe_unary_selector_p = false;
>       cp_parser_require (parser, CPP_COLON, "`:'");
> 
>       sel_seq
> 	= chainon (sel_seq,
> 		   build_tree_list (selector, NULL_TREE));
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>  finish_selector:
>   cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
> 
>   return objc_build_selector_expr (sel_seq);
> }
> 
> /* Parse a list of identifiers.
> 
>    objc-identifier-list:
>      identifier
>      objc-identifier-list , identifier
> 
>    Returns a TREE_LIST of identifier nodes.  */
> 
> static tree
> cp_parser_objc_identifier_list (cp_parser* parser)
> {
>   tree list = build_tree_list (NULL_TREE, cp_parser_identifier (parser));
>   cp_token *sep = cp_lexer_peek_token (parser->lexer);
> 
>   while (sep->type == CPP_COMMA)
>     {
>       cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
>       list = chainon (list, 
> 		      build_tree_list (NULL_TREE,
> 				       cp_parser_identifier (parser)));
>       sep = cp_lexer_peek_token (parser->lexer);
>     }
>     
>   return list;
> }
> 
> /* Parse an Objective-C alias declaration.
> 
>    objc-alias-declaration:
>      @compatibility_alias identifier identifier ;
> 
>    This function registers the alias mapping with the Objective-C front-end.
>    It returns nothing.  */
> 
> static void
> cp_parser_objc_alias_declaration (cp_parser* parser)
> {
>   tree alias, orig;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@compatibility_alias'.  */
>   alias = cp_parser_identifier (parser);
>   orig = cp_parser_identifier (parser);
>   objc_declare_alias (alias, orig);
>   cp_parser_consume_semicolon_at_end_of_statement (parser);
> }
> 
> /* Parse an Objective-C class forward-declaration.
> 
>    objc-class-declaration:
>      @class objc-identifier-list ;
> 
>    The function registers the forward declarations with the Objective-C
>    front-end.  It returns nothing.  */
> 
> static void
> cp_parser_objc_class_declaration (cp_parser* parser)
> {
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@class'.  */
>   objc_declare_class (cp_parser_objc_identifier_list (parser));
>   cp_parser_consume_semicolon_at_end_of_statement (parser);
> }
> 
> /* Parse a list of Objective-C protocol references.
> 
>    objc-protocol-refs-opt:
>      objc-protocol-refs [opt]
> 
>    objc-protocol-refs:
>      < objc-identifier-list >
16055a16601,17293
>    Returns a TREE_LIST of identifiers, if any.  */
> 
> static tree
> cp_parser_objc_protocol_refs_opt (cp_parser* parser)
> {
>   tree protorefs = NULL_TREE;
> 
>   if(cp_lexer_next_token_is (parser->lexer, CPP_LESS))
>     {
>       cp_lexer_consume_token (parser->lexer);  /* Eat '<'.  */
>       protorefs = cp_parser_objc_identifier_list (parser);
>       cp_parser_require (parser, CPP_GREATER, "`>'");
>     }
> 
>   return protorefs;
> }
> 
> static void
> cp_parser_objc_visibility_spec (cp_parser* parser)
> {
>   cp_token *vis = cp_lexer_peek_token (parser->lexer);
> 
>   switch (vis->keyword)
>     {
>     case RID_AT_PRIVATE:
>       objc_set_visibility (2);
>       break;
>     case RID_AT_PROTECTED:
>       objc_set_visibility (0);
>       break;
>     case RID_AT_PUBLIC:
>       objc_set_visibility (1);
>       break;
>     default:
>       return;
>     }
> 
>   /* Eat '@private'/'@protected'/'@public'.  */
>   cp_lexer_consume_token (parser->lexer);
> }
> 
> static void
> cp_parser_objc_method_type (cp_parser* parser)
> {
>   objc_set_method_type
>    (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS
>     ? PLUS_EXPR
>     : MINUS_EXPR);
> }
> 
> static tree
> cp_parser_objc_protocol_qualifiers (cp_parser* parser)
> {
>   tree quals = NULL_TREE, node;
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   node = token->value;
> 
>   while (node && TREE_CODE (node) == IDENTIFIER_NODE
> 	 && (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]))
>     {
>       quals = tree_cons (NULL_TREE, node, quals);
>       cp_lexer_consume_token (parser->lexer);
>       token = cp_lexer_peek_token (parser->lexer);
>       node = token->value;
>     }
> 
>   return quals;
> }
> 
> static tree
> cp_parser_objc_typename (cp_parser* parser)
> {
>   tree typename = NULL_TREE;
> 
>   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
>     {
>       tree proto_quals, cp_type = NULL_TREE;
> 
>       cp_lexer_consume_token (parser->lexer);  /* Eat '('.  */
>       proto_quals = cp_parser_objc_protocol_qualifiers (parser);
> 
>       /* An ObjC type name may consist of just protocol qualifiers, in which
> 	 case the type shall default to 'id'.  */
>       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
> 	cp_type = cp_parser_type_id (parser);
> 
>       cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
>       typename = build_tree_list (proto_quals, cp_type);
>     }
> 
>   return typename;
> }
> 
> static bool
> cp_parser_objc_selector_p (enum cpp_ttype type)
> {
>   return (type == CPP_NAME || type == CPP_KEYWORD
> 	  || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND
> 	  || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT
> 	  || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ
> 	  || type == CPP_XOR || type == CPP_XOR_EQ);
> }
> 
> static tree
> cp_parser_objc_selector (cp_parser* parser)
> {
>   cp_token *token = cp_lexer_consume_token (parser->lexer);
>   
>   if (!cp_parser_objc_selector_p (token->type))
>     {
>       error ("invalid Objective-C++ selector name");
>       return error_mark_node;
>     }
> 
>   /* C++ operator names are allowed to appear in ObjC selectors.  */
>   switch (token->type)
>     {
>     case CPP_AND_AND: return get_identifier ("and");
>     case CPP_AND_EQ: return get_identifier ("and_eq");
>     case CPP_AND: return get_identifier ("bitand");
>     case CPP_OR: return get_identifier ("bitor");
>     case CPP_COMPL: return get_identifier ("compl");
>     case CPP_NOT: return get_identifier ("not");
>     case CPP_NOT_EQ: return get_identifier ("not_eq");
>     case CPP_OR_OR: return get_identifier ("or");
>     case CPP_OR_EQ: return get_identifier ("or_eq");
>     case CPP_XOR: return get_identifier ("xor");
>     case CPP_XOR_EQ: return get_identifier ("xor_eq");
>     default: return token->value;
>     }
> }
> 
> static tree
> cp_parser_objc_method_keyword_params (cp_parser* parser)
> {
>   tree params = NULL_TREE;
>   bool maybe_unary_selector_p = true;
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
>     {
>       tree selector = NULL_TREE, typename, identifier;
> 
>       if (token->type != CPP_COLON)
> 	selector = cp_parser_objc_selector (parser);
> 
>       /* Detect if we have a unary selector.  */
>       if (maybe_unary_selector_p
> 	  && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
> 	return selector;
> 
>       maybe_unary_selector_p = false;
>       cp_parser_require (parser, CPP_COLON, "`:'");
>       typename = cp_parser_objc_typename (parser);
>       identifier = cp_parser_identifier (parser);
> 
>       params
> 	= chainon (params,
> 		   objc_build_keyword_decl (selector, 
> 					    typename,
> 					    identifier));
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   return params;
> }
> 
> static tree
> cp_parser_objc_method_tail_params_opt (cp_parser* parser)
> {
>   tree params = make_node (TREE_LIST);
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   TREE_OVERFLOW (params) = 0;  /* Initially, assume no ellipsis.  */
> 
>   while (token->type == CPP_COMMA)
>     {
>       cp_parameter_declarator *parmdecl;
>       tree parm;
> 
>       cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
>       token = cp_lexer_peek_token (parser->lexer);
> 
>       if (token->type == CPP_ELLIPSIS)
> 	{
> 	  cp_lexer_consume_token (parser->lexer);  /* Eat '...'.  */
> 	  TREE_OVERFLOW (params) = 1;
> 	  break;
> 	}
> 
>       parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
>       parm = grokdeclarator (parmdecl->declarator,
> 			     &parmdecl->decl_specifiers,
> 			     PARM, /*initialized=*/0, 
> 			     /*attrlist=*/NULL);
> 
>       chainon (params, build_tree_list (NULL_TREE, parm));
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   return params;
> }
> 
> static void
> cp_parser_objc_interstitial_code (cp_parser* parser)
> {
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   /* If the next token is `extern' and the following token is a string
>      literal, then we have a linkage specification.  */
>   if (token->keyword == RID_EXTERN
>       && cp_parser_is_string_literal (cp_lexer_peek_nth_token (parser->lexer, 2)))
>     cp_parser_linkage_specification (parser);
>   /* Handle #pragma, if any.  */
>   else if (token->type == CPP_PRAGMA)
>     cp_lexer_handle_pragma (parser->lexer);
>   /* Allow stray semicolons.  */
>   else if (token->type == CPP_SEMICOLON)
>     cp_lexer_consume_token (parser->lexer);
>   /* Finally, try to parse a block-declaration, or a function-definition.  */
>   else
>     cp_parser_block_declaration (parser, /*statement_p=*/false);
> }
> 
> static tree
> cp_parser_objc_method_signature (cp_parser* parser)
> {
>   tree rettype, kwdparms, optparms;
>   /* FIXME Conceptually, we need to add 2005-04-21 Roger Sayle
>      <roger@eyesopen.com> from objc to the Objective-C++ code.  */
>   bool ellipsis = false;
> 
>   cp_parser_objc_method_type (parser);
>   rettype = cp_parser_objc_typename (parser);
>   kwdparms = cp_parser_objc_method_keyword_params (parser);
>   optparms = cp_parser_objc_method_tail_params_opt (parser);
> 
>   return objc_build_method_signature (rettype, kwdparms, optparms, ellipsis);
> }
> 
> static void
> cp_parser_objc_method_prototype_list (cp_parser* parser)
> {
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   while (token->keyword != RID_AT_END)
>     {
>       if (token->type == CPP_PLUS || token->type == CPP_MINUS)
> 	{
> 	  objc_add_method_declaration
> 	   (cp_parser_objc_method_signature (parser));
> 	  cp_parser_consume_semicolon_at_end_of_statement (parser);
> 	}
>       else
> 	/* Allow for interspersed non-ObjC++ code.  */
> 	cp_parser_objc_interstitial_code (parser);
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
>   objc_finish_interface ();
> }
> 
> static void
> cp_parser_objc_method_definition_list (cp_parser* parser)
> {
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   while (token->keyword != RID_AT_END)
>     {
>       tree meth;
> 
>       if (token->type == CPP_PLUS || token->type == CPP_MINUS)
> 	{
> 	  push_deferring_access_checks (dk_deferred);
> 	  objc_start_method_definition
> 	   (cp_parser_objc_method_signature (parser));
> 
> 	  /* For historical reasons, we accept an optional semicolon.  */
> 	  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
> 	    cp_lexer_consume_token (parser->lexer);
> 
> 	  perform_deferred_access_checks ();
> 	  stop_deferring_access_checks ();
> 	  meth = cp_parser_function_definition_after_declarator (parser,
> 								 false);
> 	  pop_deferring_access_checks ();
> 	  objc_finish_method_definition (meth);
> 	}
>       else
> 	/* Allow for interspersed non-ObjC++ code.  */
> 	cp_parser_objc_interstitial_code (parser);
> 
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
>   objc_finish_implementation ();
> }
> 
> static void
> cp_parser_objc_class_ivars (cp_parser* parser)
> {
>   cp_token *token = cp_lexer_peek_token (parser->lexer);
> 
>   if (token->type != CPP_OPEN_BRACE)
>     return;	/* No ivars specified.  */
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '{'.  */
>   token = cp_lexer_peek_token (parser->lexer);
> 
>   while (token->type != CPP_CLOSE_BRACE)
>     {
>       cp_decl_specifier_seq declspecs;
>       int decl_class_or_enum_p;
>       tree prefix_attributes;
> 
>       cp_parser_objc_visibility_spec (parser);
> 
>       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
> 	break;
> 
>       cp_parser_decl_specifier_seq (parser,
> 				    CP_PARSER_FLAGS_OPTIONAL,
> 				    &declspecs,
> 				    &decl_class_or_enum_p);
>       prefix_attributes = declspecs.attributes;
>       declspecs.attributes = NULL_TREE;
> 
>       /* Keep going until we hit the `;' at the end of the
> 	 declaration.  */
>       while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
> 	{
> 	  tree width = NULL_TREE, attributes, first_attribute, decl;
> 	  cp_declarator *declarator = NULL;
> 	  int ctor_dtor_or_conv_p;
> 
> 	  /* Check for a (possibly unnamed) bitfield declaration.  */
> 	  token = cp_lexer_peek_token (parser->lexer);
> 	  if (token->type == CPP_COLON)
> 	    goto eat_colon;
> 
> 	  if (token->type == CPP_NAME
> 	      && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
> 		  == CPP_COLON))
> 	    {
> 	      /* Get the name of the bitfield.  */
> 	      declarator = make_id_declarator (NULL_TREE,
> 					       cp_parser_identifier (parser));
> 
> 	     eat_colon:
> 	      cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
> 	      /* Get the width of the bitfield.  */
> 	      width
> 		= cp_parser_constant_expression (parser,
> 						 /*allow_non_constant=*/false,
> 						 NULL);
> 	    }
> 	  else
> 	    {
> 	      /* Parse the declarator.  */
> 	      declarator 
> 		= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
> 					&ctor_dtor_or_conv_p,
> 					/*parenthesized_p=*/NULL,
> 					/*member_p=*/false);
> 	    }
> 
> 	  /* Look for attributes that apply to the ivar.  */
> 	  attributes = cp_parser_attributes_opt (parser);
> 	  /* Remember which attributes are prefix attributes and
> 	     which are not.  */
> 	  first_attribute = attributes;
> 	  /* Combine the attributes.  */
> 	  attributes = chainon (prefix_attributes, attributes);
> 
> 	  if (width)
> 	    {
> 	      /* Create the bitfield declaration.  */
> 	      decl = grokbitfield (declarator, &declspecs, width);
> 	      cplus_decl_attributes (&decl, attributes, /*flags=*/0);
> 	    }
> 	  else
> 	    decl = grokfield (declarator, &declspecs, NULL_TREE,
> 			      NULL_TREE, attributes);
> 	  
> 	  /* Add the instance variable.  */
> 	  objc_add_instance_variable (decl);
> 
> 	  /* Reset PREFIX_ATTRIBUTES.  */
> 	  while (attributes && TREE_CHAIN (attributes) != first_attribute)
> 	    attributes = TREE_CHAIN (attributes);
> 	  if (attributes)
> 	    TREE_CHAIN (attributes) = NULL_TREE;
> 
> 	  token = cp_lexer_peek_token (parser->lexer);
> 
> 	  if (token->type == CPP_COMMA)
> 	    {
> 	      cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
> 	      continue;
> 	    }
> 	  break;
> 	}
> 
>       cp_parser_consume_semicolon_at_end_of_statement (parser);
>       token = cp_lexer_peek_token (parser->lexer);
>     }
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '}'.  */
>   /* For historical reasons, we accept an optional semicolon.  */
>   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
>     cp_lexer_consume_token (parser->lexer);
> }
> 
> static void
> cp_parser_objc_protocol_declaration (cp_parser* parser)
> {
>   tree proto, protorefs;
>   cp_token *tok;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
>   if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
>     {
>       error ("identifier expected after `@protocol'");
>       goto finish;
>     }
> 
>   /* See if we have a foward declaration or a definition.  */
>   tok = cp_lexer_peek_nth_token (parser->lexer, 2);
>   
>   /* Try a forward declaration first.  */
>   if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
>     {
>       objc_declare_protocols (cp_parser_objc_identifier_list (parser));
>      finish: 
>       cp_parser_consume_semicolon_at_end_of_statement (parser);
>     } 
> 
>   /* Ok, we got a full-fledged definition (or at least should).  */
>   else
>     {
>       proto = cp_parser_identifier (parser);
>       protorefs = cp_parser_objc_protocol_refs_opt (parser);
>       objc_start_protocol (proto, protorefs);
>       cp_parser_objc_method_prototype_list (parser);
>     }
> }
> 
> static void
> cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super,
> 							  tree *categ)
> {
>   cp_token *next = cp_lexer_peek_token (parser->lexer);
> 
>   *super = *categ = NULL_TREE;
>   if (next->type == CPP_COLON)
>     {
>       cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
>       *super = cp_parser_identifier (parser);
>     }
>   else if (next->type == CPP_OPEN_PAREN)
>     {
>       cp_lexer_consume_token (parser->lexer);  /* Eat '('.  */
>       *categ = cp_parser_identifier (parser);
>       cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
>     }
> }
> 
> static void
> cp_parser_objc_class_interface (cp_parser* parser)
> {
>   tree name, super, categ, protos;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@interface'.  */
>   name = cp_parser_identifier (parser);
>   cp_parser_objc_superclass_or_category (parser, &super, &categ);
>   protos = cp_parser_objc_protocol_refs_opt (parser);
> 
>   /* We have either a class or a category on our hands.  */
>   if (categ)
>     objc_start_category_interface (name, categ, protos);
>   else
>     {
>       objc_start_class_interface (name, super, protos);
>       /* Handle instance variable declarations, if any.  */
>       cp_parser_objc_class_ivars (parser);
>       objc_continue_interface ();
>     }
> 
>   cp_parser_objc_method_prototype_list (parser);
> }
> 
> static void
> cp_parser_objc_class_implementation (cp_parser* parser)
> {
>   tree name, super, categ;
> 
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@implementation'.  */
>   name = cp_parser_identifier (parser);
>   cp_parser_objc_superclass_or_category (parser, &super, &categ);
> 
>   /* We have either a class or a category on our hands.  */
>   if (categ)
>     objc_start_category_implementation (name, categ);
>   else
>     {
>       objc_start_class_implementation (name, super);
>       /* Handle instance variable declarations, if any.  */
>       cp_parser_objc_class_ivars (parser);
>       objc_continue_implementation ();
>     }
> 
>   cp_parser_objc_method_definition_list (parser);
> }
> 
> static void
> cp_parser_objc_end_implementation (cp_parser* parser)
> {
>   cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
>   objc_finish_implementation ();
> }
> 
> static void
> cp_parser_objc_declaration (cp_parser* parser)
> {
>   /* Try to figure out what kind of declaration is present.  */
>   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
> 
>   switch (kwd->keyword)
>     {
>     case RID_AT_ALIAS:
>       cp_parser_objc_alias_declaration (parser);
>       break;
>     case RID_AT_CLASS:
>       cp_parser_objc_class_declaration (parser);
>       break;
>     case RID_AT_PROTOCOL:
>       cp_parser_objc_protocol_declaration (parser);
>       break;
>     case RID_AT_INTERFACE:
>       cp_parser_objc_class_interface (parser);
>       break;
>     case RID_AT_IMPLEMENTATION:
>       cp_parser_objc_class_implementation (parser);
>       break;
>     case RID_AT_END:
>       cp_parser_objc_end_implementation (parser);
>       break;
>     default:
>       error ("misplaced `@%D' Objective-C++ construct", kwd->value);
>       cp_parser_skip_to_end_of_block_or_statement (parser);
>     }
> }
> 
> /* Parse an Objective-C try-catch-finally statement.
> 
>    objc-try-catch-finally-stmt:
>      @try compound-statement objc-catch-clause-seq [opt]
>        objc-finally-clause [opt]
> 
>    objc-catch-clause-seq:
>      objc-catch-clause objc-catch-clause-seq [opt]
> 
>    objc-catch-clause:
>      @catch ( exception-declaration ) compound-statement
> 
>    objc-finally-clause
>      @finally compound-statement
> 
>    Returns NULL_TREE.  */
> 
> static tree
> cp_parser_objc_try_catch_finally_statement (cp_parser *parser) {
>   location_t location;
>   tree stmt;
> 
>   cp_parser_require_keyword (parser, RID_AT_TRY, "`@try'");
>   location = cp_lexer_peek_token (parser->lexer)->location;
>   /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
>      node, lest it get absorbed into the surrounding block.  */
>   stmt = push_stmt_list ();
>   cp_parser_compound_statement (parser, NULL, false);
>   objc_begin_try_stmt (location, pop_stmt_list (stmt));
>   
>   while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
>     {
>       cp_parameter_declarator *parmdecl;
>       tree parm;
> 
>       cp_lexer_consume_token (parser->lexer);
>       cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>       parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
>       parm = grokdeclarator (parmdecl->declarator,
> 			     &parmdecl->decl_specifiers,
> 			     PARM, /*initialized=*/0, 
> 			     /*attrlist=*/NULL);
>       cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
>       objc_begin_catch_clause (parm);
>       cp_parser_compound_statement (parser, NULL, false);
>       objc_finish_catch_clause ();
>     }
> 
>   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
>     {
>       cp_lexer_consume_token (parser->lexer);
>       location = cp_lexer_peek_token (parser->lexer)->location;
>       /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
> 	 node, lest it get absorbed into the surrounding block.  */
>       stmt = push_stmt_list ();
>       cp_parser_compound_statement (parser, NULL, false);
>       objc_build_finally_clause (location, pop_stmt_list (stmt));
>     }
> 
>   return objc_finish_try_stmt ();
> }
> 
> /* Parse an Objective-C synchronized statement.
> 
>    objc-synchronized-stmt:
>      @synchronized ( expression ) compound-statement
> 
>    Returns NULL_TREE.  */
> 
> static tree
> cp_parser_objc_synchronized_statement (cp_parser *parser) {
>   location_t location;
>   tree lock, stmt;
> 
>   cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, "`@synchronized'");
> 
>   location = cp_lexer_peek_token (parser->lexer)->location;
>   cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
>   lock = cp_parser_expression (parser, false);
>   cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
> 
>   /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
>      node, lest it get absorbed into the surrounding block.  */
>   stmt = push_stmt_list ();
>   cp_parser_compound_statement (parser, NULL, false);
> 
>   return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
> }
> 
> /* Parse an Objective-C throw statement.
> 
>    objc-throw-stmt:
>      @throw assignment-expression [opt] ;
> 
>    Returns a constructed '@throw' statement.  */
> 
> static tree
> cp_parser_objc_throw_statement (cp_parser *parser) {
>   tree expr = NULL_TREE;
> 
>   cp_parser_require_keyword (parser, RID_AT_THROW, "`@throw'");
> 
>   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
>     expr = cp_parser_assignment_expression (parser, false);
> 
>   cp_parser_consume_semicolon_at_end_of_statement (parser);
> 
>   return objc_build_throw_stmt (expr);
> }
> 
> static tree
> cp_parser_objc_statement (cp_parser * parser) {
>   /* Try to figure out what kind of declaration is present.  */
>   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
> 
>   switch (kwd->keyword)
>     {
>     case RID_AT_TRY:
>       return cp_parser_objc_try_catch_finally_statement (parser);
>     case RID_AT_SYNCHRONIZED:
>       return cp_parser_objc_synchronized_statement (parser);
>     case RID_AT_THROW:
>       return cp_parser_objc_throw_statement (parser);
>     default:
>       error ("misplaced `@%D' Objective-C++ construct", kwd->value);
>       cp_parser_skip_to_end_of_block_or_statement (parser);
>     }
> 
>   return error_mark_node;
> }
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.996
diff -r1.996 pt.c
36a37
> #include "c-common.h"
37a39
> #include "cp-objcp-common.h"
4027c4029,4046
<     return TYPE_P (ot) && same_type_p (ot, nt);
---
>     {
>       int c1, c2;
> 
>       if (!TYPE_P (ot))
> 	return 0;
> 
>       /* We must handle ObjC types specially because they may differ
> 	 only in protocol qualifications (e.g., 'NSObject *' vs.
> 	 'NSObject <Foo> *') that must be taken into account here.
> 	 See also cp/typeck.c:build_c_cast(), where a similar problem
> 	 arises.  We must call objc_comptypes() twice, since its
> 	 comparisons are _not_ symmetric.  */
>       if ((c1 = objc_comptypes (ot, nt, 0)) >= 0
> 	  && (c2 = objc_comptypes (nt, ot, 0)) >= 0)
> 	return (c1 && c2);
> 
>       return same_type_p (ot, nt);
>     }
8882a8902,8909
>       /* Handle Objective-C++ constructs, if appropriate.  */
>       {
> 	tree subst
> 	  = objcp_tsubst_copy_and_build (t, args, complain,
> 					 in_decl, /*function_p=*/false);
> 	if (subst)
> 	  return subst;
>       }
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.470
diff -r1.470 semantics.c
404c404
< static tree
---
> tree
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.432
diff -r1.432 tree.c
35a36
> #include "debug.h"
113a115
>     case CONST_DECL:
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.626
diff -r1.626 typeck.c
517c517,518
<       if (DERIVED_FROM_P (class1, class2))
---
>       if (DERIVED_FROM_P (class1, class2) || 
> 	  (c_dialect_objc () && objc_comptypes (class1, class2, 0) == 1))
520c521,522
<       else if (DERIVED_FROM_P (class2, class1))
---
>       else if (DERIVED_FROM_P (class2, class1) ||
> 	       (c_dialect_objc () && objc_comptypes (class2, class1, 0) == 1))
1851a1854,1857
>   /* If OBJECT is an ObjC class instance, we must obey ObjC access rules.  */
>   if (!objc_is_public (object, name))
>     return error_mark_node;
> 
2397a2404,2407
>   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
>      expressions, like those used for ObjC messenger dispatches.  */
>   function = objc_rewrite_function_call (function, params);
> 
5448a5459,5466
>   if (c_dialect_objc () && flag_objc_gc)
>     {
>       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
> 
>       if (result)
> 	return result;
>     }
> 
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.613
diff -r1.613 invoke.texi
199a200,201
> -fobjc-call-cxx-cdtors @gol
> -fobjc-direct-dispatch @gol
200a203
> -fobjc-gc @gol
204c207,210
< -Wno-protocol  -Wselector -Wundeclared-selector}
---
> -Wassign-intercept @gol
> -Wno-protocol  -Wselector @gol
> -Wstrict-selector-match @gol
> -Wundeclared-selector}
815a822,828
> @item @var{file}.mm
> @itemx @var{file}.M
> Objective-C++ source code which must be preprocessed.
> 
> @item @var{file}.mii
> Objective-C++ source code which should not be preprocessed.
> 
1896a1910,1938
> @item -fobjc-call-cxx-cdtors
> @opindex fobjc-call-cxx-cdtors
> For each Objective-C class, check if any of its instance variables is a
> C++ object with a non-trivial default constructor.  If so, synthesize a
> special @code{- (id) .cxx_construct} instance method that will run
> non-trivial default constructors on any such instance variables, in order,
> and then return @code{self}.  Similarly, check if any instance variable
> is a C++ object with a non-trivial destructor, and if so, synthesize a
> special @code{- (void) .cxx_destruct} method that will run
> all such default destructors, in reverse order.
> 
> The @code{- (id) .cxx_construct} and/or @code{- (void) .cxx_destruct} methods
> thusly generated will only operate on instance variables declared in the
> current Objective-C class, and not those inherited from superclasses.  It
> is the responsibility of the Objective-C runtime to invoke all such methods
> in an object's inheritance hierarchy.  The @code{- (id) .cxx_construct} methods
> will be invoked by the runtime immediately after a new object
> instance is allocated; the @code{- (void) .cxx_destruct} methods will
> be invoked immediately before the runtime deallocates an object instance.
> 
> As of this writing, only the NeXT runtime on Mac OS X 10.4 and later has
> support for invoking the @code{- (id) .cxx_construct} and
> @code{- (void) .cxx_destruct} methods.
> 
> @item -fobjc-direct-dispatch
> @opindex fobjc-direct-dispatch
> Allow fast jumps to the message dispatcher.  On Darwin this is
> accompilished via the comm page.
> 
1988a2031,2034
> @item -fobjc-gc
> @opindex fobjc-gc
> Enable garbage collection (GC) in Objective-C and Objective-C++ programs.
> 
2014a2061,2065
> @item -Wassign-intercept
> @opindex Wassign-intercept
> Warn whenever an Objective-C assignment is being intercepted by the
> garbage collector.
> 
2037a2089,2097
> @item -Wstrict-selector-match
> @opindex Wstrict-selector-match
> Warn if multiple methods with differing argument and/or return types are
> found for a given selector when attempting to send a message using this
> selector to a receiver of type @code{id} or @code{Class}.  When this flag
> is off (which is the default behavior), the compiler will omit such warnings
> if any differences found are confined to types which share the same size
> and alignment.
> 
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.272
diff -r1.272 objc-act.c
79a80,81
> static unsigned int should_call_super_dealloc = 0;
> 
129c131
< #define OBJC_VERSION	(flag_next_runtime ? 5 : 8)
---
> #define OBJC_VERSION	(flag_next_runtime ? 6 : 8)
177a180,188
> static int objc_is_gcable_type (tree, int);
> static tree objc_substitute_decl (tree, tree, tree);
> static tree objc_build_ivar_assignment (tree, tree, tree);
> static tree objc_build_global_assignment (tree, tree);
> static tree objc_build_strong_cast_assignment (tree, tree);
> static int objc_is_gcable_p (tree);
> static int objc_is_ivar_reference_p (tree);
> static int objc_is_global_reference_p (tree);
> 
193c204
< static void generate_shared_structures (void);
---
> static void generate_shared_structures (int);
196a208,212
> #ifdef OBJCPLUS
> static void objc_generate_cxx_ctor_or_dtor (bool);
> static void objc_generate_cxx_cdtors (void);
> #endif
> 
218c234
< static tree add_class (tree);
---
> static tree add_class (tree, tree);
259c275,276
< static int comp_proto_with_proto (tree, tree);
---
> static int objc_types_share_size_and_alignment (tree, tree);
> static int comp_proto_with_proto (tree, tree, int);
380a398
> #define CLS_HAS_CXX_STRUCTORS		0x2000L
407a426,438
> #define TAG_ASSIGNIVAR			"objc_assign_ivar"
> #define TAG_ASSIGNGLOBAL		"objc_assign_global"
> #define TAG_ASSIGNSTRONGCAST		"objc_assign_strongCast"
> 
> /* Branch entry points.  All that matters here are the addresses;
>    functions with these names do not really exist in libobjc.  */
> 
> #define TAG_MSGSEND_FAST		"objc_msgSend_Fast"
> #define TAG_ASSIGNIVAR_FAST		"objc_assign_ivar_Fast"
> 
> #define TAG_CXX_CONSTRUCT		".cxx_construct"
> #define TAG_CXX_DESTRUCT		".cxx_destruct"
> 
412a444,447
> /* Flags for lookup_method_static().  */
> #define OBJC_LOOKUP_CLASS	1	/* Look for class methods.  */
> #define OBJC_LOOKUP_NO_SUPER	2	/* Do not examine superclasses.  */
> 
599,600c634,635
<      and code if only checking syntax.  */
<   if (!flag_syntax_only)
---
>      and code if only checking syntax, or if generating a PCH file.  */
>   if (!flag_syntax_only && !pch_file)
748a784,788
> #ifdef OBJCPLUS
>   if (flag_objc_call_cxx_cdtors)
>     objc_generate_cxx_cdtors ();
> #endif
> 
1443a1484,1494
>   /* Declare pointers to method and ivar lists.  */
>   objc_method_list_ptr = build_pointer_type
> 			 (xref_tag (RECORD_TYPE,
> 				    get_identifier (UTAG_METHOD_LIST)));
>   objc_method_proto_list_ptr
>     = build_pointer_type (xref_tag (RECORD_TYPE,
> 				    get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
>   objc_ivar_list_ptr = build_pointer_type
> 		       (xref_tag (RECORD_TYPE,
> 				  get_identifier (UTAG_IVAR_LIST)));
> 
1472a1524,1538
>       /* id objc_msgSend_Fast (id, SEL, ...)
> 	   __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
> #ifdef OFFS_MSGSEND_FAST
>       umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
> 					 type, 0, NOT_BUILT_IN,
> 					 NULL, NULL_TREE);
>       DECL_ATTRIBUTES (umsg_fast_decl) 
> 	= tree_cons (get_identifier ("hard_coded_address"), 
> 		     build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
> 		     NULL_TREE);
> #else
>       /* No direct dispatch availible.  */
>       umsg_fast_decl = umsg_decl;
> #endif
> 
2552a2619
>   bool local_scope = false;
2559c2626,2632
<     ident = DECL_NAME (ident);
---
>     {
>       /* The type must exist in the global namespace.  */
>       if (DECL_CONTEXT (ident) && DECL_CONTEXT (ident) != global_namespace)
> 	local_scope = true;
> 
>       ident = DECL_NAME (ident);
>     }
2563c2636
<   if (!(ident = objc_is_class_name (ident)))
---
>   if (local_scope || !(ident = objc_is_class_name (ident)))
2810a2884,2903
> static int
> objc_is_gcable_type (tree type, int or_strong_p)
> {
>   tree name; 
> 
>   if (!TYPE_P (type))
>     return 0;
>   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
>     return 1;
>   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
>     return 1;
>   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
>     return 0;
>   type = TREE_TYPE (type);
>   if (TREE_CODE (type) != RECORD_TYPE)
>     return 0;
>   name = TYPE_NAME (type);
>   return (objc_is_class_name (name) != NULL_TREE);
> }
> 
2812c2905
< lookup_interface (tree ident)
---
> objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
2814c2907,2929
<   tree chain;
---
>   if (expr == oldexpr)
>     return newexpr;
> 
>   switch (TREE_CODE (expr))
>     {
>     case COMPONENT_REF:
>       return build_component_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
> 							oldexpr,
> 							newexpr),
> 				  DECL_NAME (TREE_OPERAND (expr, 1)));
>     case ARRAY_REF:
>       return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
> 						    oldexpr,
> 						    newexpr),
> 			      TREE_OPERAND (expr, 1));
>     case INDIRECT_REF:
>       return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
> 						       oldexpr,
> 						       newexpr), "->");
>     default:
>       return expr;
>     }
> }
2815a2931,3153
> static tree
> objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
> {
>   tree func_params;
>   /* The LHS parameter contains the expression 'outervar->memberspec';
>      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
>      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
>   */
>   tree offs
>     = objc_substitute_decl
>       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
>   tree func
>     = (flag_objc_direct_dispatch
>        ? objc_assign_ivar_fast_decl
>        : objc_assign_ivar_decl);
> 
>   offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
>   offs = fold (offs);
>   func_params = tree_cons (NULL_TREE, 
> 	convert (objc_object_type, rhs),
> 	    tree_cons (NULL_TREE, convert (objc_object_type, outervar),
> 		tree_cons (NULL_TREE, offs,
> 		    NULL_TREE)));
> 
>   assemble_external (func);
>   return build_function_call (func, func_params);
> }
> 
> static tree
> objc_build_global_assignment (tree lhs, tree rhs)
> {
>   tree func_params = tree_cons (NULL_TREE,
> 	convert (objc_object_type, rhs),
> 	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
> 		      build_unary_op (ADDR_EXPR, lhs, 0)),
> 		    NULL_TREE));
> 
>   assemble_external (objc_assign_global_decl);
>   return build_function_call (objc_assign_global_decl, func_params);
> }
> 
> static tree
> objc_build_strong_cast_assignment (tree lhs, tree rhs)
> {
>   tree func_params = tree_cons (NULL_TREE,
> 	convert (objc_object_type, rhs),
> 	    tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
> 		      build_unary_op (ADDR_EXPR, lhs, 0)), 
> 		    NULL_TREE));
> 
>   assemble_external (objc_assign_strong_cast_decl);
>   return build_function_call (objc_assign_strong_cast_decl, func_params);
> }
> 
> static int
> objc_is_gcable_p (tree expr)
> {
>   return (TREE_CODE (expr) == COMPONENT_REF
> 	  ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
> 	  : TREE_CODE (expr) == ARRAY_REF
> 	  ? (objc_is_gcable_p (TREE_TYPE (expr))
> 	     || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
> 	  : TREE_CODE (expr) == ARRAY_TYPE
> 	  ? objc_is_gcable_p (TREE_TYPE (expr))
> 	  : TYPE_P (expr)
> 	  ? objc_is_gcable_type (expr, 1)
> 	  : (objc_is_gcable_p (TREE_TYPE (expr))
> 	     || (DECL_P (expr)
> 		 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
> }
> 
> static int
> objc_is_ivar_reference_p (tree expr)
> {
>   return (TREE_CODE (expr) == ARRAY_REF
> 	  ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
> 	  : TREE_CODE (expr) == COMPONENT_REF
> 	  ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
> 	  : 0);
> }
> 
> static int
> objc_is_global_reference_p (tree expr)
> {
>   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
> 	  ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
> 	  : DECL_P (expr)
> 	  ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
> 	  : 0);
> }
> 
> tree
> objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
> {
>   tree result = NULL_TREE, outer;
>   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
> 
>   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
>      will have been transformed to the form '*(type *)&expr'.  */
>   if (TREE_CODE (lhs) == INDIRECT_REF)
>     {
>       outer = TREE_OPERAND (lhs, 0);
> 
>       while (!strong_cast_p
> 	     && (TREE_CODE (outer) == CONVERT_EXPR
> 		 || TREE_CODE (outer) == NOP_EXPR
> 		 || TREE_CODE (outer) == NON_LVALUE_EXPR))
> 	{
> 	  tree lhstype = TREE_TYPE (outer);
> 
> 	  /* Descend down the cast chain, and record the first objc_gc
> 	     attribute found.  */
> 	  if (POINTER_TYPE_P (lhstype))
> 	    {
> 	      tree attr
> 		= lookup_attribute ("objc_gc",
> 				    TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
> 
> 	      if (attr)
> 		strong_cast_p = 1;
> 	    }
> 
> 	  outer = TREE_OPERAND (outer, 0);
> 	}
>     }
> 
>   /* If we have a __strong cast, it trumps all else.  */
>   if (strong_cast_p)
>     {
>       if (modifycode != NOP_EXPR)
>         goto invalid_pointer_arithmetic;
> 
>       if (warn_assign_intercept)
> 	warning (0, "strong-cast assignment has been intercepted");
> 
>       result = objc_build_strong_cast_assignment (lhs, rhs);
> 
>       goto exit_point;
>     }
> 
>   /* the lhs must be of a suitable type, regardless of its underlying
>      structure.  */
>   if (!objc_is_gcable_p (lhs))
>     goto exit_point;
> 
>   outer = lhs;
> 
>   while (outer
> 	 && (TREE_CODE (outer) == COMPONENT_REF
> 	     || TREE_CODE (outer) == ARRAY_REF))
>     outer = TREE_OPERAND (outer, 0);
> 
>   if (TREE_CODE (outer) == INDIRECT_REF)
>     {
>       outer = TREE_OPERAND (outer, 0);
>       indirect_p = 1;
>     }
> 
>   outer_gc_p = objc_is_gcable_p (outer);
>   
>   /* Handle ivar assignments. */
>   if (objc_is_ivar_reference_p (lhs))
>     {
>       /* if the struct to the left of the ivar is not an Objective-C object (__strong
> 	 doesn't cut it here), the best we can do here is suggest a cast.  */
>       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
> 	{
> 	  /* We may still be able to use the global write barrier... */
> 	  if (!indirect_p && objc_is_global_reference_p (outer))
> 	    goto global_reference;
> 
> 	 suggest_cast:
> 	  if (modifycode == NOP_EXPR)
> 	    {
> 	      if (warn_assign_intercept)
> 		warning (0, "strong-cast may possibly be needed");
> 	    }
> 
> 	  goto exit_point;
> 	}
> 
>       if (modifycode != NOP_EXPR)
>         goto invalid_pointer_arithmetic;
> 
>       if (warn_assign_intercept)
> 	warning (0, "instance variable assignment has been intercepted");
> 
>       result = objc_build_ivar_assignment (outer, lhs, rhs);
> 
>       goto exit_point;
>     }
> 
>   /* Likewise, intercept assignment to global/static variables if their type is
>      GC-marked.  */    
>   if (objc_is_global_reference_p (outer))
>     {
>       if (indirect_p)
> 	goto suggest_cast;
> 
>      global_reference:
>       if (modifycode != NOP_EXPR)
> 	{
> 	 invalid_pointer_arithmetic:
> 	  if (outer_gc_p)
> 	    warning (0, "pointer arithmetic for garbage-collected objects not allowed");
> 
> 	  goto exit_point;
> 	}
> 
>       if (warn_assign_intercept)
> 	warning (0, "global/static variable assignment has been intercepted");
> 
>       result = objc_build_global_assignment (lhs, rhs);
>     }
> 
>   /* In all other cases, fall back to the normal mechanism.  */
>  exit_point:
>   return result;
> }
> 
> static tree
> lookup_interface (tree ident)
> {
2820,2825c3158,3160
<   for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
<     {
<       if (ident == CLASS_NAME (chain))
<       return chain;
<     }
<   return NULL_TREE;
---
>   return (ident && TREE_CODE (ident) == IDENTIFIER_NODE
> 	  ? IDENTIFIER_INTERFACE_VALUE (ident)
> 	  : NULL_TREE);
3018a3354,3360
> #ifdef OBJCPLUS
>   /* Convert _setjmp argument to type that is expected.  */
>   if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
>     t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
>   else
>     t = convert (ptr_type_node, t);
> #else
3019a3362
> #endif
3245a3589,3591
> 
>   if (flag_objc_sjlj_exceptions)
>     objc_mark_locals_volatile (NULL);
3341c3687
< void
---
> tree
3378a3725
>   return stmt;
3410c3757
< void
---
> tree
3430c3777
<   objc_finish_try_stmt ();
---
>   return objc_finish_try_stmt ();
3511a3859,3896
> 
>   /* id objc_assign_ivar (id, id, unsigned int); */
>   /* id objc_assign_ivar_Fast (id, id, unsigned int)
>        __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
>   temp_type
>     = build_function_type (objc_object_type,
> 			   tree_cons
> 			   (NULL_TREE, objc_object_type,
> 			    tree_cons (NULL_TREE, objc_object_type,
> 				       tree_cons (NULL_TREE,
> 						  unsigned_type_node,
> 						  OBJC_VOID_AT_END))));
>   objc_assign_ivar_decl
>     = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
> 			NULL, NULL_TREE);
> #ifdef OFFS_ASSIGNIVAR_FAST
>   objc_assign_ivar_fast_decl
>     = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
> 			NOT_BUILT_IN, NULL, NULL_TREE);
>   DECL_ATTRIBUTES (objc_assign_ivar_fast_decl) 
>     = tree_cons (get_identifier ("hard_coded_address"), 
> 		 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
> 		 NULL_TREE);
> #else
>   /* Default to slower ivar method.  */
>   objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
> #endif
> 
>   /* id objc_assign_global (id, id *); */
>   /* id objc_assign_strongCast (id, id *); */
>   temp_type = build_function_type (objc_object_type,
> 		tree_cons (NULL_TREE, objc_object_type,
> 		    tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
> 			OBJC_VOID_AT_END)));
>   objc_assign_global_decl
> 	= builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
>   objc_assign_strong_cast_decl
> 	= builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3558a3944,3948
> 
>       /* Set the TREE_USED bit for this struct, so that stab generator
> 	 can emit stabs for this struct type.  */
>       if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
> 	TREE_USED (TYPE_STUB_DECL (record)) = 1;
3598,3602c3988,3989
<   /* struct objc_method_list *instance_methods; */
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_PROTOTYPE_LIST))),
---
>   /* struct _objc__method_prototype_list *instance_methods; */
>   field_decl = create_field_decl (objc_method_proto_list_ptr,
3606,3610c3993,3994
<   /* struct objc_method_list *class_methods; */
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_PROTOTYPE_LIST))),
---
>   /* struct _objc__method_prototype_list *class_methods; */
>   field_decl = create_field_decl (objc_method_proto_list_ptr,
3711c4095
<   return TYPE_MAIN_VARIANT (type);
---
>   return type;
3888a4273,4402
> /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
>    current class.  */
> #ifdef OBJCPLUS
> static void
> objc_generate_cxx_ctor_or_dtor (bool dtor)
> {
>   tree fn, body, compound_stmt, ivar;
> 
>   /* - (id) .cxx_construct { ... return self; } */
>   /* - (void) .cxx_construct { ... }            */
> 
>   objc_set_method_type (MINUS_EXPR);
>   objc_start_method_definition
>    (objc_build_method_signature (build_tree_list (NULL_TREE,
> 						  dtor
> 						  ? void_type_node
> 						  : objc_object_type),
> 				 get_identifier (dtor
> 						 ? TAG_CXX_DESTRUCT
> 						 : TAG_CXX_CONSTRUCT),
> 				 make_node (TREE_LIST),
> 				 false));
>   body = begin_function_body ();
>   compound_stmt = begin_compound_stmt (0);
> 
>   ivar = CLASS_IVARS (implementation_template);
>   /* Destroy ivars in reverse order.  */
>   if (dtor)
>     ivar = nreverse (copy_list (ivar));
> 
>   for (; ivar; ivar = TREE_CHAIN (ivar))
>     {
>       if (TREE_CODE (ivar) == FIELD_DECL)
> 	{
> 	  tree type = TREE_TYPE (ivar);
> 
> 	  /* Call the ivar's default constructor or destructor.  Do not
> 	     call the destructor unless a corresponding constructor call
> 	     has also been made (or is not needed).  */
> 	  if (IS_AGGR_TYPE (type)
> 	      && (dtor
> 		  ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
> 		     && (!TYPE_NEEDS_CONSTRUCTING (type)
> 			 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
> 		  : (TYPE_NEEDS_CONSTRUCTING (type)
> 		     && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
> 	    finish_expr_stmt
> 	     (build_special_member_call
> 	      (build_ivar_reference (DECL_NAME (ivar)),
> 	       dtor ? complete_dtor_identifier : complete_ctor_identifier,
> 	       NULL_TREE, type, LOOKUP_NORMAL));
> 	}
>     }
> 
>   /* The constructor returns 'self'.  */
>   if (!dtor)
>     finish_return_stmt (self_decl);
> 
>   finish_compound_stmt (compound_stmt);
>   finish_function_body (body);
>   fn = current_function_decl;
>   finish_function ();
>   objc_finish_method_definition (fn);
> }
> 
> /* The following routine will examine the current @interface for any
>    non-POD C++ ivars requiring non-trivial construction and/or
>    destruction, and then synthesize special '- .cxx_construct' and/or
>    '- .cxx_destruct' methods which will run the appropriate
>    construction or destruction code.  Note that ivars inherited from
>    super-classes are _not_ considered.  */
> static void
> objc_generate_cxx_cdtors (void)
> {
>   bool need_ctor = false, need_dtor = false;
>   tree ivar;
> 
>   /* We do not want to do this for categories, since they do not have
>      their own ivars.  */
> 
>   if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
>     return;
> 
>   /* First, determine if we even need a constructor and/or destructor.  */
> 
>   for (ivar = CLASS_IVARS (implementation_template); ivar;
>        ivar = TREE_CHAIN (ivar))
>     {
>       if (TREE_CODE (ivar) == FIELD_DECL)
> 	{
> 	  tree type = TREE_TYPE (ivar);
> 
> 	  if (IS_AGGR_TYPE (type))
> 	    {
> 	      if (TYPE_NEEDS_CONSTRUCTING (type)
> 		  && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
> 		/* NB: If a default constructor is not available, we will not
> 		   be able to initialize this ivar; the add_instance_variable()
> 		   routine will already have warned about this.  */
> 		need_ctor = true;
> 
> 	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
> 		  && (!TYPE_NEEDS_CONSTRUCTING (type)
> 		      || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
> 		/* NB: If a default constructor is not available, we will not
> 		   call the destructor either, for symmetry.  */
> 		need_dtor = true;
> 	    }
> 	}
>     }
> 
>   /* Generate '- .cxx_construct' if needed.  */
> 
>   if (need_ctor)
>     objc_generate_cxx_ctor_or_dtor (false);
> 
>   /* Generate '- .cxx_destruct' if needed.  */
> 
>   if (need_dtor)
>     objc_generate_cxx_ctor_or_dtor (true);
> 
>   /* The 'imp_list' variable points at an imp_entry record for the current
>      @implementation.  Record the existence of '- .cxx_construct' and/or
>      '- .cxx_destruct' methods therein; it will be included in the
>      metadata for the class.  */
>   if (flag_next_runtime)
>     imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
> }
> #endif
> 
4022c4536,4537
<       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
---
>       expr = convert (objc_method_proto_list_ptr,
> 		      build_unary_op (ADDR_EXPR, instance_methods, 0));
4030c4545,4546
<       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
---
>       expr = convert (objc_method_proto_list_ptr,
> 		      build_unary_op (ADDR_EXPR, class_methods, 0));
4062,4065c4578
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_LIST))),
---
>   field_decl = create_field_decl (objc_method_list_ptr,
4070,4073c4583
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_LIST))),
---
>   field_decl = create_field_decl (objc_method_list_ptr,
4175,4178c4685
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_IVAR_LIST))),
---
>   field_decl = create_field_decl (objc_ivar_list_ptr,
4183,4186c4690
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_LIST))),
---
>   field_decl = create_field_decl (objc_method_list_ptr,
4437,4440c4941
<   field_decl = create_field_decl (build_pointer_type
< 				  (xref_tag (RECORD_TYPE,
< 					     get_identifier
< 					     (UTAG_METHOD_PROTOTYPE_LIST))),
---
>   field_decl = create_field_decl (objc_method_proto_list_ptr,
4839c5340,5341
<       expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
---
>       expr = convert (objc_method_list_ptr,
> 		      build_unary_op (ADDR_EXPR, instance_methods, 0));
4846c5348,5349
<       expr = build_unary_op (ADDR_EXPR, class_methods, 0);
---
>       expr = convert (objc_method_list_ptr,
> 		      build_unary_op (ADDR_EXPR, class_methods, 0));
4922c5425,5426
<       expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
---
>       expr = convert (objc_ivar_list_ptr,
> 		      build_unary_op (ADDR_EXPR, ivar_list, 0));
4931c5435,5436
<       expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
---
>       expr = convert (objc_method_list_ptr,
> 		      build_unary_op (ADDR_EXPR, dispatch_table, 0));
5026c5531
< generate_shared_structures (void)
---
> generate_shared_structures (int cls_flags)
5117c5622
<        1 /*CLS_FACTORY*/,
---
>        1 /*CLS_FACTORY*/ | cls_flags,
5377a5883
> 
5378a5885,5898
> 	  /* But just how different are those types?  If
> 	     -Wno-strict-selector-match is specified, we shall not
> 	     complain if the differences are solely among types with
> 	     identical size and alignment.  */
> 	  if (!warn_strict_selector_match)
> 	    {
> 	      for (loop = hsh->list; loop; loop = loop->next)
> 		if (!comp_proto_with_proto (meth, loop->value, 0))
> 		  goto issue_warning;
> 
> 	      return meth;
> 	    }
> 
> 	issue_warning:
5589a6110,6113
>   /* If we are calling [super dealloc], reset our warning flag.  */
>   if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
>     should_call_super_dealloc = 0;
> 
5618c6142
<   if (!rtype || objc_is_id (rtype))
---
>   if (objc_is_id (rtype))
5620,5629c6144,6148
<       if (!rtype)
< 	rtype = xref_tag (RECORD_TYPE, class_tree);
<       else
< 	{
< 	  class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
< 	  rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
< 		     ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
< 		     : NULL_TREE);
< 	  rtype = NULL_TREE;
< 	}
---
>       class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
>       rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
> 		 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
> 		 : NULL_TREE);
>       rtype = NULL_TREE;
5654c6173
<   else
---
>   else if (rtype)
5676c6195
< 	rtype = saved_rtype;
---
> 	rtype = NULL_TREE;
5791c6310,6312
< 		  ? umsg_decl
---
> 		  ? (flag_objc_direct_dispatch
> 		     ? umsg_fast_decl
> 		     : umsg_decl)
6127a6649,6658
> /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
>    in INTERFACE, along with any categories and protocols attached thereto.
>    If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
>    recursively examine the INTERFACE's superclass.  If OBJC_LOOKUP_CLASS is 
>    set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
>    be found in INTERFACE or any of its superclasses, look for an _instance_
>    method of the same name in the root class as a last resort.
> 
>    If a suitable method cannot be found, return NULL_TREE.  */
>    
6129c6660
< lookup_method_static (tree interface, tree ident, int is_class)
---
> lookup_method_static (tree interface, tree ident, int flags)
6132a6664,6665
>   int is_class = (flags & OBJC_LOOKUP_CLASS);
>   int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6168a6702,6705
>       /* If we were instructed not to look in superclasses, don't.  */
>       if (no_superclasses)
> 	return NULL_TREE;
> 
6198c6735
<       int already_there = comp_proto_with_proto (method, hsh->key);
---
>       int already_there = comp_proto_with_proto (method, hsh->key, 1);
6200c6737
< 	already_there |= comp_proto_with_proto (method, loop->value);
---
> 	already_there |= comp_proto_with_proto (method, loop->value, 1);
6236c6773
< 	  && !comp_proto_with_proto (method, mth))
---
> 	  && !comp_proto_with_proto (method, mth, 1))
6266c6803
< add_class (tree class)
---
> add_class (tree class, tree name)
6270a6808
>   IDENTIFIER_INTERFACE_VALUE (name) = class;
6326,6329c6864,6871
<   /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
<      cannot be ivars; ditto for classes with vtables. */
<   if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
<       || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
---
>   /* Check if the ivar being added has a non-POD C++ type.   If so, we will
>      need to either (1) warn the user about it or (2) generate suitable
>      constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
>      methods (if '-fobjc-call-cxx-cdtors' was specified).  */
>   if (IS_AGGR_TYPE (field_type)
>       && (TYPE_NEEDS_CONSTRUCTING (field_type)
> 	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
> 	  || TYPE_POLYMORPHIC_P (field_type)))
6332,6346c6874,6922
<       if(TYPE_POLYMORPHIC_P (field_type)) {
<         /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
<         error ("type %qs has virtual member functions", type_name);
<         error ("illegal aggregate type %qs specified for instance variable %qs",
<   	       type_name, ivar_name);
<         /* Return class as is without adding this ivar.  */
<         return class;
<       }
<       /* user-defined constructors and destructors are not known to Obj-C and
<          hence will not be called.  This may or may not be a problem. */
<       if (TYPE_NEEDS_CONSTRUCTING (field_type))
<         warning (0, "type %qs has a user-defined constructor", type_name);
<       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
<         warning (0, "type %qs has a user-defined destructor", type_name);
<       warning (0, "C++ constructors and destructors will not be invoked for Objective-C fields");
---
> 
>       if (flag_objc_call_cxx_cdtors)
>         {
> 	  /* Since the ObjC runtime will be calling the constructors and
> 	     destructors for us, the only thing we can't handle is the lack
> 	     of a default constructor.  */
> 	  if (TYPE_NEEDS_CONSTRUCTING (field_type)
> 	      && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
> 	    {
> 	      warning (0, "type `%s' has no default constructor to call",
> 		       type_name);
> 
> 	      /* If we cannot call a constructor, we should also avoid
> 		 calling the destructor, for symmetry.  */
> 	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
> 		warning (0, "destructor for `%s' shall not be run either",
> 			 type_name);
> 	    }
>         }
>       else
> 	{
> 	  static bool warn_cxx_ivars = false;
> 
> 	  if (TYPE_POLYMORPHIC_P (field_type))
> 	    {
> 	      /* Vtable pointers are Real Bad(tm), since Obj-C cannot
> 		 initialize them.  */
> 	      error ("type `%s' has virtual member functions", type_name);
> 	      error ("illegal aggregate type `%s' specified "
> 		     "for instance variable `%s'",
> 		     type_name, ivar_name);
> 	      /* Return class as is without adding this ivar.  */
> 	      return class;
> 	    }
> 
> 	  /* User-defined constructors and destructors are not known to Obj-C
> 	     and hence will not be called.  This may or may not be a problem. */
> 	  if (TYPE_NEEDS_CONSTRUCTING (field_type))
> 	    warning (0,"type `%s' has a user-defined constructor", type_name);
> 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
> 	    warning (0,"type `%s' has a user-defined destructor", type_name);
> 
> 	  if (!warn_cxx_ivars)
> 	    {
> 	      warning (0,"C++ constructors and destructors will not "
> 		       "be invoked for Objective-C fields");
> 	      warn_cxx_ivars = true;
> 	    }
> 	}
6403d6978
<   enum tree_code code = TREE_CODE (basetype);
6406c6981
<   if (code == RECORD_TYPE)
---
>   if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
6410c6985,6987
< 	  if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype)) == IDENTIFIER_NODE)
---
> 	  tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
> 
> 	  if (!class)
6417c6994
< 	  if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
---
> 	  if ((decl = is_ivar (get_class_ivars (class), identifier)))
6458,6463d7034
< 
<       else if (objc_implementation_context && (basetype == objc_object_reference))
< 	{
< 	  expr = convert (uprivate_record, expr);
< 	  warning (0, "static access to object of type %<id%>");
< 	}
6690c7261,7263
<   /* Check for existence of the super class, if one was specified.  */
---
>   /* Check for existence of the super class, if one was specified.  Note
>      that we must have seen an @interface, not just a @class.  If we
>      are looking at a @compatibility_alias, traverse it first.  */
6692c7265
<       && super_name && !objc_is_class_name (super_name))
---
>       && super_name)
6694,6697c7267,7277
<       error ("cannot find interface declaration for %qs, superclass of %qs",
< 	     IDENTIFIER_POINTER (super_name),
< 	     IDENTIFIER_POINTER (class_name));
<       super_name = NULL_TREE;
---
>       tree super = objc_is_class_name (super_name);
> 
>       if (!super || !lookup_interface (super))
> 	{
> 	  error ("cannot find interface declaration for %qs, superclass of %qs",
> 		 IDENTIFIER_POINTER (super ? super : super_name),
> 		 IDENTIFIER_POINTER (class_name));
> 	  super_name = NULL_TREE;
> 	}
>       else
> 	super_name = super;
6740c7320,7321
< 	  add_class (implementation_template = objc_implementation_context);
---
> 	  add_class (implementation_template = objc_implementation_context,
> 		     class_name);
6774c7355
<         add_class (class);
---
>         add_class (class, class_name);
6831d7411
<       tree ivar_context;
6846d7425
<       ivar_context = TYPE_FIELDS (uprivate_record);
6857a7437
>       imp_entry->has_cxx_cdtors = 0;
6870c7450
<       return ivar_context;
---
>       return get_class_ivars (implementation_template);
7162,7164c7742,7745
<   int pointed_to
<    = (obstack_object_size (&util_obstack) > 0
<       && *(obstack_next_free (&util_obstack) - 1) == '^');
---
>   int ob_size = obstack_object_size (&util_obstack);
>   char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
>   char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
>   int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7167c7748
<       && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
---
>       && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7513a8095,8103
>   /* If we are defining a "dealloc" method in a non-root class, we
>      will need to check if a [super dealloc] is missing, and warn if
>      it is.  */
>   if(CLASS_SUPER_NAME (objc_implementation_context)
>      && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
>     should_call_super_dealloc = 1;
>   else
>     should_call_super_dealloc = 0;
> 
7591a8182,8190
> /* Return 1 if TYPE1 has the same size and alignment as TYPE2.  */
> 
> static int
> objc_types_share_size_and_alignment (tree type1, tree type2)
> {
>   return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
> 	  && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
> }
> 
7593c8192,8195
<    for purposes of method overloading.  */
---
>    for purposes of method overloading.  Ordinarily, the type signatures
>    should match up exactly, unless STRICT is zero, in which case we
>    shall allow differences in which the size and alignment of a type
>    is the same.  */
7596c8198
< comp_proto_with_proto (tree proto1, tree proto2)
---
> comp_proto_with_proto (tree proto1, tree proto2, int strict)
7609c8211,8212
<   if (!objc_types_are_equivalent (type1, type2))
---
>   if (!objc_types_are_equivalent (type1, type2)
>       && (strict || !objc_types_share_size_and_alignment (type1, type2)))
7618c8221,8224
<       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
---
>       if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
> 	  && (strict
> 	      || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
> 						       TREE_VALUE (type2))))
7684a8291,8293
>   current_function_returns_value = 0;  /* Assume, until we see it does.  */
>   current_function_returns_null = 0;
> 
7775c8384,8385
< 				TREE_CODE (method) == CLASS_METHOD_DECL);
---
> 				((TREE_CODE (method) == CLASS_METHOD_DECL)
> 				 | OBJC_LOOKUP_NO_SUPER));
7779c8389
< 	  if (!comp_proto_with_proto (method, proto))
---
> 	  if (!comp_proto_with_proto (method, proto, 1))
7950a8561,8563
> 
>   if (should_call_super_dealloc)
>     warning (0,"method possibly missing a [super dealloc] call");
8325c8938,8940
< 	  generate_shared_structures ();
---
> 	  generate_shared_structures (impent->has_cxx_cdtors
> 				      ? CLS_HAS_CXX_STRUCTORS
> 				      : 0);
8342c8957
<   if (flag_replace_objc_classes && imp_list)
---
>   if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
8523a9139,9141
>   int flags
>     = ((flag_replace_objc_classes && imp_list ? 1 : 0)
>        | (flag_objc_gc ? 2 : 0));
8531c9149
<   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
---
>   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
8568c9186,9191
<       && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
---
>       && other && other != error_mark_node
> #ifdef OBJCPLUS
>       && CP_DECL_CONTEXT (other) != global_namespace)
> #else
>       && !DECL_FILE_SCOPE_P (other))
> #endif
8581a9205,9223
> /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
>    needs to be done if we are calling a function through a cast.  */
> 
> tree
> objc_rewrite_function_call (tree function, tree params)
> {
>   if (TREE_CODE (function) == NOP_EXPR
>       && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
>       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
> 	 == FUNCTION_DECL)
>     {
>       function = build (OBJ_TYPE_REF, TREE_TYPE (function),
> 			TREE_OPERAND (function, 0),
> 			TREE_VALUE (params), size_zero_node);
>     }
> 
>   return function;
> }
> 
8606a9249,9251
> #ifdef OBJCPLUS
>   return cp_gimplify_expr (expr_p, pre_p, post_p);
> #else
8607a9253
> #endif
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.37
diff -r1.37 objc-act.h
79a80,82
> 
> /* The following three macros must be overridden (in objcp/objcp-decl.h)
>    for Objective-C++.  */
80a84,89
> #define SIZEOF_OBJC_TYPE_LANG_SPECIFIC sizeof (struct lang_type)
> #define ALLOC_OBJC_TYPE_LANG_SPECIFIC(NODE)				\
>   do {									\
>     TYPE_LANG_SPECIFIC (NODE) = GGC_CNEW (struct lang_type);		\
>   } while (0)
> 
82,83c91
< 	(TYPE_LANG_SPECIFIC (TYPE)				\
< 	 && TYPE_LANG_SPECIFIC (TYPE)->objc_info)
---
> 	(TYPE_LANG_SPECIFIC (TYPE) && TYPE_OBJC_INFO (TYPE))
86a95
> 
91,94c100,102
< 	      TYPE_LANG_SPECIFIC (TYPE)				\
< 		= ALLOC_OBJC_TYPE_LANG_SPECIFIC;			\
< 	    if (!TYPE_LANG_SPECIFIC (TYPE)->objc_info)		\
< 	      TYPE_LANG_SPECIFIC (TYPE)->objc_info		\
---
> 	      ALLOC_OBJC_TYPE_LANG_SPECIFIC(TYPE);		\
> 	    if (!TYPE_OBJC_INFO (TYPE))				\
> 	      TYPE_OBJC_INFO (TYPE)				\
101,102c109
< 	    TYPE_LANG_SPECIFIC (DST)				\
< 	      = ALLOC_OBJC_TYPE_LANG_SPECIFIC;			\
---
> 	    ALLOC_OBJC_TYPE_LANG_SPECIFIC(DST);			\
107c114
< 	    TYPE_LANG_SPECIFIC (DST)->objc_info			\
---
> 	    TYPE_OBJC_INFO (DST)				\
112,116d118
< /* The following two macros must be overridden (in objcp/objcp-decl.h)
<    for Objective-C++.  */
< #define ALLOC_OBJC_TYPE_LANG_SPECIFIC	GGC_CNEW (struct lang_type)
< #define SIZEOF_OBJC_TYPE_LANG_SPECIFIC	sizeof (struct lang_type)
< 
123a126,128
> #define IDENTIFIER_INTERFACE_VALUE(NODE) \
> 	(((struct lang_identifier *) (NODE))->interface_value)
> 
172a178
>   BOOL_BITFIELD has_cxx_cdtors : 1;
193a200
>     OCTI_UMSG_FAST_DECL,
243a251,253
>     OCTI_METH_LIST_TEMPL,
>     OCTI_METH_PROTO_LIST_TEMPL,
>     OCTI_IVAR_LIST_TEMPL,
280a291,295
>     OCTI_ASSIGN_IVAR_DECL,
>     OCTI_ASSIGN_IVAR_FAST_DECL,
>     OCTI_ASSIGN_GLOBAL_DECL,
>     OCTI_ASSIGN_STRONGCAST_DECL,
> 
299a315
> #define umsg_fast_decl		objc_global_trees[OCTI_UMSG_FAST_DECL]
410a427,433
> #define objc_assign_ivar_decl	objc_global_trees[OCTI_ASSIGN_IVAR_DECL]
> #define objc_assign_ivar_fast_decl		\
> 				objc_global_trees[OCTI_ASSIGN_IVAR_FAST_DECL]
> #define objc_assign_global_decl	objc_global_trees[OCTI_ASSIGN_GLOBAL_DECL]
> #define objc_assign_strong_cast_decl		\
> 				objc_global_trees[OCTI_ASSIGN_STRONGCAST_DECL]
> 
412a436,439
> #define objc_method_list_ptr	objc_global_trees[OCTI_METH_LIST_TEMPL]
> #define objc_method_proto_list_ptr		\
> 				objc_global_trees[OCTI_METH_PROTO_LIST_TEMPL]
> #define objc_ivar_list_ptr	objc_global_trees[OCTI_IVAR_LIST_TEMPL]
Index: gcc/objcp/Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objcp/Make-lang.in,v
retrieving revision 1.2
diff -r1.2 Make-lang.in
63c63
<   $(DIAGNOSTIC_H) cp/cp-objcp-common.h
---
>   $(DIAGNOSTIC_H) cp/cp-objcp-common.h tree-gimple.h
68c68
<    objcp/objcp-decl.h
---
>    objcp/objcp-decl.h tree-gimple.h
76c76,77
<    objcp/objcp-decl.h $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h
---
>    objcp/objcp-decl.h $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h \
>    tree-gimple.h
Index: gcc/objcp/objcp-lang.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objcp/objcp-lang.c,v
retrieving revision 1.2
diff -r1.2 objcp-lang.c
50a51,52
> #undef LANG_HOOKS_GIMPLIFY_EXPR 
> #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
Index: gcc/testsuite/objc.dg/method-5.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-5.m,v
retrieving revision 1.3
diff -r1.3 method-5.m
14,15c14,15
<   [u nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\-nonexistent_method." } */
<   [UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */
---
>   [u nonexistent_method]; /* { dg-warning "no .\\-nonexistent_method. method found" } */
>   [UnderSpecified nonexistent_method]; /* { dg-warning "no .\\+nonexistent_method. method found" } */
Index: gcc/testsuite/objc.dg/method-6.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-6.m,v
retrieving revision 1.5
diff -r1.5 method-6.m
4a5
> /* { dg-options "-Wstrict-selector-match" } */
22,23c23,24
<        /* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */
<        /* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 14 } */
---
>        /* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 10 } */
>        /* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 15 } */
26,28c27,29
<        /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
<        /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
<        /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
---
>        /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 26 } */
>        /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 26 } */
>        /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 26 } */
Index: gcc/testsuite/objc.dg/method-7.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-7.m,v
retrieving revision 1.2
diff -r1.2 method-7.m
2a3
> 
3a5
> /* { dg-options "-Wstrict-selector-match" } */
19,21c21,23
<        /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 18 } */
<        /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 18 } */
<        /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 18 } */
---
>   /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 20 } */
>   /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 20 } */
>   /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 20 } */
23,24c25,26
<        /* { dg-warning "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 8 } */
<        /* { dg-warning "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 12 } */
---
>   /* { dg-warning "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 10 } */
>   /* { dg-warning "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 14 } */
Index: gcc/testsuite/objc.dg/method-9.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/method-9.m,v
retrieving revision 1.3
diff -r1.3 method-9.m
3a4
> 
4a6
> /* { dg-options "-Wstrict-selector-match" } */
34,37c36,39
<      /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 33 } */
<      /* { dg-warning "using .\\-\\(id\\)initWithData:\\(Object \\*\\)data." "" { target *-*-* } 9 } */
<      /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 17 } */
<      /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 13 } */
---
>     /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 35 } */
>     /* { dg-warning "using .\\-\\(id\\)initWithData:\\(Object \\*\\)data." "" { target *-*-* } 11 } */
>     /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 19 } */
>     /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 15 } */
39,40c41,42
<      /* The following warning is a consequence of picking the "wrong" method signature.  */
<      /* { dg-warning "passing argument 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 33 } */
---
>     /* The following warning is a consequence of picking the "wrong" method signature.  */
>     /* { dg-warning "passing argument 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 35 } */
Index: gcc/testsuite/objc.dg/try-catch-2.m
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/objc.dg/try-catch-2.m,v
retrieving revision 1.4
diff -r1.4 try-catch-2.m
1,2c1,2
< /* Test out '@catch(id foo) {...}', which should catch
<    all uncaught exceptions.  */
---
> /* Test out '@catch(id foo) {...}', which should catch all uncaught
>    exceptions.  */
