OSDN Git Service

PR c/14765
[pf3gnuchains/gcc-fork.git] / gcc / c-parse.in
index bb9cc1a..b89c19d 100644 (file)
@@ -1,6 +1,6 @@
 /* YACC parser for C syntax and for Objective C.  -*-c-*-
-   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -20,17 +20,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
 /* This file defines the grammar of C and that of Objective C.
-   ifobjc ... end ifobjc  conditionals contain code for Objective C only.
-   ifc ... end ifc  conditionals contain code for C only.
+   @@ifobjc ... @@end_ifobjc  conditionals contain code for Objective C only.
+   @@ifc ... @@end_ifc  conditionals contain code for C only.
    Sed commands in Makefile.in are used to convert this file into
    c-parse.y and into objc-parse.y.  */
 
 /* To whomever it may concern: I have heard that such a thing was once
    written by AT&T, but I have never seen it.  */
 
-ifc
+@@ifc
 %expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts.  */
-end ifc
+@@end_ifc
 
 %{
 #include "config.h"
@@ -38,6 +38,7 @@ end ifc
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "langhooks.h"
 #include "input.h"
 #include "cpplib.h"
 #include "intl.h"
@@ -50,9 +51,9 @@ end ifc
 #include "toplev.h"
 #include "ggc.h"
 
-ifobjc
+@@ifobjc
 #include "objc-act.h"
-end ifobjc
+@@end_ifobjc
 
 /* Like YYERROR but do call yyerror.  */
 #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
@@ -145,7 +146,7 @@ do {                                                                        \
 %token ATTRIBUTE EXTENSION LABEL
 %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
 %token PTR_VALUE PTR_BASE PTR_EXTENT
-%token FUNC_NAME
+%token FUNC_NAME OFFSETOF
 
 /* Add precedence rules to solve dangling else s/r conflict */
 %nonassoc IF
@@ -175,6 +176,7 @@ do {                                                                        \
    Objective C, so that the token codes are the same in both.  */
 %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
 %token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+%token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
 %token OBJC_STRING
 
 %type <code> unop
@@ -197,16 +199,17 @@ do {                                                                      \
 %type <ttype> maybe_type_quals_attrs typespec_nonattr typespec_attr
 %type <ttype> typespec_reserved_nonattr typespec_reserved_attr
 %type <ttype> typespec_nonreserved_nonattr
+%type <ttype> offsetof_member_designator
 
-%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_type_qual
-%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
-%type <ttype> init maybeasm
+%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile
+%type <ttype> initdecls notype_initdecls initdcl notype_initdcl init
+%type <ttype> simple_asm_expr maybeasm asm_stmt asm_argument
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
-%type <ttype> any_word extension
+%type <ttype> any_word
 
 %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
-%type <ttype> do_stmt_start poplevel stmt label
+%type <ttype> do_stmt_start pop_scope stmt label
 
 %type <ttype> c99_block_start c99_block_end
 %type <ttype> declarator
@@ -229,11 +232,11 @@ do {                                                                      \
 %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
 %type <ttype> identifiers_or_typenames
 
-%type <itype> setspecs setspecs_fp
+%type <itype> setspecs setspecs_fp extension
 
 %type <location> save_location
 \f
-ifobjc
+@@ifobjc
 /* the Objective-C nonterminals */
 
 %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
@@ -245,7 +248,10 @@ ifobjc
 %type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
 
 %type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
-end ifobjc
+
+%type <ttype> superclass
+%type <itype> objc_try_catch_stmt objc_finally_block
+@@end_ifobjc
 \f
 %{
 /* Number of statements (loosely speaking) and compound statements
@@ -291,22 +297,21 @@ static GTY(()) tree declspec_stack;
 
 /* For __extension__, save/restore the warning flags which are
    controlled by __extension__.  */
-#define SAVE_EXT_FLAGS()                       \
-       size_int (pedantic                      \
-                 | (warn_pointer_arith << 1)   \
-                 | (warn_traditional << 2)     \
-                 | (flag_iso << 3))
+#define SAVE_EXT_FLAGS()               \
+       (pedantic                       \
+        | (warn_pointer_arith << 1)    \
+        | (warn_traditional << 2)      \
+        | (flag_iso << 3))
 
-#define RESTORE_EXT_FLAGS(tval)                        \
+#define RESTORE_EXT_FLAGS(val)                 \
   do {                                         \
-    int val = tree_low_cst (tval, 0);          \
     pedantic = val & 1;                                \
     warn_pointer_arith = (val >> 1) & 1;       \
     warn_traditional = (val >> 2) & 1;         \
     flag_iso = (val >> 3) & 1;                 \
   } while (0)
 
-ifobjc
+@@ifobjc
 /* Objective-C specific parser/lexer information */
 
 static enum tree_code objc_inherit_code;
@@ -318,13 +323,11 @@ static int objc_pq_context = 0, objc_public_flag = 0;
    exists.  */
 static int objc_need_raw_identifier;
 #define OBJC_NEED_RAW_IDENTIFIER(VAL)  objc_need_raw_identifier = VAL
-end ifobjc
+@@end_ifobjc
 
-ifc
+@@ifc
 #define OBJC_NEED_RAW_IDENTIFIER(VAL)  /* nothing */
-end ifc
-
-static bool parsing_iso_function_signature;
+@@end_ifc
 
 /* Tell yyparse how to print a token's value, if yydebug is set.  */
 
@@ -364,26 +367,14 @@ extdefs:
        ;
 
 extdef:
-       extdef_1
-       { parsing_iso_function_signature = false; } /* Reset after any external definition.  */
-       ;
-
-extdef_1:
        fndef
        | datadef
-ifobjc
-       | objcdef
-end ifobjc
-       | ASM_KEYWORD '(' expr ')' ';'
-               { STRIP_NOPS ($3);
-                 if ((TREE_CODE ($3) == ADDR_EXPR
-                      && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
-                     || TREE_CODE ($3) == STRING_CST)
-                   assemble_asm ($3);
-                 else
-                   error ("argument of `asm' is not a constant string"); }
+       | asmdef
        | extension extdef
                { RESTORE_EXT_FLAGS ($1); }
+@@ifobjc
+       | objcdef
+@@end_ifobjc
        ;
 
 datadef:
@@ -452,10 +443,10 @@ fndef:
 identifier:
        IDENTIFIER
        | TYPENAME
-ifobjc
+@@ifobjc
        | OBJECTNAME
        | CLASSNAME
-end ifobjc
+@@end_ifobjc
        ;
 
 unop:     '&'
@@ -464,10 +455,10 @@ unop:     '&'
                { $$ = NEGATE_EXPR; }
        | '+'
                { $$ = CONVERT_EXPR;
-ifc
+@@ifc
   if (warn_traditional && !in_system_header)
     warning ("traditional C rejects the unary plus operator");
-end ifc
+@@end_ifc
                }
        | PLUSPLUS
                { $$ = PREINCREMENT_EXPR; }
@@ -576,21 +567,21 @@ expr_no_commas:
        | expr_no_commas '^' expr_no_commas
                { $$ = parser_build_binary_op ($2, $1, $3); }
        | expr_no_commas ANDAND
-               { $1 = c_common_truthvalue_conversion
+               { $1 = lang_hooks.truthvalue_conversion
                    (default_conversion ($1));
                  skip_evaluation += $1 == truthvalue_false_node; }
          expr_no_commas
                { skip_evaluation -= $1 == truthvalue_false_node;
                  $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); }
        | expr_no_commas OROR
-               { $1 = c_common_truthvalue_conversion
+               { $1 = lang_hooks.truthvalue_conversion
                    (default_conversion ($1));
                  skip_evaluation += $1 == truthvalue_true_node; }
          expr_no_commas
                { skip_evaluation -= $1 == truthvalue_true_node;
                  $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); }
        | expr_no_commas '?'
-               { $1 = c_common_truthvalue_conversion
+               { $1 = lang_hooks.truthvalue_conversion
                    (default_conversion ($1));
                  skip_evaluation += $1 == truthvalue_false_node; }
           expr ':'
@@ -603,9 +594,8 @@ expr_no_commas:
                { if (pedantic)
                    pedwarn ("ISO C forbids omitting the middle term of a ?: expression");
                  /* Make sure first operand is calculated only once.  */
-                 $<ttype>2 = save_expr ($1);
-                 $1 = c_common_truthvalue_conversion
-                   (default_conversion ($<ttype>2));
+                 $<ttype>2 = save_expr (default_conversion ($1));
+                 $1 = lang_hooks.truthvalue_conversion ($<ttype>2);
                  skip_evaluation += $1 == truthvalue_true_node; }
          ':' expr_no_commas
                { skip_evaluation -= $1 == truthvalue_true_node;
@@ -649,7 +639,7 @@ primary:
                  finish_init ();
 
                  if (pedantic && ! flag_isoc99)
-                   pedwarn ("ISO C89 forbids compound literals");
+                   pedwarn ("ISO C90 forbids compound literals");
                  $$ = build_compound_literal (type, constructor);
                }
        | '(' expr ')'
@@ -672,6 +662,7 @@ primary:
                    last_expr_type = void_type_node;
                  $$ = build1 (STMT_EXPR, last_expr_type, $1);
                  TREE_SIDE_EFFECTS ($$) = 1;
+                 annotate_with_locus ($$, input_location);
                }
        | compstmt_primary_start error ')'
                {
@@ -684,17 +675,25 @@ primary:
        | VA_ARG '(' expr_no_commas ',' typename ')'
                { $$ = build_va_arg ($3, groktypename ($5)); }
 
-      | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' expr_no_commas ')'
+       | OFFSETOF '(' typename ',' offsetof_member_designator ')'
+               { $$ = build_offsetof (groktypename ($3), $5); }
+       | OFFSETOF '(' error ')'
+               { $$ = error_mark_node; }
+       | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ','
+                         expr_no_commas ')'
                {
                   tree c;
 
                   c = fold ($3);
                   STRIP_NOPS (c);
                   if (TREE_CODE (c) != INTEGER_CST)
-                    error ("first argument to __builtin_choose_expr not a constant");
+                    error ("first argument to __builtin_choose_expr not"
+                          " a constant");
                   $$ = integer_zerop (c) ? $7 : $5;
                }
-      | TYPES_COMPATIBLE_P '(' typename ',' typename ')'
+       | CHOOSE_EXPR '(' error ')'
+               { $$ = error_mark_node; }
+       | TYPES_COMPATIBLE_P '(' typename ',' typename ')'
                {
                  tree e1, e2;
 
@@ -704,33 +703,22 @@ primary:
                  $$ = comptypes (e1, e2, COMPARE_STRICT)
                    ? build_int_2 (1, 0) : build_int_2 (0, 0);
                }
+       | TYPES_COMPATIBLE_P '(' error ')'
+               { $$ = error_mark_node; }
        | primary '[' expr ']'   %prec '.'
                { $$ = build_array_ref ($1, $3); }
        | primary '.' identifier
-               {
-ifobjc
-                   if (!is_public ($1, $3))
-                     $$ = error_mark_node;
-                   else
-end ifobjc
-                     $$ = build_component_ref ($1, $3);
-               }
+               { $$ = build_component_ref ($1, $3); }
        | primary POINTSAT identifier
                {
                   tree expr = build_indirect_ref ($1, "->");
-
-ifobjc
-                     if (!is_public (expr, $3))
-                       $$ = error_mark_node;
-                     else
-end ifobjc
-                       $$ = build_component_ref (expr, $3);
+                 $$ = build_component_ref (expr, $3);
                }
        | primary PLUSPLUS
                { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
        | primary MINUSMINUS
                { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
-ifobjc
+@@ifobjc
        | objcmessageexpr
                { $$ = build_message_expr ($1); }
        | objcselectorexpr
@@ -741,32 +729,27 @@ ifobjc
                { $$ = build_encode_expr ($1); }
        | OBJC_STRING
                { $$ = build_objc_string_object ($1); }
-end ifobjc
+@@end_ifobjc
        ;
 
-old_style_parm_decls:
-       old_style_parm_decls_1
-       {
-         parsing_iso_function_signature = false; /* Reset after decls.  */
-       }
+/* This is the second argument to __builtin_offsetof.  We must have one
+   identifier, and beyond that we want to accept sub structure and sub
+   array references.  We return tree list where each element has
+   PURPOSE set for component refs or VALUE set for array refs.  We'll
+   turn this into something real inside build_offsetof.  */
+
+offsetof_member_designator:
+         identifier
+               { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); }
+       | offsetof_member_designator '.' identifier
+               { $$ = tree_cons ($3, NULL_TREE, $1); }
+       | offsetof_member_designator '[' expr ']'
+               { $$ = tree_cons (NULL_TREE, $3, $1); }
        ;
 
-old_style_parm_decls_1:
+old_style_parm_decls:
        /* empty */
-       {
-         if (warn_traditional && !in_system_header
-             && parsing_iso_function_signature)
-           warning ("traditional C rejects ISO C style function definitions");
-         if (warn_old_style_definition && !in_system_header
-             && !parsing_iso_function_signature)
-           warning ("old-style parameter declaration");
-         parsing_iso_function_signature = false; /* Reset after warning.  */
-       }
        | datadecls
-       {
-         if (warn_old_style_definition && !in_system_header)
-           warning ("old-style parameter declaration");
-       }
        ;
 
 /* The following are analogous to lineno_decl, decls and decl
@@ -1356,7 +1339,7 @@ typespec_nonreserved_nonattr:
                { /* For a typedef name, record the meaning, not the name.
                     In case of `foo foo, bar;'.  */
                  $$ = lookup_name ($1); }
-ifobjc
+@@ifobjc
        | CLASSNAME protocolrefs
                { $$ = get_static_reference ($1, $2); }
        | OBJECTNAME protocolrefs
@@ -1366,9 +1349,13 @@ ifobjc
    - nisse@lysator.liu.se */
         | non_empty_protocolrefs
                 { $$ = get_object_reference ($1); }
-end ifobjc
+@@end_ifobjc
        | typeof '(' expr ')'
-               { skip_evaluation--; $$ = TREE_TYPE ($3); }
+               { skip_evaluation--;
+                 if (TREE_CODE ($3) == COMPONENT_REF
+                     && DECL_C_BIT_FIELD (TREE_OPERAND ($3, 1)))
+                   error ("`typeof' applied to a bit-field");
+                 $$ = TREE_TYPE ($3); }
        | typeof '(' typename ')'
                { skip_evaluation--; $$ = groktypename ($3); }
        ;
@@ -1385,13 +1372,6 @@ notype_initdecls:
        | notype_initdecls ',' maybe_resetattrs notype_initdcl
        ;
 
-maybeasm:
-         /* empty */
-               { $$ = NULL_TREE; }
-       | ASM_KEYWORD '(' STRING ')'
-               { $$ = $3; }
-       ;
-
 initdcl:
          declarator maybeasm maybe_attribute '='
                { $<ttype>$ = start_decl ($1, current_declspecs, 1,
@@ -1439,8 +1419,11 @@ attributes:
        ;
 
 attribute:
-      ATTRIBUTE '(' '(' attribute_list ')' ')'
-               { $$ = $4; }
+      ATTRIBUTE stop_string_translation
+                '(' '(' attribute_list ')' ')' start_string_translation
+               { $$ = $5; }
+      | ATTRIBUTE error start_string_translation
+                {}
        ;
 
 attribute_list:
@@ -1508,7 +1491,7 @@ initlist1:
 initelt:
          designator_list '=' initval
                { if (pedantic && ! flag_isoc99)
-                   pedwarn ("ISO C89 forbids specifying subobject to initialize"); }
+                   pedwarn ("ISO C90 forbids specifying subobject to initialize"); }
        | designator initval
                { if (pedantic)
                    pedwarn ("obsolete use of designated initializer without `='"); }
@@ -1559,7 +1542,6 @@ nested_function:
                      pop_function_context ();
                      YYERROR1;
                    }
-                 parsing_iso_function_signature = false; /* Don't warn about nested functions.  */
                }
           old_style_parm_decls save_location
                { tree decl = current_function_decl;
@@ -1590,7 +1572,6 @@ notype_nested_function:
                      pop_function_context ();
                      YYERROR1;
                    }
-                 parsing_iso_function_signature = false; /* Don't warn about nested functions.  */
                }
          old_style_parm_decls save_location
                { tree decl = current_function_decl;
@@ -1624,17 +1605,14 @@ after_type_declarator:
                { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
        | after_type_declarator '(' parmlist_or_identifiers  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-/*     | after_type_declarator '(' error ')'  %prec '.'
-               { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
-                 poplevel (0, 0, 0); }  */
        | after_type_declarator array_declarator  %prec '.'
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | '*' maybe_type_quals_attrs after_type_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
        | TYPENAME
-ifobjc
+@@ifobjc
        | OBJECTNAME
-end ifobjc
+@@end_ifobjc
        ;
 
 /* Kinds of declarator that can appear in a parameter list
@@ -1649,23 +1627,17 @@ parm_declarator:
 parm_declarator_starttypename:
          parm_declarator_starttypename '(' parmlist_or_identifiers  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-/*     | parm_declarator_starttypename '(' error ')'  %prec '.'
-               { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
-                 poplevel (0, 0, 0); }  */
        | parm_declarator_starttypename array_declarator  %prec '.'
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | TYPENAME
-ifobjc
+@@ifobjc
        | OBJECTNAME
-end ifobjc
+@@end_ifobjc
        ;
 
 parm_declarator_nostarttypename:
          parm_declarator_nostarttypename '(' parmlist_or_identifiers  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-/*     | parm_declarator_nostarttypename '(' error ')'  %prec '.'
-               { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
-                 poplevel (0, 0, 0); }  */
        | parm_declarator_nostarttypename array_declarator  %prec '.'
                { $$ = set_array_declarator_type ($2, $1, 0); }
        | '*' maybe_type_quals_attrs parm_declarator_starttypename  %prec UNARY
@@ -1682,9 +1654,6 @@ parm_declarator_nostarttypename:
 notype_declarator:
          notype_declarator '(' parmlist_or_identifiers  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-/*     | notype_declarator '(' error ')'  %prec '.'
-               { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
-                 poplevel (0, 0, 0); }  */
        | '(' maybe_attribute notype_declarator ')'
                { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; }
        | '*' maybe_type_quals_attrs notype_declarator  %prec UNARY
@@ -1806,22 +1775,11 @@ component_decl_list2:   /* empty */
        | component_decl_list2 ';'
                { if (pedantic)
                    pedwarn ("extra semicolon in struct or union specified"); }
-ifobjc
+@@ifobjc
        /* foo(sizeof(struct{ @defs(ClassName)})); */
        | DEFS '(' CLASSNAME ')'
-               {
-                 tree interface = lookup_interface ($3);
-
-                 if (interface)
-                   $$ = nreverse (get_class_ivars (interface));
-                 else
-                   {
-                     error ("cannot find interface declaration for `%s'",
-                            IDENTIFIER_POINTER ($3));
-                     $$ = NULL_TREE;
-                   }
-               }
-end ifobjc
+               { $$ = nreverse (get_class_ivars_from_name ($3)); }
+@@end_ifobjc
        ;
 
 component_decl:
@@ -1980,16 +1938,16 @@ direct_absdcl1:
 /* The [...] part of a declarator for an array type.  */
 
 array_declarator:
-       '[' maybe_type_quals_attrs expr ']'
+       '[' maybe_type_quals_attrs expr_no_commas ']'
                { $$ = build_array_declarator ($3, $2, 0, 0); }
        | '[' maybe_type_quals_attrs ']'
                { $$ = build_array_declarator (NULL_TREE, $2, 0, 0); }
        | '[' maybe_type_quals_attrs '*' ']'
                { $$ = build_array_declarator (NULL_TREE, $2, 0, 1); }
-       | '[' STATIC maybe_type_quals_attrs expr ']'
+       | '[' STATIC maybe_type_quals_attrs expr_no_commas ']'
                { $$ = build_array_declarator ($4, $3, 1, 0); }
        /* declspecs_nosc_nots is a synonym for type_quals_attrs.  */
-       | '[' declspecs_nosc_nots STATIC expr ']'
+       | '[' declspecs_nosc_nots STATIC expr_no_commas ']'
                { $$ = build_array_declarator ($4, $2, 1, 0); }
        ;
 
@@ -2004,7 +1962,7 @@ stmts_and_decls:
        | lineno_stmt_decl_or_labels_ending_decl
        | lineno_stmt_decl_or_labels_ending_label
                {
-                 pedwarn ("deprecated use of label at end of compound statement");
+                 error ("label at end of compound statement");
                }
        | lineno_stmt_decl_or_labels_ending_error
        ;
@@ -2052,19 +2010,21 @@ lineno_stmt_decl_or_labels:
 errstmt:  error ';'
        ;
 
-pushlevel:  /* empty */
-               { pushlevel (0);
+push_scope:  /* empty */
+               { push_scope ();
                  clear_last_expr ();
                  add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
-ifobjc
-                 if (objc_method_context)
-                   add_objc_decls ();
-end ifobjc
                }
        ;
 
-poplevel:  /* empty */
-                { $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
+pop_scope:  /* empty */
+                {
+@@ifobjc
+                 if (c_dialect_objc ())
+                   objc_clear_super_receiver ();
+@@end_ifobjc
+                 $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+               }
         ;
 
 /* Start and end blocks created for the new scopes of C99.  */
@@ -2072,13 +2032,9 @@ c99_block_start: /* empty */
                { if (flag_isoc99)
                    {
                      $$ = c_begin_compound_stmt ();
-                     pushlevel (0);
+                     push_scope ();
                      clear_last_expr ();
                      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
-ifobjc
-                     if (objc_method_context)
-                       add_objc_decls ();
-end ifobjc
                    }
                  else
                    $$ = NULL_TREE;
@@ -2092,7 +2048,7 @@ c99_block_end: /* empty */
                 { if (flag_isoc99)
                    {
                      tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
-                     $$ = poplevel (KEEP_MAYBE, 0, 0);
+                     $$ = pop_scope ();
                      SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
                        = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
                        = $$;
@@ -2141,8 +2097,8 @@ compstmt_start: '{' { compstmt_count++;
 
 compstmt_nostart: '}'
                { $$ = convert (void_type_node, integer_zero_node); }
-       | pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
-               { $$ = poplevel (KEEP_MAYBE, 0, 0);
+       | push_scope maybe_label_decls compstmt_contents_nonempty '}' pop_scope
+               { $$ = pop_scope ();
                  SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
                    = SCOPE_STMT_BLOCK (TREE_VALUE ($5))
                    = $$; }
@@ -2167,6 +2123,7 @@ compstmt_primary_start:
                  keep_next_level ();
                  compstmt_count++;
                  $$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree));
+                 last_expr_type = NULL_TREE;
                }
         ;
 
@@ -2188,7 +2145,7 @@ simple_if:
 
 if_prefix:
          /* We must build the IF_STMT node before parsing its
-            condition so that STMT_LINENO refers to the line
+            condition so that EXPR_LOCUS refers to the line
             containing the "if", and not the line containing
             the close-parenthesis.
 
@@ -2198,7 +2155,7 @@ if_prefix:
           IF
                 { $<ttype>$ = c_begin_if_stmt (); }
             '(' expr ')'
-               { c_expand_start_cond (c_common_truthvalue_conversion ($4),
+               { c_expand_start_cond (lang_hooks.truthvalue_conversion ($4),
                                       compstmt_count,$<ttype>2);
                  $<itype>$ = stmt_count;
                  if_stmt_locus = $<location>-1; }
@@ -2211,6 +2168,7 @@ do_stmt_start:
          DO
                { stmt_count++;
                  compstmt_count++;
+                 c_in_iteration_stmt++;
                  $<ttype>$
                    = add_stmt (build_stmt (DO_STMT, NULL_TREE,
                                            NULL_TREE));
@@ -2221,7 +2179,8 @@ do_stmt_start:
                  DO_COND ($<ttype>$) = error_mark_node; }
          c99_block_lineno_labeled_stmt WHILE
                { $$ = $<ttype>2;
-                 RECHAIN_STMTS ($$, DO_BODY ($$)); }
+                 RECHAIN_STMTS ($$, DO_BODY ($$));
+                 c_in_iteration_stmt--; }
        ;
 
 /* The forced readahead in here is because we might be at the end of a
@@ -2250,12 +2209,8 @@ lineno_stmt:
          save_location stmt
                { if ($2)
                    {
-                     STMT_LINENO ($2) = $1.line;
-                     /* ??? We currently have no way of recording
-                        the filename for a statement.  This probably
-                        matters little in practice at the moment,
-                        but I suspect that problems will occur when
-                        doing inlining at the tree level.  */
+                     SET_EXPR_LOCUS ($2, NULL);
+                     annotate_with_locus ($2, $1);
                    }
                }
        ;
@@ -2264,7 +2219,8 @@ lineno_label:
          save_location label
                { if ($2)
                    {
-                     STMT_LINENO ($2) = $1.line;
+                     SET_EXPR_LOCUS ($2, NULL);
+                     annotate_with_locus ($2, $1);
                    }
                }
        ;
@@ -2293,7 +2249,7 @@ select_or_iter_stmt:
        | simple_if ELSE error
                { c_expand_end_cond (); }
        /* We must build the WHILE_STMT node before parsing its
-         condition so that STMT_LINENO refers to the line
+         condition so that EXPR_LOCUS refers to the line
          containing the "while", and not the line containing
          the close-parenthesis.
 
@@ -2304,15 +2260,17 @@ select_or_iter_stmt:
                 { stmt_count++;
                  $<ttype>$ = c_begin_while_stmt (); }
          '(' expr ')'
-                { $4 = c_common_truthvalue_conversion ($4);
+                { c_in_iteration_stmt++;
+                 $4 = lang_hooks.truthvalue_conversion ($4);
                  c_finish_while_stmt_cond
-                   (c_common_truthvalue_conversion ($4), $<ttype>2);
+                   (lang_hooks.truthvalue_conversion ($4), $<ttype>2);
                  $<ttype>$ = add_stmt ($<ttype>2); }
          c99_block_lineno_labeled_stmt
-               { RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
+                { c_in_iteration_stmt--;
+                 RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
        | do_stmt_start
          '(' expr ')' ';'
-                { DO_COND ($1) = c_common_truthvalue_conversion ($3); }
+                { DO_COND ($1) = lang_hooks.truthvalue_conversion ($3); }
        | do_stmt_start error
                { }
        | FOR
@@ -2325,16 +2283,20 @@ select_or_iter_stmt:
          xexpr ';'
                 { if ($6)
                    FOR_COND ($<ttype>2)
-                     = c_common_truthvalue_conversion ($6); }
+                     = lang_hooks.truthvalue_conversion ($6); }
          xexpr ')'
-               { FOR_EXPR ($<ttype>2) = $9; }
+                { c_in_iteration_stmt++;
+                 FOR_EXPR ($<ttype>2) = $9; }
          c99_block_lineno_labeled_stmt
-                { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2)); }
+                { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2));
+                 c_in_iteration_stmt--;}
        | SWITCH '(' expr ')'
                { stmt_count++;
-                 $<ttype>$ = c_start_case ($3); }
+                 $<ttype>$ = c_start_case ($3);
+                 c_in_case_stmt++; }
          c99_block_lineno_labeled_stmt
-                { c_finish_case (); }
+                { c_finish_case ();
+                 c_in_case_stmt--; }
        ;
 
 for_init_stmt:
@@ -2344,6 +2306,12 @@ for_init_stmt:
                { check_for_loop_decls (); }
        ;
 
+xexpr:
+       /* empty */
+               { $$ = NULL_TREE; }
+       | expr
+       ;
+
 /* Parse a single real statement, not including any labels.  */
 stmt:
          compstmt
@@ -2357,9 +2325,21 @@ stmt:
                  $$ = NULL_TREE; }
        | BREAK ';'
                { stmt_count++;
+               if (!(c_in_iteration_stmt || c_in_case_stmt))
+                 {
+                   error ("break statement not within loop or switch");
+                   $$ = NULL_TREE;
+                 }
+               else
                  $$ = add_stmt (build_break_stmt ()); }
        | CONTINUE ';'
                 { stmt_count++;
+               if (!c_in_iteration_stmt)
+                 {
+                   error ("continue statement not within a loop");
+                   $$ = NULL_TREE;
+                 }
+               else
                  $$ = add_stmt (build_continue_stmt ()); }
        | RETURN ';'
                 { stmt_count++;
@@ -2367,23 +2347,7 @@ stmt:
        | RETURN expr ';'
                 { stmt_count++;
                  $$ = c_expand_return ($2); }
-       | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
-               { stmt_count++;
-                 $$ = simple_asm_stmt ($4); }
-       /* This is the case with just output operands.  */
-       | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
-               { stmt_count++;
-                 $$ = build_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
-       /* This is the case with input operands as well.  */
-       | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
-         asm_operands ')' ';'
-               { stmt_count++;
-                 $$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
-       /* This is the case with clobbered registers as well.  */
-       | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
-         asm_operands ':' asm_clobbers ')' ';'
-               { stmt_count++;
-                 $$ = build_asm_stmt ($2, $4, $6, $8, $10); }
+       | asm_stmt
        | GOTO identifier ';'
                { tree decl;
                  stmt_count++;
@@ -2404,6 +2368,59 @@ stmt:
                  $$ = add_stmt (build_stmt (GOTO_STMT, $3)); }
        | ';'
                { $$ = NULL_TREE; }
+@@ifobjc
+       | AT_THROW expr ';'
+               { stmt_count++;
+                 $$ = objc_build_throw_stmt ($2);
+               }
+       | AT_THROW ';'
+               { stmt_count++;
+                 $$ = objc_build_throw_stmt (NULL_TREE);
+               }
+       | objc_try_catch_stmt
+               { objc_build_finally_prologue (); }
+         objc_finally_block
+               { $$ = objc_build_try_catch_finally_stmt ($1, $3); }
+       | AT_SYNCHRONIZED '(' expr ')'
+               { objc_build_synchronized_prologue ($3); }
+         compstmt
+               { $$ = objc_build_synchronized_epilogue (); }
+       ;
+
+objc_try_catch_stmt:
+         objc_try_stmt
+               { objc_build_try_epilogue (1); }
+         objc_catch_list
+               { objc_build_catch_epilogue (); $$ = 1; }
+       | objc_try_stmt
+               { objc_build_try_epilogue (0); $$ = 0; }
+       ;
+
+
+objc_try_stmt:
+         AT_TRY
+               { objc_build_try_prologue (); }
+         compstmt
+       ;
+
+objc_catch_list:
+         objc_catch_list objc_catch_block
+       | objc_catch_block
+       ;
+
+objc_catch_block:
+         AT_CATCH '(' parm ')'
+               { objc_build_catch_stmt ($3); }
+         compstmt
+               { stmt_count++; }
+       ;
+
+objc_finally_block:
+         AT_FINALLY compstmt
+           { $$ = 1; }
+       | /* NULL */
+           { $$ = 0; }
+@@end_ifobjc
        ;
 
 /* Any kind of label, including jump labels and case labels.
@@ -2432,20 +2449,69 @@ label:    CASE expr_no_commas ':'
                }
        ;
 
-/* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
+/* Asm expressions and statements */
 
-maybe_type_qual:
-       /* empty */
-               { emit_line_note (input_location);
-                 $$ = NULL_TREE; }
-       | TYPE_QUAL
-               { emit_line_note (input_location); }
+/* simple_asm_expr is used in restricted contexts, where a full
+   expression with inputs and outputs does not make sense.  */
+simple_asm_expr:
+       ASM_KEYWORD stop_string_translation
+             '(' STRING ')' start_string_translation
+               { $$ = $4; }
        ;
 
-xexpr:
-       /* empty */
+/* maybeasm: used for assembly names for declarations */
+maybeasm:
+         /* empty */
                { $$ = NULL_TREE; }
-       | expr
+       | simple_asm_expr
+       ;
+
+/* asmdef: asm() outside a function body.  */
+asmdef:
+       simple_asm_expr ';'
+               { assemble_asm ($1); }
+        | ASM_KEYWORD error start_string_translation ';'
+                {}
+       ;
+
+/* Full-blown asm statement with inputs, outputs, clobbers, and
+   volatile tag allowed.  */
+asm_stmt:
+       ASM_KEYWORD maybe_volatile stop_string_translation
+               '(' asm_argument ')' start_string_translation ';'
+               { stmt_count++;
+                 $$ = build_asm_stmt ($2, $5); }
+       ;
+
+asm_argument:
+       /* no operands */
+       STRING
+               { $$ = build_asm_expr ($1, 0, 0, 0, true); }
+       /* output operands */
+       | STRING ':' asm_operands
+               { $$ = build_asm_expr ($1, $3, 0, 0, false); }
+       /* output and input operands */
+       | STRING ':' asm_operands ':' asm_operands
+               { $$ = build_asm_expr ($1, $3, $5, 0, false); }
+       /* output and input operands and clobbers */
+       | STRING ':' asm_operands ':' asm_operands ':' asm_clobbers
+               { $$ = build_asm_expr ($1, $3, $5, $7, false); }
+       ;
+
+/* Either 'volatile' or nothing.  First thing in an `asm' statement.  */
+
+maybe_volatile:
+       /* empty */
+               { $$ = 0; }
+       | TYPE_QUAL
+               { if ($1 != ridpointers[RID_VOLATILE])
+                   {
+                     warning ("%E qualifier ignored on asm", $1);
+                     $$ = 0;
+                   }
+                 else
+                   $$ = $1;
+               }
        ;
 
 /* These are the operands other than the first string and colon
@@ -2462,12 +2528,13 @@ nonnull_asm_operands:
        ;
 
 asm_operand:
-         STRING '(' expr ')'
-               { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $3); }
-       | '[' identifier ']' STRING '(' expr ')'
+         STRING start_string_translation '(' expr ')' stop_string_translation
+               { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $4); }
+       | '[' identifier ']' STRING start_string_translation
+         '(' expr ')' stop_string_translation
                { $2 = build_string (IDENTIFIER_LENGTH ($2),
                                     IDENTIFIER_POINTER ($2));
-                 $$ = build_tree_list (build_tree_list ($2, $4), $6); }
+                 $$ = build_tree_list (build_tree_list ($2, $4), $7); }
        ;
 
 asm_clobbers:
@@ -2476,6 +2543,15 @@ asm_clobbers:
        | asm_clobbers ',' STRING
                { $$ = tree_cons (NULL_TREE, $3, $1); }
        ;
+
+stop_string_translation:
+        { c_lex_string_translate = false; }
+        ;
+
+start_string_translation:
+        { c_lex_string_translate = true; }
+        ;
+
 \f
 /* This is what appears inside the parens in a function declarator.
    Its value is a list of ..._TYPE nodes.  Attributes must appear here
@@ -2484,11 +2560,11 @@ asm_clobbers:
    "void bar (int (__attribute__((__mode__(SI))) int foo));".  */
 parmlist:
          maybe_attribute
-               { pushlevel (0);
+               { push_scope ();
                  declare_parm_level (); }
          parmlist_1
                { $$ = $3;
-                 poplevel (0, 0, 0); }
+                 pop_scope (); }
        ;
 
 parmlist_1:
@@ -2501,29 +2577,23 @@ parmlist_1:
          parmlist_1
                { $$ = $6; }
        | error ')'
-               { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
+               { $$ = make_node (TREE_LIST); }
        ;
 
 /* This is what appears inside the parens in a function declarator.
    Is value is represented in the format that grokdeclarator expects.  */
 parmlist_2:  /* empty */
-               { $$ = get_parm_info (0); }
+               { $$ = make_node (TREE_LIST); }
        | ELLIPSIS
-               { $$ = get_parm_info (0);
-                 /* Gcc used to allow this as an extension.  However, it does
-                    not work for all targets, and thus has been disabled.
-                    Also, since func (...) and func () are indistinguishable,
-                    it caused problems with the code in expand_builtin which
-                    tries to verify that BUILT_IN_NEXT_ARG is being used
-                    correctly.  */
+               { $$ = make_node (TREE_LIST); 
+                 /* Suppress -Wold-style-definition for this case.  */
+                 TREE_CHAIN ($$) = error_mark_node;
                  error ("ISO C requires a named argument before `...'");
                }
        | parms
-               { $$ = get_parm_info (1);
-                 parsing_iso_function_signature = true;
-               }
+               { $$ = get_parm_info (/*ellipsis=*/false); }
        | parms ',' ELLIPSIS
-               { $$ = get_parm_info (0); }
+               { $$ = get_parm_info (/*ellipsis=*/true); }
        ;
 
 parms:
@@ -2598,11 +2668,11 @@ setspecs_fp:
    Its value is a list of ..._TYPE nodes or a list of identifiers.  */
 parmlist_or_identifiers:
          maybe_attribute
-               { pushlevel (0);
+               { push_scope ();
                  declare_parm_level (); }
          parmlist_or_identifiers_1
                { $$ = $3;
-                 poplevel (0, 0, 0); }
+                 pop_scope (); }
        ;
 
 parmlist_or_identifiers_1:
@@ -2648,7 +2718,7 @@ extension:
                  flag_iso = 0; }
        ;
 \f
-ifobjc
+@@ifobjc
 /* Objective-C productions.  */
 
 objcdef:
@@ -2692,115 +2762,52 @@ aliasdecl:
                }
        ;
 
-classdef:
-         INTERFACE identifier protocolrefs '{'
-               {
-                 objc_interface_context = objc_ivar_context
-                   = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
-                  objc_public_flag = 0;
-               }
-         ivar_decl_list '}'
-               {
-                  continue_class (objc_interface_context);
-               }
-         methodprotolist
-         END
-               {
-                 finish_class (objc_interface_context);
-                 objc_interface_context = NULL_TREE;
-               }
+superclass:
+         ':' identifier { $$ = $2; }
+       | /* NULL */ %prec HYPERUNARY    { $$ = NULL_TREE; }
+       ;
 
-       | INTERFACE identifier protocolrefs
-               {
-                 objc_interface_context
-                   = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
-                  continue_class (objc_interface_context);
-               }
-         methodprotolist
-         END
-               {
-                 finish_class (objc_interface_context);
-                 objc_interface_context = NULL_TREE;
-               }
+class_ivars:
+         '{' ivar_decl_list '}'
+       | /* NULL */
+       ;
 
-       | INTERFACE identifier ':' identifier protocolrefs '{'
+classdef:
+         INTERFACE identifier superclass protocolrefs
                {
                  objc_interface_context = objc_ivar_context
-                   = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
+                   = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
                   objc_public_flag = 0;
                }
-         ivar_decl_list '}'
+         class_ivars
                {
                   continue_class (objc_interface_context);
                }
-         methodprotolist
-         END
-               {
-                 finish_class (objc_interface_context);
-                 objc_interface_context = NULL_TREE;
-               }
-
-       | INTERFACE identifier ':' identifier protocolrefs
-               {
-                 objc_interface_context
-                   = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
-                  continue_class (objc_interface_context);
-               }
-         methodprotolist
-         END
+         methodprotolist END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
 
-       | IMPLEMENTATION identifier '{'
-               {
-                 objc_implementation_context = objc_ivar_context
-                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
-                  objc_public_flag = 0;
-               }
-         ivar_decl_list '}'
-               {
-                  objc_ivar_chain
-                   = continue_class (objc_implementation_context);
-               }
-
-       | IMPLEMENTATION identifier
-               {
-                 objc_implementation_context
-                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
-                  objc_ivar_chain
-                   = continue_class (objc_implementation_context);
-               }
-
-       | IMPLEMENTATION identifier ':' identifier '{'
+       | IMPLEMENTATION identifier superclass
                {
                  objc_implementation_context = objc_ivar_context
-                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
+                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE);
                   objc_public_flag = 0;
                }
-         ivar_decl_list '}'
+         class_ivars
                {
                   objc_ivar_chain
                    = continue_class (objc_implementation_context);
                }
 
-       | IMPLEMENTATION identifier ':' identifier
-               {
-                 objc_implementation_context
-                   = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
-                  objc_ivar_chain
-                   = continue_class (objc_implementation_context);
-               }
-
        | INTERFACE identifier '(' identifier ')' protocolrefs
                {
                  objc_interface_context
                    = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
                   continue_class (objc_interface_context);
                }
-         methodprotolist
-         END
+         methodprotolist END
                {
                  finish_class (objc_interface_context);
                  objc_interface_context = NULL_TREE;
@@ -2947,10 +2954,9 @@ methoddef:
          methoddecl
                {
                  objc_pq_context = 0;
-                 if (objc_inherit_code == CLASS_METHOD_DECL)
-                   add_class_method (objc_implementation_context, $3);
-                 else
-                   add_instance_method (objc_implementation_context, $3);
+                 objc_add_method (objc_implementation_context,
+                                  $3,
+                                  objc_inherit_code == CLASS_METHOD_DECL);
                  start_method_def ($3);
                }
          optarglist
@@ -2969,14 +2975,8 @@ methoddef:
 
 methodprotolist:
          /* empty  */
-       | {$<ttype>$ = NULL_TREE; } methodprotolist2
-       ;
-
-methodprotolist2:               /* eliminates a shift/reduce conflict */
-          methodproto
-       |  datadef
-       | methodprotolist2 methodproto
-       | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
+       | methodprotolist methodproto
+       | methodprotolist { $<ttype>$ = NULL_TREE; } datadef
        ;
 
 semi_or_error:
@@ -2994,10 +2994,9 @@ methodproto:
                {
                  /* Forget protocol qualifiers here.  */
                  objc_pq_context = 0;
-                 if (objc_inherit_code == CLASS_METHOD_DECL)
-                   add_class_method (objc_interface_context, $3);
-                 else
-                   add_instance_method (objc_interface_context, $3);
+                 objc_add_method (objc_interface_context,
+                                  $3,
+                                  objc_inherit_code == CLASS_METHOD_DECL);
                }
          semi_or_error
        ;
@@ -3091,13 +3090,13 @@ optparmlist:
                }
        | ','
                {
-                 pushlevel (0);
+                 push_scope ();
                }
          parmlist_2
                {
                  /* returns a tree list node generated by get_parm_info */
                  $$ = $3;
-                 poplevel (0, 0, 0);
+                 pop_scope ();
                }
        ;
 
@@ -3194,6 +3193,10 @@ receiver:
                {
                  $$ = get_class_reference ($1);
                }
+       | TYPENAME
+               {
+                 $$ = get_class_reference ($1);
+               }
        ;
 
 objcmessageexpr:
@@ -3248,7 +3251,7 @@ objcencodeexpr:
                }
        ;
 
-end ifobjc
+@@end_ifobjc
 %%
 
 /* yylex() is a thin wrapper around c_lex(), all it does is translate
@@ -3284,6 +3287,7 @@ static const struct resword reswords[] =
   { "__attribute",     RID_ATTRIBUTE,  0 },
   { "__attribute__",   RID_ATTRIBUTE,  0 },
   { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
+  { "__builtin_offsetof", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
   { "__builtin_va_arg",        RID_VA_ARG,     0 },
   { "__complex",       RID_COMPLEX,    0 },
@@ -3350,7 +3354,7 @@ static const struct resword reswords[] =
   { "void",            RID_VOID,       0 },
   { "volatile",                RID_VOLATILE,   0 },
   { "while",           RID_WHILE,      0 },
-ifobjc
+@@ifobjc
   { "id",              RID_ID,                 D_OBJC },
 
   /* These objc keywords are recognized only immediately after
@@ -3367,7 +3371,11 @@ ifobjc
   { "protocol",                RID_AT_PROTOCOL,        D_OBJC },
   { "public",          RID_AT_PUBLIC,          D_OBJC },
   { "selector",                RID_AT_SELECTOR,        D_OBJC },
-
+  { "throw",           RID_AT_THROW,           D_OBJC },
+  { "try",             RID_AT_TRY,             D_OBJC },
+  { "catch",           RID_AT_CATCH,           D_OBJC },
+  { "finally",         RID_AT_FINALLY,         D_OBJC },
+  { "synchronized",    RID_AT_SYNCHRONIZED,    D_OBJC },
   /* These are recognized only in protocol-qualifier context
      (see above) */
   { "bycopy",          RID_BYCOPY,             D_OBJC },
@@ -3376,7 +3384,7 @@ ifobjc
   { "inout",           RID_INOUT,              D_OBJC },
   { "oneway",          RID_ONEWAY,             D_OBJC },
   { "out",             RID_OUT,                D_OBJC },
-end ifobjc
+@@end_ifobjc
 };
 #define N_reswords (sizeof reswords / sizeof (struct resword))
 
@@ -3476,6 +3484,7 @@ static const short rid_to_yy[RID_MAX] =
   /* RID_FALSE */      0,
   /* RID_NAMESPACE */  0,
   /* RID_NEW */                0,
+  /* RID_OFFSETOF */    OFFSETOF,
   /* RID_OPERATOR */   0,
   /* RID_THIS */       0,
   /* RID_THROW */      0,
@@ -3503,6 +3512,11 @@ static const short rid_to_yy[RID_MAX] =
   /* RID_AT_PUBLIC */          PUBLIC,
   /* RID_AT_PROTOCOL */                PROTOCOL,
   /* RID_AT_SELECTOR */                SELECTOR,
+  /* RID_AT_THROW */           AT_THROW,
+  /* RID_AT_TRY */             AT_TRY,
+  /* RID_AT_CATCH */           AT_CATCH,
+  /* RID_AT_FINALLY */         AT_FINALLY,
+  /* RID_AT_SYNCHRONIZED */    AT_SYNCHRONIZED,
   /* RID_AT_INTERFACE */       INTERFACE,
   /* RID_AT_IMPLEMENTATION */  IMPLEMENTATION
 };
@@ -3538,28 +3552,7 @@ init_reswords (void)
 static void
 yyerror (const char *msgid)
 {
-  const char *string = _(msgid);
-
-  if (last_token == CPP_EOF)
-    error ("%s at end of input", string);
-  else if (last_token == CPP_CHAR || last_token == CPP_WCHAR)
-    {
-      unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
-      const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
-      if (val <= UCHAR_MAX && ISGRAPH (val))
-       error ("%s before %s'%c'", string, ell, val);
-      else
-       error ("%s before %s'\\x%x'", string, ell, val);
-    }
-  else if (last_token == CPP_STRING
-          || last_token == CPP_WSTRING)
-    error ("%s before string constant", string);
-  else if (last_token == CPP_NUMBER)
-    error ("%s before numeric constant", string);
-  else if (last_token == CPP_NAME)
-    error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype));
-  else
-    error ("%s before '%s' token", string, NAME(last_token));
+  c_parse_error (msgid, last_token, yylval.ttype);
 }
 
 static int
@@ -3567,16 +3560,16 @@ yylexname (void)
 {
   tree decl;
 
-ifobjc
+@@ifobjc
   int objc_force_identifier = objc_need_raw_identifier;
   OBJC_NEED_RAW_IDENTIFIER (0);
-end ifobjc
+@@end_ifobjc
 
   if (C_IS_RESERVED_WORD (yylval.ttype))
     {
       enum rid rid_code = C_RID_CODE (yylval.ttype);
 
-ifobjc
+@@ifobjc
       /* Turn non-typedefed refs to "id" into plain identifiers; this
         allows constructs like "void foo(id id);" to work.  */
       if (rid_code == RID_ID)
@@ -3588,7 +3581,7 @@ ifobjc
 
       if (!OBJC_IS_AT_KEYWORD (rid_code)
          && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
-end ifobjc
+@@end_ifobjc
       {
        /* Return the canonical spelling for this keyword.  */
        yylval.ttype = ridpointers[(int) rid_code];
@@ -3602,7 +3595,7 @@ end ifobjc
       if (TREE_CODE (decl) == TYPE_DECL)
        return TYPENAME;
     }
-ifobjc
+@@ifobjc
   else
     {
       tree objc_interface_decl = is_class_name (yylval.ttype);
@@ -3616,7 +3609,7 @@ ifobjc
          return CLASSNAME;
        }
     }
-end ifobjc
+@@end_ifobjc
 
   return IDENTIFIER;
 }
@@ -3700,7 +3693,7 @@ _yylex (void)
     case CPP_STRING:
     case CPP_WSTRING:
       return STRING;
-      
+
     case CPP_OBJC_STRING:
       return OBJC_STRING;
 
@@ -3769,29 +3762,14 @@ yyprint (FILE *file, int yychar, YYSTYPE yyl)
     }
 }
 \f
-/* This is not the ideal place to put these, but we have to get them out
-   of c-lex.c because cp/lex.c has its own versions.  */
-
-/* Free malloced parser stacks if necessary.  */
-
-void
-free_parser_stacks (void)
-{
-}
+/* This is not the ideal place to put this, but we have to get it out
+   of c-lex.c because cp/lex.c has its own version.  */
 
 /* Parse the file.  */
 void
 c_parse_file (void)
 {
   yyparse ();
-  /* In case there were missing closebraces, get us back to the global
-     binding level.  */
-  while (! global_bindings_p ())
-    poplevel (0, 0, 0);
-  /* __FUNCTION__ is defined at file scope ("").  This
-     call may not be necessary as my tests indicate it
-     still works without it.  */
-  finish_fname_decls ();
 
   if (malloced_yyss)
     {