OSDN Git Service

In gcc/c-family/:
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index c691ef2..d9cc727 100644 (file)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -23,20 +23,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "dyn-string.h"
-#include "varray.h"
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
-#include "c-pragma.h"
+#include "intl.h"
+#include "c-family/c-pragma.h"
 #include "decl.h"
 #include "flags.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "output.h"
 #include "target.h"
 #include "cgraph.h"
-#include "c-common.h"
+#include "c-family/c-common.h"
 #include "plugin.h"
 
 \f
@@ -149,6 +148,128 @@ typedef struct GTY(()) cp_token_cache {
   cp_token * GTY ((skip)) last;
 } cp_token_cache;
 
+/* The various kinds of non integral constant we encounter. */
+typedef enum non_integral_constant {
+  NIC_NONE,
+  /* floating-point literal */
+  NIC_FLOAT,
+  /* %<this%> */
+  NIC_THIS,
+  /* %<__FUNCTION__%> */
+  NIC_FUNC_NAME,
+  /* %<__PRETTY_FUNCTION__%> */
+  NIC_PRETTY_FUNC,
+  /* %<__func__%> */
+  NIC_C99_FUNC,
+  /* "%<va_arg%> */
+  NIC_VA_ARG,
+  /* a cast */
+  NIC_CAST,
+  /* %<typeid%> operator */
+  NIC_TYPEID,
+  /* non-constant compound literals */
+  NIC_NCC,
+  /* a function call */
+  NIC_FUNC_CALL,
+  /* an increment */
+  NIC_INC,
+  /* an decrement */
+  NIC_DEC,
+  /* an array reference */
+  NIC_ARRAY_REF,
+  /* %<->%> */
+  NIC_ARROW,
+  /* %<.%> */
+  NIC_POINT,
+  /* the address of a label */
+  NIC_ADDR_LABEL,
+  /* %<*%> */
+  NIC_STAR,
+  /* %<&%> */
+  NIC_ADDR,
+  /* %<++%> */
+  NIC_PREINCREMENT,
+  /* %<--%> */
+  NIC_PREDECREMENT,
+  /* %<new%> */
+  NIC_NEW,
+  /* %<delete%> */
+  NIC_DEL,
+  /* calls to overloaded operators */
+  NIC_OVERLOADED,
+  /* an assignment */
+  NIC_ASSIGNMENT,
+  /* a comma operator */
+  NIC_COMMA,
+  /* a call to a constructor */
+  NIC_CONSTRUCTOR
+} non_integral_constant;
+
+/* The various kinds of errors about name-lookup failing. */
+typedef enum name_lookup_error {
+  /* NULL */
+  NLE_NULL,
+  /* is not a type */
+  NLE_TYPE,
+  /* is not a class or namespace */
+  NLE_CXX98,
+  /* is not a class, namespace, or enumeration */
+  NLE_NOT_CXX98
+} name_lookup_error;
+
+/* The various kinds of required token */
+typedef enum required_token {
+  RT_NONE,
+  RT_SEMICOLON,  /* ';' */
+  RT_OPEN_PAREN, /* '(' */
+  RT_CLOSE_BRACE, /* '}' */
+  RT_OPEN_BRACE,  /* '{' */
+  RT_CLOSE_SQUARE, /* ']' */
+  RT_OPEN_SQUARE,  /* '[' */
+  RT_COMMA, /* ',' */
+  RT_SCOPE, /* '::' */
+  RT_LESS, /* '<' */
+  RT_GREATER, /* '>' */
+  RT_EQ, /* '=' */
+  RT_ELLIPSIS, /* '...' */
+  RT_MULT, /* '*' */
+  RT_COMPL, /* '~' */
+  RT_COLON, /* ':' */
+  RT_COLON_SCOPE, /* ':' or '::' */
+  RT_CLOSE_PAREN, /* ')' */
+  RT_COMMA_CLOSE_PAREN, /* ',' or ')' */
+  RT_PRAGMA_EOL, /* end of line */
+  RT_NAME, /* identifier */
+
+  /* The type is CPP_KEYWORD */
+  RT_NEW, /* new */
+  RT_DELETE, /* delete */
+  RT_RETURN, /* return */
+  RT_WHILE, /* while */
+  RT_EXTERN, /* extern */
+  RT_STATIC_ASSERT, /* static_assert */
+  RT_DECLTYPE, /* decltype */
+  RT_OPERATOR, /* operator */
+  RT_CLASS, /* class */
+  RT_TEMPLATE, /* template */
+  RT_NAMESPACE, /* namespace */
+  RT_USING, /* using */
+  RT_ASM, /* asm */
+  RT_TRY, /* try */
+  RT_CATCH, /* catch */
+  RT_THROW, /* throw */
+  RT_LABEL, /* __label__ */
+  RT_AT_TRY, /* @try */
+  RT_AT_SYNCHRONIZED, /* @synchronized */
+  RT_AT_THROW, /* @throw */
+
+  RT_SELECT,  /* selection-statement */
+  RT_INTERATION, /* iteration-statement */
+  RT_JUMP, /* jump-statement */
+  RT_CLASS_KEY, /* class-key */
+  RT_CLASS_TYPENAME_TEMPLATE /* class, typename, or template */
+} required_token;
+
 /* Prototypes.  */
 
 static cp_lexer *cp_lexer_new_main
@@ -247,6 +368,10 @@ static void cp_parser_initial_pragma
 static FILE *cp_lexer_debug_stream;
 #endif /* ENABLE_CHECKING */
 
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+   sizeof, typeof, or alignof.  */
+int cp_unevaluated_operand;
+
 /* Create a new main C++ lexer, the lexer that gets tokens from the
    preprocessor.  */
 
@@ -268,7 +393,7 @@ cp_lexer_new_main (void)
   c_common_no_more_pch ();
 
   /* Allocate the memory.  */
-  lexer = GGC_CNEW (cp_lexer);
+  lexer = ggc_alloc_cleared_cp_lexer ();
 
 #ifdef ENABLE_CHECKING
   /* Initially we are not debugging.  */
@@ -279,7 +404,7 @@ cp_lexer_new_main (void)
 
   /* Create the buffer.  */
   alloc = CP_LEXER_BUFFER_SIZE;
-  buffer = GGC_NEWVEC (cp_token, alloc);
+  buffer = ggc_alloc_vec_cp_token (alloc);
 
   /* Put the first token in the buffer.  */
   space = alloc;
@@ -320,7 +445,7 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
 {
   cp_token *first = cache->first;
   cp_token *last = cache->last;
-  cp_lexer *lexer = GGC_CNEW (cp_lexer);
+  cp_lexer *lexer = ggc_alloc_cleared_cp_lexer ();
 
   /* We do not own the buffer.  */
   lexer->buffer = NULL;
@@ -398,7 +523,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
    /* Get a new token from the preprocessor.  */
   token->type
     = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
-                       lexer == NULL ? 0 : C_LEX_RAW_STRINGS);
+                       lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN);
   token->keyword = RID_MAX;
   token->pragma_kind = PRAGMA_NONE;
 
@@ -428,8 +553,8 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
               /* Warn about the C++0x keyword (but still treat it as
                  an identifier).  */
               warning (OPT_Wc__0x_compat, 
-                       "identifier %<%s%> will become a keyword in C++0x",
-                       IDENTIFIER_POINTER (token->u.value));
+                       "identifier %qE will become a keyword in C++0x",
+                       token->u.value);
 
               /* Clear out the C_RID_CODE so we don't warn about this
                  particular identifier-turned-keyword again.  */
@@ -440,21 +565,28 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
          token->keyword = RID_MAX;
        }
     }
-  /* Handle Objective-C++ keywords.  */
   else if (token->type == CPP_AT_NAME)
     {
+      /* This only happens in Objective-C++; it must be a keyword.  */
       token->type = CPP_KEYWORD;
       switch (C_RID_CODE (token->u.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;
+         /* Replace 'class' with '@class', 'private' with '@private',
+            etc.  This prevents confusion with the C++ keyword
+            'class', and makes the tokens consistent with other
+            Objective-C 'AT' keywords.  For example '@class' is
+            reported as RID_AT_CLASS which is consistent with
+            '@synchronized', which is reported as
+            RID_AT_SYNCHRONIZED.
+         */
+       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->u.value);
+       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->u.value);
        }
     }
   else if (token->type == CPP_PRAGMA)
@@ -557,6 +689,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
     case RID_SHORT:
     case RID_INT:
     case RID_LONG:
+    case RID_INT128:
     case RID_SIGNED:
     case RID_UNSIGNED:
     case RID_FLOAT:
@@ -788,6 +921,7 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
+    case CPP_UTF8STRING:
       fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
       break;
 
@@ -819,7 +953,7 @@ cp_lexer_stop_debugging (cp_lexer* lexer)
 static cp_token_cache *
 cp_token_cache_new (cp_token *first, cp_token *last)
 {
-  cp_token_cache *cache = GGC_NEW (cp_token_cache);
+  cp_token_cache *cache = ggc_alloc_cp_token_cache ();
   cache->first = first;
   cache->last = last;
   return cache;
@@ -884,6 +1018,7 @@ make_declarator (cp_declarator_kind kind)
   declarator->attributes = NULL_TREE;
   declarator->declarator = NULL;
   declarator->parameter_pack_p = false;
+  declarator->id_loc = UNKNOWN_LOCATION;
 
   return declarator;
 }
@@ -940,6 +1075,7 @@ make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target)
   declarator->u.pointer.class_type = NULL_TREE;
   if (target)
     {
+      declarator->id_loc = target->id_loc;
       declarator->parameter_pack_p = target->parameter_pack_p;
       target->parameter_pack_p = false;
     }
@@ -963,6 +1099,7 @@ make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
   declarator->u.reference.rvalue_ref = rvalue_ref;
   if (target)
     {
+      declarator->id_loc = target->id_loc;
       declarator->parameter_pack_p = target->parameter_pack_p;
       target->parameter_pack_p = false;
     }
@@ -1019,6 +1156,7 @@ make_call_declarator (cp_declarator *target,
   declarator->u.function.late_return_type = late_return_type;
   if (target)
     {
+      declarator->id_loc = target->id_loc;
       declarator->parameter_pack_p = target->parameter_pack_p;
       target->parameter_pack_p = false;
     }
@@ -1041,6 +1179,7 @@ make_array_declarator (cp_declarator *element, tree bounds)
   declarator->u.array.bounds = bounds;
   if (element)
     {
+      declarator->id_loc = element->id_loc;
       declarator->parameter_pack_p = element->parameter_pack_p;
       element->parameter_pack_p = false;
     }
@@ -1183,19 +1322,23 @@ function_declarator_p (const cp_declarator *declarator)
 /* Flags that are passed to some parsing functions.  These values can
    be bitwise-ored together.  */
 
-enum cp_parser_flags
+enum
 {
   /* No flags.  */
   CP_PARSER_FLAGS_NONE = 0x0,
   /* The construct is optional.  If it is not present, then no error
      should be issued.  */
   CP_PARSER_FLAGS_OPTIONAL = 0x1,
-  /* When parsing a type-specifier, do not allow user-defined types.  */
-  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2
+  /* When parsing a type-specifier, treat user-defined type-names
+     as non-type identifiers.  */
+  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
+  /* When parsing a type-specifier, do not try to parse a class-specifier
+     or enum-specifier.  */
+  CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4
 };
 
 /* This type is used for parameters and variables which hold
-   combinations of the flags in enum cp_parser_flags.  */
+   combinations of the above flags.  */
 typedef int cp_parser_flags;
 
 /* The different kinds of declarators we want to parse.  */
@@ -1364,7 +1507,7 @@ cp_parser_context_new (cp_parser_context* next)
       memset (context, 0, sizeof (*context));
     }
   else
-    context = GGC_CNEW (cp_parser_context);
+    context = ggc_alloc_cleared_cp_parser_context ();
 
   /* No errors have occurred yet in this context.  */
   context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
@@ -1382,6 +1525,34 @@ cp_parser_context_new (cp_parser_context* next)
   return context;
 }
 
+/* An entry in a queue of function arguments that require post-processing.  */
+
+typedef struct GTY(()) cp_default_arg_entry_d {
+  /* The current_class_type when we parsed this arg.  */
+  tree class_type;
+
+  /* The function decl itself.  */
+  tree decl;
+} cp_default_arg_entry;
+
+DEF_VEC_O(cp_default_arg_entry);
+DEF_VEC_ALLOC_O(cp_default_arg_entry,gc);
+
+/* An entry in a stack for member functions of local classes.  */
+
+typedef struct GTY(()) cp_unparsed_functions_entry_d {
+  /* Functions with default arguments that require post-processing.
+     Functions appear in this list in declaration order.  */
+  VEC(cp_default_arg_entry,gc) *funs_with_default_args;
+
+  /* Functions with defintions that require post-processing.  Functions
+     appear in this list in declaration order.  */
+  VEC(tree,gc) *funs_with_definitions;
+} cp_unparsed_functions_entry;
+
+DEF_VEC_O(cp_unparsed_functions_entry);
+DEF_VEC_ALLOC_O(cp_unparsed_functions_entry,gc);
+
 /* The cp_parser structure represents the C++ parser.  */
 
 typedef struct GTY(()) cp_parser {
@@ -1508,21 +1679,10 @@ typedef struct GTY(()) cp_parser {
      issued as an error message if a type is defined.  */
   const char *type_definition_forbidden_message;
 
-  /* A list of lists. The outer list is a stack, used for member
-     functions of local classes. At each level there are two sub-list,
-     one on TREE_VALUE and one on TREE_PURPOSE. Each of those
-     sub-lists has a FUNCTION_DECL or TEMPLATE_DECL on their
-     TREE_VALUE's. The functions are chained in reverse declaration
-     order.
-
-     The TREE_PURPOSE sublist contains those functions with default
-     arguments that need post processing, and the TREE_VALUE sublist
-     contains those functions with definitions that need post
-     processing.
-
-     These lists can only be processed once the outermost class being
-     defined is complete.  */
-  tree unparsed_functions_queues;
+  /* A stack used for member functions of local classes.  The lists
+     contained in an individual entry can only be processed once the
+     outermost class being defined is complete.  */
+  VEC(cp_unparsed_functions_entry,gc) *unparsed_queues;
 
   /* The number of classes whose definitions are currently in
      progress.  */
@@ -1533,6 +1693,29 @@ typedef struct GTY(()) cp_parser {
   unsigned num_template_parameter_lists;
 } cp_parser;
 
+/* Managing the unparsed function queues.  */
+
+#define unparsed_funs_with_default_args \
+  VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args
+#define unparsed_funs_with_definitions \
+  VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_definitions
+
+static void
+push_unparsed_function_queues (cp_parser *parser)
+{
+  VEC_safe_push (cp_unparsed_functions_entry, gc,
+                parser->unparsed_queues, NULL);
+  unparsed_funs_with_default_args = NULL;
+  unparsed_funs_with_definitions = make_tree_vector ();
+}
+
+static void
+pop_unparsed_function_queues (cp_parser *parser)
+{
+  release_tree_vector (unparsed_funs_with_definitions);
+  VEC_pop (cp_unparsed_functions_entry, parser->unparsed_queues);
+}
+
 /* Prototypes.  */
 
 /* Constructors and destructors.  */
@@ -1584,8 +1767,10 @@ static tree cp_parser_postfix_open_square_expression
   (cp_parser *, tree, bool);
 static tree cp_parser_postfix_dot_deref_expression
   (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
-static tree cp_parser_parenthesized_expression_list
-  (cp_parser *, bool, bool, bool, bool *);
+static VEC(tree,gc) *cp_parser_parenthesized_expression_list
+  (cp_parser *, int, bool, bool, bool *);
+/* Values for the second parameter of cp_parser_parenthesized_expression_list.  */
+enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree *, tree *);
 static tree cp_parser_unary_expression
@@ -1594,7 +1779,7 @@ static enum tree_code cp_parser_unary_operator
   (cp_token *);
 static tree cp_parser_new_expression
   (cp_parser *);
-static tree cp_parser_new_placement
+static VEC(tree,gc) *cp_parser_new_placement
   (cp_parser *);
 static tree cp_parser_new_type_id
   (cp_parser *, tree *);
@@ -1602,7 +1787,7 @@ static cp_declarator *cp_parser_new_declarator_opt
   (cp_parser *);
 static cp_declarator *cp_parser_direct_new_declarator
   (cp_parser *);
-static tree cp_parser_new_initializer
+static VEC(tree,gc) *cp_parser_new_initializer
   (cp_parser *);
 static tree cp_parser_delete_expression
   (cp_parser *);
@@ -1622,6 +1807,14 @@ static tree cp_parser_constant_expression
   (cp_parser *, bool, bool *);
 static tree cp_parser_builtin_offsetof
   (cp_parser *);
+static tree cp_parser_lambda_expression
+  (cp_parser *);
+static void cp_parser_lambda_introducer
+  (cp_parser *, tree);
+static void cp_parser_lambda_declarator_opt
+  (cp_parser *, tree);
+static void cp_parser_lambda_body
+  (cp_parser *, tree);
 
 /* Statements [gram.stmt.stmt]  */
 
@@ -1643,6 +1836,10 @@ static tree cp_parser_iteration_statement
   (cp_parser *);
 static void cp_parser_for_init_statement
   (cp_parser *);
+static tree  cp_parser_c_for
+  (cp_parser *);
+static tree  cp_parser_range_for
+  (cp_parser *);
 static tree cp_parser_jump_statement
   (cp_parser *);
 static void cp_parser_declaration_statement
@@ -1729,10 +1926,11 @@ static tree cp_parser_type_id
   (cp_parser *);
 static tree cp_parser_template_type_arg
   (cp_parser *);
+static tree cp_parser_trailing_type_id (cp_parser *);
 static tree cp_parser_type_id_1
-  (cp_parser *, bool);
+  (cp_parser *, bool, bool);
 static void cp_parser_type_specifier_seq
-  (cp_parser *, bool, cp_decl_specifier_seq *);
+  (cp_parser *, bool, bool, cp_decl_specifier_seq *);
 static tree cp_parser_parameter_declaration_clause
   (cp_parser *);
 static tree cp_parser_parameter_declaration_list
@@ -1855,6 +2053,8 @@ static tree cp_parser_asm_operand_list
   (cp_parser *);
 static tree cp_parser_asm_clobber_list
   (cp_parser *);
+static tree cp_parser_asm_label_list
+  (cp_parser *);
 static tree cp_parser_attributes_opt
   (cp_parser *);
 static tree cp_parser_attribute_list
@@ -1893,9 +2093,11 @@ static tree cp_parser_objc_selector
 static tree cp_parser_objc_protocol_refs_opt
   (cp_parser *);
 static void cp_parser_objc_declaration
-  (cp_parser *);
+  (cp_parser *, tree);
 static tree cp_parser_objc_statement
   (cp_parser *);
+static bool cp_parser_objc_valid_prefix_attributes
+  (cp_parser* parser, tree *attrib);
 
 /* Utility Routines */
 
@@ -1949,10 +2151,12 @@ static void cp_parser_set_decl_spec_type
   (cp_decl_specifier_seq *, tree, location_t, bool);
 static bool cp_parser_friend_p
   (const cp_decl_specifier_seq *);
+static void cp_parser_required_error
+  (cp_parser *, required_token, bool);
 static cp_token *cp_parser_require
-  (cp_parser *, enum cpp_ttype, const char *);
+  (cp_parser *, enum cpp_ttype, required_token);
 static cp_token *cp_parser_require_keyword
-  (cp_parser *, enum rid, const char *);
+  (cp_parser *, enum rid, required_token);
 static bool cp_parser_token_starts_function_definition_p
   (cp_token *);
 static bool cp_parser_next_token_starts_class_definition_p
@@ -1988,7 +2192,7 @@ static bool cp_parser_uncommitted_to_tentative_parse_p
 static void cp_parser_error
   (cp_parser *, const char *);
 static void cp_parser_name_lookup_error
-  (cp_parser *, tree, tree, const char *, location_t);
+  (cp_parser *, tree, tree, name_lookup_error, location_t);
 static bool cp_parser_simulate_error
   (cp_parser *);
 static bool cp_parser_check_type_definition
@@ -1998,7 +2202,7 @@ static void cp_parser_check_for_definition_in_return_type
 static void cp_parser_check_for_invalid_template_id
   (cp_parser *, tree, location_t location);
 static bool cp_parser_non_integral_constant_expression
-  (cp_parser *, const char *);
+  (cp_parser *, non_integral_constant);
 static void cp_parser_diagnose_invalid_type_name
   (cp_parser *, tree, tree, location_t);
 static bool cp_parser_parse_and_diagnose_invalid_type_name
@@ -2046,7 +2250,8 @@ cp_parser_is_string_literal (cp_token* token)
   return (token->type == CPP_STRING ||
          token->type == CPP_STRING16 ||
          token->type == CPP_STRING32 ||
-         token->type == CPP_WSTRING);
+         token->type == CPP_WSTRING ||
+         token->type == CPP_UTF8STRING);
 }
 
 /* Returns nonzero if TOKEN is the indicated KEYWORD.  */
@@ -2064,7 +2269,7 @@ cp_parser_is_keyword (cp_token* token, enum rid keyword)
    OTHER-TOKEN".  */
 
 static void
-cp_parser_error (cp_parser* parser, const char* message)
+cp_parser_error (cp_parser* parser, const char* gmsgid)
 {
   if (!cp_parser_simulate_error (parser))
     {
@@ -2075,12 +2280,13 @@ cp_parser_error (cp_parser* parser, const char* message)
 
       if (token->type == CPP_PRAGMA)
        {
-         error ("%H%<#pragma%> is not allowed here", &token->location);
+         error_at (token->location,
+                   "%<#pragma%> is not allowed here");
          cp_parser_skip_to_pragma_eol (parser, token);
          return;
        }
 
-      c_parse_error (message,
+      c_parse_error (gmsgid,
                     /* Because c_parser_error does not understand
                        CPP_KEYWORD, keywords are treated like
                        identifiers.  */
@@ -2098,7 +2304,7 @@ static void
 cp_parser_name_lookup_error (cp_parser* parser,
                             tree name,
                             tree decl,
-                            const char* desired,
+                            name_lookup_error desired,
                             location_t location)
 {
   /* If name lookup completely failed, tell the user that NAME was not
@@ -2106,26 +2312,79 @@ cp_parser_name_lookup_error (cp_parser* parser,
   if (decl == error_mark_node)
     {
       if (parser->scope && parser->scope != global_namespace)
-       error ("%H%<%E::%E%> has not been declared",
-              &location, parser->scope, name);
+       error_at (location, "%<%E::%E%> has not been declared",
+                 parser->scope, name);
       else if (parser->scope == global_namespace)
-       error ("%H%<::%E%> has not been declared", &location, name);
+       error_at (location, "%<::%E%> has not been declared", name);
       else if (parser->object_scope
               && !CLASS_TYPE_P (parser->object_scope))
-       error ("%Hrequest for member %qE in non-class type %qT",
-              &location, name, parser->object_scope);
+       error_at (location, "request for member %qE in non-class type %qT",
+                 name, parser->object_scope);
       else if (parser->object_scope)
-       error ("%H%<%T::%E%> has not been declared",
-              &location, parser->object_scope, name);
+       error_at (location, "%<%T::%E%> has not been declared",
+                 parser->object_scope, name);
       else
-       error ("%H%qE has not been declared", &location, name);
+       error_at (location, "%qE has not been declared", name);
     }
   else if (parser->scope && parser->scope != global_namespace)
-    error ("%H%<%E::%E%> %s", &location, parser->scope, name, desired);
+    {
+      switch (desired)
+       {
+         case NLE_TYPE:
+           error_at (location, "%<%E::%E%> is not a type",
+                               parser->scope, name);
+           break;
+         case NLE_CXX98:
+           error_at (location, "%<%E::%E%> is not a class or namespace",
+                               parser->scope, name);
+           break;
+         case NLE_NOT_CXX98:
+           error_at (location,
+                     "%<%E::%E%> is not a class, namespace, or enumeration",
+                     parser->scope, name);
+           break;
+         default:
+           gcc_unreachable ();
+           
+       }
+    }
   else if (parser->scope == global_namespace)
-    error ("%H%<::%E%> %s", &location, name, desired);
+    {
+      switch (desired)
+       {
+         case NLE_TYPE:
+           error_at (location, "%<::%E%> is not a type", name);
+           break;
+         case NLE_CXX98:
+           error_at (location, "%<::%E%> is not a class or namespace", name);
+           break;
+         case NLE_NOT_CXX98:
+           error_at (location,
+                     "%<::%E%> is not a class, namespace, or enumeration",
+                     name);
+           break;
+         default:
+           gcc_unreachable ();
+       }
+    }
   else
-    error ("%H%qE %s", &location, name, desired);
+    {
+      switch (desired)
+       {
+         case NLE_TYPE:
+           error_at (location, "%qE is not a type", name);
+           break;
+         case NLE_CXX98:
+           error_at (location, "%qE is not a class or namespace", name);
+           break;
+         case NLE_NOT_CXX98:
+           error_at (location,
+                     "%qE is not a class, namespace, or enumeration", name);
+           break;
+         default:
+           gcc_unreachable ();
+       }
+    }
 }
 
 /* If we are parsing tentatively, remember that an error has occurred
@@ -2149,18 +2408,18 @@ static void
 cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
                           location_t location)
 {
-  cp_decl_spec ds;
+  int ds;
 
   for (ds = ds_first; ds != ds_last; ++ds)
     {
-      unsigned count = decl_specs->specs[(int)ds];
+      unsigned count = decl_specs->specs[ds];
       if (count < 2)
        continue;
       /* The "long" specifier is a special case because of "long long".  */
       if (ds == ds_long)
        {
          if (count > 2)
-           error ("%H%<long long long%> is too long for GCC", &location);
+           error_at (location, "%<long long long%> is too long for GCC");
          else 
            pedwarn_cxx98 (location, OPT_Wlong_long, 
                           "ISO C++ 1998 does not support %<long long%>");
@@ -2180,10 +2439,11 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
            "explicit",
            "friend",
            "typedef",
+            "constexpr",
            "__complex",
            "__thread"
          };
-         error ("%Hduplicate %qs", &location, decl_spec_names[(int)ds]);
+         error_at (location, "duplicate %qs", decl_spec_names[ds]);
        }
     }
 }
@@ -2227,7 +2487,8 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
   if (declarator
       && declarator->kind == cdk_function)
     {
-      error ("%Hnew types may not be defined in a return type", &type_location);
+      error_at (type_location,
+               "new types may not be defined in a return type");
       inform (type_location, 
              "(perhaps a semicolon is missing after the definition of %qT)",
              type);
@@ -2249,11 +2510,11 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
     {
       if (TYPE_P (type))
-       error ("%H%qT is not a template", &location, type);
+       error_at (location, "%qT is not a template", type);
       else if (TREE_CODE (type) == IDENTIFIER_NODE)
-       error ("%H%qE is not a template", &location, type);
+       error_at (location, "%qE is not a template", type);
       else
-       error ("%Hinvalid template-id", &location);
+       error_at (location, "invalid template-id");
       /* Remember the location of the invalid "<".  */
       if (cp_parser_uncommitted_to_tentative_parse_p (parser))
        start = cp_lexer_token_position (parser->lexer, true);
@@ -2275,20 +2536,112 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
 
 static bool
 cp_parser_non_integral_constant_expression (cp_parser  *parser,
-                                           const char *thing)
+                                           non_integral_constant thing)
 {
   parser->non_integral_constant_expression_p = true;
   if (parser->integral_constant_expression_p)
     {
       if (!parser->allow_non_integral_constant_expression_p)
        {
-         /* Don't use `%s' to print THING, because quotations (`%<', `%>')
-            in the message need to be interpreted.  */
-         char *message = concat (thing,
-                                 " cannot appear in a constant-expression",
-                                 NULL);
-         error (message);
-         free (message);
+         const char *msg = NULL;
+         switch (thing)
+           {
+             case NIC_FLOAT:
+               error ("floating-point literal "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_CAST:
+               error ("a cast to a type other than an integral or "
+                      "enumeration type cannot appear in a "
+                      "constant-expression");
+               return true;
+             case NIC_TYPEID:
+               error ("%<typeid%> operator "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_NCC:
+               error ("non-constant compound literals "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_FUNC_CALL:
+               error ("a function call "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_INC:
+               error ("an increment "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_DEC:
+               error ("an decrement "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_ARRAY_REF:
+               error ("an array reference "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_ADDR_LABEL:
+               error ("the address of a label "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_OVERLOADED:
+               error ("calls to overloaded operators "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_ASSIGNMENT:
+               error ("an assignment cannot appear in a constant-expression");
+               return true;
+             case NIC_COMMA:
+               error ("a comma operator "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_CONSTRUCTOR:
+               error ("a call to a constructor "
+                      "cannot appear in a constant-expression");
+               return true;
+             case NIC_THIS:
+               msg = "this";
+               break;
+             case NIC_FUNC_NAME:
+               msg = "__FUNCTION__";
+               break;
+             case NIC_PRETTY_FUNC:
+               msg = "__PRETTY_FUNCTION__";
+               break;
+             case NIC_C99_FUNC:
+               msg = "__func__";
+               break;
+             case NIC_VA_ARG:
+               msg = "va_arg";
+               break;
+             case NIC_ARROW:
+               msg = "->";
+               break;
+             case NIC_POINT:
+               msg = ".";
+               break;
+             case NIC_STAR:
+               msg = "*";
+               break;
+             case NIC_ADDR:
+               msg = "&";
+               break;
+             case NIC_PREINCREMENT:
+               msg = "++";
+               break;
+             case NIC_PREDECREMENT:
+               msg = "--";
+               break;
+             case NIC_NEW:
+               msg = "new";
+               break;
+             case NIC_DEL:
+               msg = "delete";
+               break;
+             default:
+               gcc_unreachable ();
+           }
+         if (msg)
+           error ("%qs cannot appear in a constant-expression", msg);
          return true;
        }
     }
@@ -2315,18 +2668,18 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
   /* If the lookup found a template-name, it means that the user forgot
   to specify an argument list. Emit a useful error message.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
-    error ("%Hinvalid use of template-name %qE without an argument list",
-           &location, decl);
+    error_at (location,
+             "invalid use of template-name %qE without an argument list",
+             decl);
   else if (TREE_CODE (id) == BIT_NOT_EXPR)
-    error ("%Hinvalid use of destructor %qD as a type", &location, id);
+    error_at (location, "invalid use of destructor %qD as a type", id);
   else if (TREE_CODE (decl) == TYPE_DECL)
     /* Something like 'unsigned A a;'  */
-    error ("%Hinvalid combination of multiple type-specifiers",
-           &location);
+    error_at (location, "invalid combination of multiple type-specifiers");
   else if (!parser->scope)
     {
       /* Issue an error message.  */
-      error ("%H%qE does not name a type", &location, id);
+      error_at (location, "%qE does not name a type", id);
       /* If we're in a template class, it's possible that the user was
         referring to a type from a base class.  For example:
 
@@ -2354,7 +2707,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
                  base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
                  for (field = TYPE_FIELDS (base_type);
                       field;
-                      field = TREE_CHAIN (field))
+                      field = DECL_CHAIN (field))
                    if (TREE_CODE (field) == TYPE_DECL
                        && DECL_NAME (field) == id)
                      {
@@ -2374,11 +2727,26 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
   else if (parser->scope != error_mark_node)
     {
       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
-       error ("%H%qE in namespace %qE does not name a type",
-              &location, id, parser->scope);
+       error_at (location, "%qE in namespace %qE does not name a type",
+                 id, parser->scope);
+      else if (CLASS_TYPE_P (parser->scope)
+              && constructor_name_p (id, parser->scope))
+       {
+         /* A<T>::A<T>() */
+         error_at (location, "%<%T::%E%> names the constructor, not"
+                   " the type", parser->scope, id);
+         if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+           error_at (location, "and %qT has no template constructors",
+                     parser->scope);
+       }
+      else if (TYPE_P (parser->scope)
+              && dependent_scope_p (parser->scope))
+       error_at (location, "need %<typename%> before %<%T::%E%> because "
+                 "%qT is a dependent scope",
+                 parser->scope, id, parser->scope);
       else if (TYPE_P (parser->scope))
-       error ("%H%qE in class %qT does not name a type",
-               &location, id, parser->scope);
+       error_at (location, "%qE in class %qT does not name a type",
+                 id, parser->scope);
       else
        gcc_unreachable ();
     }
@@ -2401,6 +2769,14 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
   tree id;
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
+  /* Avoid duplicate error about ambiguous lookup.  */
+  if (token->type == CPP_NESTED_NAME_SPECIFIER)
+    {
+      cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2);
+      if (next->type == CPP_NAME && next->ambiguous_p)
+       goto out;
+    }
+
   cp_parser_parse_tentatively (parser);
   id = cp_parser_id_expression (parser,
                                /*template_keyword_p=*/false,
@@ -2408,12 +2784,9 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
                                /*template_p=*/NULL,
                                /*declarator_p=*/true,
                                /*optional_p=*/false);
-  /* After the id-expression, there should be a plain identifier,
-     otherwise this is not a simple variable declaration. Also, if
-     the scope is dependent, we cannot do much.  */
-  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)
-      || (parser->scope && TYPE_P (parser->scope)
-         && dependent_type_p (parser->scope))
+  /* If the next token is a (, this is a function with no explicit return
+     type, i.e. constructor, destructor or conversion op.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
       || TREE_CODE (id) == TYPE_DECL)
     {
       cp_parser_abort_tentative_parse (parser);
@@ -2425,9 +2798,12 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
   /* Emit a diagnostic for the invalid type.  */
   cp_parser_diagnose_invalid_type_name (parser, parser->scope,
                                        id, token->location);
-  /* Skip to the end of the declaration; there's no point in
-     trying to process it.  */
-  cp_parser_skip_to_end_of_block_or_statement (parser);
+ out:
+  /* If we aren't in the middle of a declarator (i.e. in a
+     parameter-declaration-clause), skip to the end of the declaration;
+     there's no point in trying to process it.  */
+  if (!parser->in_declarator_p)
+    cp_parser_skip_to_end_of_block_or_statement (parser);
   return true;
 }
 
@@ -2444,6 +2820,7 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
 {
   unsigned paren_depth = 0;
   unsigned brace_depth = 0;
+  unsigned square_depth = 0;
 
   if (recovering && !or_comma
       && cp_parser_uncommitted_to_tentative_parse_p (parser))
@@ -2460,6 +2837,15 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
          /* If we've run out of tokens, then there is no closing `)'.  */
          return 0;
 
+        /* This is good for lambda expression capture-lists.  */
+        case CPP_OPEN_SQUARE:
+          ++square_depth;
+          break;
+        case CPP_CLOSE_SQUARE:
+          if (!square_depth--)
+            return 0;
+          break;
+
        case CPP_SEMICOLON:
          /* This matches the processing in skip_to_end_of_statement.  */
          if (!brace_depth)
@@ -2475,7 +2861,8 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
          break;
 
        case CPP_COMMA:
-         if (recovering && or_comma && !brace_depth && !paren_depth)
+         if (recovering && or_comma && !brace_depth && !paren_depth
+             && !square_depth)
            return -1;
          break;
 
@@ -2577,7 +2964,7 @@ static void
 cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
 {
   /* Look for the trailing `;'.  */
-  if (!cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"))
+  if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
     {
       /* If there is additional (erroneous) input, skip to the end of
         the statement.  */
@@ -2705,7 +3092,7 @@ static void
 cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
 {
   parser->lexer->in_pragma = false;
-  if (!cp_parser_require (parser, CPP_PRAGMA_EOL, "end of line"))
+  if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
     cp_parser_skip_to_pragma_eol (parser, pragma_tok);
 }
 
@@ -2763,7 +3150,7 @@ cp_parser_new (void)
   cp_lexer *lexer;
   unsigned i;
 
-  /* cp_lexer_new_main is called before calling ggc_alloc because
+  /* cp_lexer_new_main is called before doing GC allocation because
      cp_lexer_new_main might load a PCH file.  */
   lexer = cp_lexer_new_main ();
 
@@ -2772,7 +3159,7 @@ cp_parser_new (void)
   for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++)
     binops_by_token[binops[i].token_type] = binops[i];
 
-  parser = GGC_CNEW (cp_parser);
+  parser = ggc_alloc_cleared_cp_parser ();
   parser->lexer = lexer;
   parser->context = cp_parser_context_new (NULL);
 
@@ -2821,7 +3208,7 @@ cp_parser_new (void)
   parser->in_function_body = false;
 
   /* The unparsed function queue is empty.  */
-  parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE);
+  push_unparsed_function_queues (parser);
 
   /* There are no classes being defined.  */
   parser->num_classes_being_defined = 0;
@@ -2873,7 +3260,7 @@ cp_parser_identifier (cp_parser* parser)
   cp_token *token;
 
   /* Look for the identifier.  */
-  token = cp_parser_require (parser, CPP_NAME, "identifier");
+  token = cp_parser_require (parser, CPP_NAME, RT_NAME);
   /* Return the value.  */
   return token ? token->u.value : error_mark_node;
 }
@@ -2941,8 +3328,9 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
              if (type == CPP_STRING)
                type = tok->type;
              else if (tok->type != CPP_STRING)
-               error ("%Hunsupported non-standard concatenation "
-                       "of string literals", &tok->location);
+               error_at (tok->location,
+                         "unsupported non-standard concatenation "
+                         "of string literals");
            }
 
          obstack_grow (&str_ob, &str, sizeof (cpp_string));
@@ -2970,6 +3358,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
        {
        default:
        case CPP_STRING:
+       case CPP_UTF8STRING:
          TREE_TYPE (value) = char_array_type_node;
          break;
        case CPP_STRING16:
@@ -3144,8 +3533,8 @@ cp_parser_primary_expression (cp_parser *parser,
       token = cp_lexer_consume_token (parser->lexer);
       if (TREE_CODE (token->u.value) == FIXED_CST)
        {
-         error ("%Hfixed-point types not supported in C++",
-                &token->location);
+         error_at (token->location,
+                   "fixed-point types not supported in C++");
          return error_mark_node;
        }
       /* Floating-point literals are only allowed in an integral
@@ -3190,8 +3579,7 @@ cp_parser_primary_expression (cp_parser *parser,
             checked at that point.  If we are not within a cast, then
             this code is invalid.  */
          if (!cast_p)
-           cp_parser_non_integral_constant_expression
-             (parser, "floating-point literal");
+           cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
        }
       return token->u.value;
 
@@ -3199,6 +3587,7 @@ cp_parser_primary_expression (cp_parser *parser,
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
+    case CPP_UTF8STRING:
       /* ??? Should wide strings be allowed when parser->translate_strings_p
         is false (i.e. in attributes)?  If not, we can kill the third
         argument to cp_parser_string_literal.  */
@@ -3236,9 +3625,9 @@ cp_parser_primary_expression (cp_parser *parser,
            if (!parser->in_function_body
                || parser->in_template_argument_list_p)
              {
-               error ("%Hstatement-expressions are not allowed outside "
-                      "functions nor in template-argument lists",
-                      &token->location);
+               error_at (token->location,
+                         "statement-expressions are not allowed outside "
+                         "functions nor in template-argument lists");
                cp_parser_skip_to_end_of_block_or_statement (parser);
                expr = error_mark_node;
              }
@@ -3268,12 +3657,26 @@ cp_parser_primary_expression (cp_parser *parser,
        parser->greater_than_is_operator_p
          = saved_greater_than_is_operator_p;
        /* Consume the `)'.  */
-       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
          cp_parser_skip_to_end_of_statement (parser);
 
        return expr;
       }
 
+    case CPP_OPEN_SQUARE:
+      if (c_dialect_objc ())
+        /* We have an Objective-C++ message. */
+        return cp_parser_objc_expression (parser);
+      maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
+      return cp_parser_lambda_expression (parser);
+
+    case CPP_OBJC_STRING:
+      if (c_dialect_objc ())
+       /* We have an Objective-C++ string literal. */
+        return cp_parser_objc_expression (parser);
+      cp_parser_error (parser, "expected primary-expression");
+      return error_mark_node;
+
     case CPP_KEYWORD:
       switch (token->keyword)
        {
@@ -3290,17 +3693,22 @@ cp_parser_primary_expression (cp_parser *parser,
          cp_lexer_consume_token (parser->lexer);
          return null_node;
 
+         /* The `nullptr' literal.  */
+       case RID_NULLPTR:
+         cp_lexer_consume_token (parser->lexer);
+         return nullptr_node;
+
          /* Recognize the `this' keyword.  */
        case RID_THIS:
          cp_lexer_consume_token (parser->lexer);
          if (parser->local_variables_forbidden_p)
            {
-             error ("%H%<this%> may not be used in this context",
-                     &token->location);
+             error_at (token->location,
+                       "%<this%> may not be used in this context");
              return error_mark_node;
            }
          /* Pointers cannot appear in constant-expressions.  */
-         if (cp_parser_non_integral_constant_expression (parser, "%<this%>"))
+         if (cp_parser_non_integral_constant_expression (parser, NIC_THIS))
            return error_mark_node;
          return finish_this_expr ();
 
@@ -3313,7 +3721,7 @@ cp_parser_primary_expression (cp_parser *parser,
        case RID_PRETTY_FUNCTION_NAME:
        case RID_C99_FUNCTION_NAME:
          {
-           const char *name;
+           non_integral_constant name;
 
            /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
               __func__ are the names of variables -- but they are
@@ -3327,13 +3735,13 @@ cp_parser_primary_expression (cp_parser *parser,
            switch (token->keyword)
              {
              case RID_FUNCTION_NAME:
-               name = "%<__FUNCTION__%>";
+               name = NIC_FUNC_NAME;
                break;
              case RID_PRETTY_FUNCTION_NAME:
-               name = "%<__PRETTY_FUNCTION__%>";
+               name = NIC_PRETTY_FUNC;
                break;
              case RID_C99_FUNCTION_NAME:
-               name = "%<__func__%>";
+               name = NIC_C99_FUNC;
                break;
              default:
                gcc_unreachable ();
@@ -3355,20 +3763,20 @@ cp_parser_primary_expression (cp_parser *parser,
               `va_arg'.  Consume the `__builtin_va_arg' token.  */
            cp_lexer_consume_token (parser->lexer);
            /* Look for the opening `('.  */
-           cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+           cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
            /* Now, parse the assignment-expression.  */
            expression = cp_parser_assignment_expression (parser,
                                                          /*cast_p=*/false, NULL);
            /* Look for the `,'.  */
-           cp_parser_require (parser, CPP_COMMA, "%<,%>");
+           cp_parser_require (parser, CPP_COMMA, RT_COMMA);
            /* Parse the type-id.  */
            type = cp_parser_type_id (parser);
            /* Look for the closing `)'.  */
-           cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+           cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
            /* Using `va_arg' in a constant-expression is not
               allowed.  */
            if (cp_parser_non_integral_constant_expression (parser,
-                                                           "%<va_arg%>"))
+                                                           NIC_VA_ARG))
              return error_mark_node;
            return build_x_va_arg (expression, type);
          }
@@ -3392,6 +3800,8 @@ cp_parser_primary_expression (cp_parser *parser,
        case RID_IS_ENUM:
        case RID_IS_POD:
        case RID_IS_POLYMORPHIC:
+       case RID_IS_STD_LAYOUT:
+       case RID_IS_TRIVIAL:
        case RID_IS_UNION:
          return cp_parser_trait_expr (parser, token->keyword);
 
@@ -3401,6 +3811,16 @@ cp_parser_primary_expression (cp_parser *parser,
        case RID_AT_SELECTOR:
          return cp_parser_objc_expression (parser);
 
+       case RID_TEMPLATE:
+         if (parser->in_function_body
+             && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+                 == CPP_LESS))
+           {
+             error_at (token->location,
+                       "a template declaration cannot appear at block scope");
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             return error_mark_node;
+           }
        default:
          cp_parser_error (parser, "expected primary-expression");
          return error_mark_node;
@@ -3451,6 +3871,16 @@ cp_parser_primary_expression (cp_parser *parser,
          {
            tree ambiguous_decls;
 
+           /* If we already know that this lookup is ambiguous, then
+              we've already issued an error message; there's no reason
+              to check again.  */
+           if (id_expr_token->type == CPP_NAME
+               && id_expr_token->ambiguous_p)
+             {
+               cp_parser_simulate_error (parser);
+               return error_mark_node;
+             }
+
            decl = cp_parser_lookup_name (parser, id_expression,
                                          none_type,
                                          template_p,
@@ -3504,8 +3934,9 @@ cp_parser_primary_expression (cp_parser *parser,
                decl = check_for_out_of_scope_variable (decl);
                if (local_variable_p (decl))
                  {
-                   error ("%Hlocal variable %qD may not appear in this context",
-                          &id_expr_token->location, decl);
+                   error_at (id_expr_token->location,
+                             "local variable %qD may not appear in this context",
+                             decl);
                    return error_mark_node;
                  }
              }
@@ -3528,13 +3959,6 @@ cp_parser_primary_expression (cp_parser *parser,
 
       /* Anything else is an error.  */
     default:
-      /* ...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);
-
       cp_parser_error (parser, "expected primary-expression");
       return error_mark_node;
     }
@@ -3804,8 +4228,9 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
          {
            if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-             error ("%Hscope %qT before %<~%> is not a class-name",
-                    &token->location, scope);
+             error_at (token->location,
+                       "scope %qT before %<~%> is not a class-name",
+                       scope);
            cp_parser_simulate_error (parser);
            if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
              cp_lexer_consume_token (parser->lexer);
@@ -3813,20 +4238,26 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
        gcc_assert (!scope || TYPE_P (scope));
 
-       /* If the name is of the form "X::~X" it's OK.  */
+       /* If the name is of the form "X::~X" it's OK even if X is a
+          typedef.  */
        token = cp_lexer_peek_token (parser->lexer);
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
-               == CPP_OPEN_PAREN)
-           && constructor_name_p (token->u.value, scope))
+               != CPP_LESS)
+           && (token->u.value == TYPE_IDENTIFIER (scope)
+               || constructor_name_p (token->u.value, scope)))
          {
            cp_lexer_consume_token (parser->lexer);
            return build_nt (BIT_NOT_EXPR, scope);
          }
 
        /* If there was an explicit qualification (S::~T), first look
-          in the scope given by the qualification (i.e., S).  */
+          in the scope given by the qualification (i.e., S).
+
+          Note: in the calls to cp_parser_class_name below we pass
+          typename_type so that lookup finds the injected-class-name
+          rather than the constructor.  */
        done = false;
        type_decl = NULL_TREE;
        if (scope)
@@ -3835,7 +4266,7 @@ cp_parser_unqualified_id (cp_parser* parser,
            type_decl = cp_parser_class_name (parser,
                                              /*typename_keyword_p=*/false,
                                              /*template_keyword_p=*/false,
-                                             none_type,
+                                             typename_type,
                                              /*check_dependency=*/false,
                                              /*class_head_p=*/false,
                                              declarator_p);
@@ -3853,7 +4284,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3871,7 +4302,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3890,7 +4321,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3918,8 +4349,9 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (declarator_p && scope && !check_dtor_name (scope, type_decl))
          {
            if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-             error ("%Hdeclaration of %<~%T%> as member of %qT",
-                    &token->location, type_decl, scope);
+             error_at (token->location,
+                       "declaration of %<~%T%> as member of %qT",
+                       type_decl, scope);
            cp_parser_simulate_error (parser);
            return error_mark_node;
          }
@@ -3932,8 +4364,9 @@ cp_parser_unqualified_id (cp_parser* parser,
            && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
            && !DECL_SELF_REFERENCE_P (type_decl)
            && !cp_parser_uncommitted_to_tentative_parse_p (parser))
-         error ("%Htypedef-name %qD used as destructor declarator",
-                &token->location, type_decl);
+         error_at (token->location,
+                   "typedef-name %qD used as destructor declarator",
+                   type_decl);
 
        return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
       }
@@ -4106,7 +4539,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
                                        type_p,
                                        is_declaration);
       /* Look for the `::' token.  */
-      cp_parser_require (parser, CPP_SCOPE, "%<::%>");
+      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
 
       /* If we found what we wanted, we keep going; otherwise, we're
         done.  */
@@ -4146,23 +4579,27 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
                                                    &ambiguous_decls,
                                                    token->location);
                      if (TREE_CODE (decl) == TEMPLATE_DECL)
-                       error ("%H%qD used without template parameters",
-                              &token->location, decl);
+                       error_at (token->location,
+                                 "%qD used without template parameters",
+                                 decl);
                      else if (ambiguous_decls)
                        {
-                         error ("%Hreference to %qD is ambiguous",
-                                &token->location, token->u.value);
+                         error_at (token->location,
+                                   "reference to %qD is ambiguous",
+                                   token->u.value);
                          print_candidates (ambiguous_decls);
                          decl = error_mark_node;
                        }
                      else
                         {
-                          const char* msg = "is not a class or namespace";
                           if (cxx_dialect != cxx98)
-                            msg = "is not a class, namespace, or enumeration";
-                          cp_parser_name_lookup_error
-                            (parser, token->u.value, decl, msg,
+                            cp_parser_name_lookup_error
+                            (parser, token->u.value, decl, NLE_NOT_CXX98,
                             token->location);
+                         else
+                           cp_parser_name_lookup_error
+                           (parser, token->u.value, decl, NLE_CXX98,
+                            token->location);
                         }
                    }
                  parser->scope = error_mark_node;
@@ -4235,7 +4672,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
       token->type = CPP_NESTED_NAME_SPECIFIER;
       /* Retrieve any deferred checks.  Do not pop this access checks yet
         so the memory will not be reclaimed during token replacing below.  */
-      token->u.tree_check_value = GGC_CNEW (struct tree_check);
+      token->u.tree_check_value = ggc_alloc_cleared_tree_check ();
       token->u.tree_check_value->value = parser->scope;
       token->u.tree_check_value->checks = get_deferred_access_checks ();
       token->u.tree_check_value->qualifying_scope =
@@ -4349,6 +4786,16 @@ cp_parser_qualifying_entity (cp_parser *parser,
      
       /* Parse a typedef-name or enum-name.  */
       scope = cp_parser_nonclass_name (parser);
+
+      /* "If the name found does not designate a namespace or a class,
+        enumeration, or dependent type, the program is ill-formed."
+
+         We cover classes and dependent types above and namespaces below,
+         so this code is only looking for enums.  */
+      if (!scope || TREE_CODE (scope) != TYPE_DECL
+         || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE)
+       cp_parser_simulate_error (parser);
+
       successful_parse_p = cp_parser_parse_definitely (parser);
     }
   /* If that didn't work, try for a namespace-name.  */
@@ -4447,29 +4894,26 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* New types cannot be defined in the cast.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in casts";
+         = G_("types may not be defined in casts");
 
        /* Look for the opening `<'.  */
-       cp_parser_require (parser, CPP_LESS, "%<<%>");
+       cp_parser_require (parser, CPP_LESS, RT_LESS);
        /* Parse the type to which we are casting.  */
        type = cp_parser_type_id (parser);
        /* Look for the closing `>'.  */
-       cp_parser_require (parser, CPP_GREATER, "%<>%>");
+       cp_parser_require (parser, CPP_GREATER, RT_GREATER);
        /* Restore the old message.  */
        parser->type_definition_forbidden_message = saved_message;
 
        /* And the expression which is being cast.  */
-       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
        expression = cp_parser_expression (parser, /*cast_p=*/true, & idk);
-       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
        /* Only type conversions to integral or enumeration types
           can be used in constant-expressions.  */
        if (!cast_valid_in_integral_constant_expression_p (type)
-           && (cp_parser_non_integral_constant_expression
-               (parser,
-                "a cast to a type other than an integral or "
-                "enumeration type")))
+           && cp_parser_non_integral_constant_expression (parser, NIC_CAST))
          return error_mark_node;
 
        switch (keyword)
@@ -4506,11 +4950,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* Consume the `typeid' token.  */
        cp_lexer_consume_token (parser->lexer);
        /* Look for the `(' token.  */
-       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
        /* Types cannot be defined in a `typeid' expression.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in a %<typeid%> expression";
+         = G_("types may not be defined in a %<typeid%> expression");
        /* We can't be sure yet whether we're looking at a type-id or an
           expression.  */
        cp_parser_parse_tentatively (parser);
@@ -4522,7 +4966,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* Look for the `)' token.  Otherwise, we can't be sure that
           we're not looking at an expression: consider `typeid (int
           (3))', for example.  */
-       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
        /* If all went well, simply lookup the type-id.  */
        if (cp_parser_parse_definitely (parser))
          postfix_expression = get_typeid (type);
@@ -4536,13 +4980,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            /* Compute its typeid.  */
            postfix_expression = build_typeid (expression);
            /* Look for the `)' token.  */
-           cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+           cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
          }
        /* Restore the saved message.  */
        parser->type_definition_forbidden_message = saved_message;
        /* `typeid' may not appear in an integral constant expression.  */
-       if (cp_parser_non_integral_constant_expression(parser,
-                                                      "%<typeid%> operator"))
+       if (cp_parser_non_integral_constant_expression(parser, NIC_TYPEID))
          return error_mark_node;
       }
       break;
@@ -4597,9 +5040,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            type = cp_parser_type_id (parser);
            parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
            /* Look for the `)'.  */
-           cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+           cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
            /* Look for the `{'.  */
-           cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>");
+           cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
            /* If things aren't going well, there's no need to
               keep going.  */
            if (!cp_parser_error_occurred (parser))
@@ -4612,7 +5055,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
                  cp_lexer_consume_token (parser->lexer);
                /* Look for the final `}'.  */
-               cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+               cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
              }
            /* If that worked, we're definitely looking at a
               compound-literal expression.  */
@@ -4630,8 +5073,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                   currently accepted programs.  (Of course, as
                   compound literals are not part of ISO C++, the
                   standard has nothing to say.)  */
-               if (cp_parser_non_integral_constant_expression 
-                   (parser, "non-constant compound literals"))
+               if (cp_parser_non_integral_constant_expression (parser,
+                                                               NIC_NCC))
                  {
                    postfix_expression = error_mark_node;
                    break;
@@ -4685,7 +5128,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            bool is_builtin_constant_p;
            bool saved_integral_constant_expression_p = false;
            bool saved_non_integral_constant_expression_p = false;
-           tree args;
+           VEC(tree,gc) *args;
 
             is_member_access = false;
 
@@ -4702,7 +5145,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                parser->integral_constant_expression_p = false;
              }
            args = (cp_parser_parenthesized_expression_list
-                   (parser, /*is_attribute_list=*/false,
+                   (parser, non_attr,
                     /*cast_p=*/false, /*allow_expansion_p=*/true,
                     /*non_constant_p=*/NULL));
            if (is_builtin_constant_p)
@@ -4713,7 +5156,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  = saved_non_integral_constant_expression_p;
              }
 
-           if (args == error_mark_node)
+           if (args == NULL)
              {
                postfix_expression = error_mark_node;
                break;
@@ -4723,9 +5166,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
               constant-expressions.  */
            if (! builtin_valid_in_constant_expr_p (postfix_expression)
                && cp_parser_non_integral_constant_expression (parser,
-                                                              "a function call"))
+                                                              NIC_FUNC_CALL))
              {
                postfix_expression = error_mark_node;
+               release_tree_vector (args);
                break;
              }
 
@@ -4735,12 +5179,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
              {
                if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  {
-                   if (args)
+                   if (!VEC_empty (tree, args))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
                          postfix_expression
-                           = perform_koenig_lookup (postfix_expression, args);
+                           = perform_koenig_lookup (postfix_expression, args,
+                                                    /*include_std=*/false);
                      }
                    else
                      postfix_expression
@@ -4749,22 +5194,23 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                /* We do not perform argument-dependent lookup if
                   normal lookup finds a non-function, in accordance
                   with the expected resolution of DR 218.  */
-               else if (args && is_overloaded_fn (postfix_expression))
+               else if (!VEC_empty (tree, args)
+                        && is_overloaded_fn (postfix_expression))
                  {
                    tree fn = get_first_fn (postfix_expression);
+                   fn = STRIP_TEMPLATE (fn);
 
-                   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-                     fn = OVL_CURRENT (TREE_OPERAND (fn, 0));
-
-                   /* Only do argument dependent lookup if regular
-                      lookup does not find a set of member functions.
-                      [basic.lookup.koenig]/2a  */
-                   if (!DECL_FUNCTION_MEMBER_P (fn))
+                   /* Do not do argument dependent lookup if regular
+                      lookup finds a member function or a block-scope
+                      function declaration.  [basic.lookup.argdep]/3  */
+                   if (!DECL_FUNCTION_MEMBER_P (fn)
+                       && !DECL_LOCAL_FUNCTION_P (fn))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
                          postfix_expression
-                           = perform_koenig_lookup (postfix_expression, args);
+                           = perform_koenig_lookup (postfix_expression, args,
+                                                    /*include_std=*/false);
                      }
                  }
              }
@@ -4782,7 +5228,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                        || any_type_dependent_arguments_p (args)))
                  {
                    postfix_expression
-                     = build_nt_call_list (postfix_expression, args);
+                     = build_nt_call_vec (postfix_expression, args);
+                   release_tree_vector (args);
                    break;
                  }
 
@@ -4790,7 +5237,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  {
                  postfix_expression
                    = (build_new_method_call
-                      (instance, fn, args, NULL_TREE,
+                      (instance, fn, &args, NULL_TREE,
                        (idk == CP_ID_KIND_QUALIFIED
                         ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
                        /*fn_p=*/NULL,
@@ -4798,7 +5245,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                  }
                else
                  postfix_expression
-                   = finish_call_expr (postfix_expression, args,
+                   = finish_call_expr (postfix_expression, &args,
                                        /*disallow_virtual=*/false,
                                        /*koenig_p=*/false,
                                        tf_warning_or_error);
@@ -4807,25 +5254,27 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                     || TREE_CODE (postfix_expression) == MEMBER_REF
                     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
              postfix_expression = (build_offset_ref_call_from_tree
-                                   (postfix_expression, args));
+                                   (postfix_expression, &args));
            else if (idk == CP_ID_KIND_QUALIFIED)
              /* A call to a static class member, or a namespace-scope
                 function.  */
              postfix_expression
-               = finish_call_expr (postfix_expression, args,
+               = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/true,
                                    koenig_p,
                                    tf_warning_or_error);
            else
              /* All other function calls.  */
              postfix_expression
-               = finish_call_expr (postfix_expression, args,
+               = finish_call_expr (postfix_expression, &args,
                                    /*disallow_virtual=*/false,
                                    koenig_p,
                                    tf_warning_or_error);
 
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
+
+           release_tree_vector (args);
          }
          break;
 
@@ -4857,8 +5306,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            = finish_increment_expr (postfix_expression,
                                     POSTINCREMENT_EXPR);
          /* Increments may not appear in constant-expressions.  */
-         if (cp_parser_non_integral_constant_expression (parser,
-                                                         "an increment"))
+         if (cp_parser_non_integral_constant_expression (parser, NIC_INC))
            postfix_expression = error_mark_node;
          idk = CP_ID_KIND_NONE;
           is_member_access = false;
@@ -4873,8 +5321,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            = finish_increment_expr (postfix_expression,
                                     POSTDECREMENT_EXPR);
          /* Decrements may not appear in constant-expressions.  */
-         if (cp_parser_non_integral_constant_expression (parser,
-                                                         "a decrement"))
+         if (cp_parser_non_integral_constant_expression (parser, NIC_DEC))
            postfix_expression = error_mark_node;
          idk = CP_ID_KIND_NONE;
           is_member_access = false;
@@ -4927,7 +5374,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
     index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
   /* Look for the closing `]'.  */
-  cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
   /* Build the ARRAY_REF.  */
   postfix_expression = grok_array_decl (postfix_expression, index);
@@ -4935,8 +5382,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
   /* When not doing offsetof, array references are not permitted in
      constant-expressions.  */
   if (!for_offsetof
-      && (cp_parser_non_integral_constant_expression
-         (parser, "an array reference")))
+      && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
     postfix_expression = error_mark_node;
 
   return postfix_expression;
@@ -4993,7 +5439,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
       /* The type of the POSTFIX_EXPRESSION must be complete.  */
       if (scope == unknown_type_node)
        {
-         error ("%H%qE does not have class type", &location, postfix_expression);
+         error_at (location, "%qE does not have class type",
+                   postfix_expression);
          scope = NULL_TREE;
        }
       else
@@ -5077,7 +5524,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
         TYPE_DECL here.  That is invalid code.  */
       if (TREE_CODE (name) == TYPE_DECL)
        {
-         error ("%Hinvalid use of %qD", &token->location, name);
+         error_at (token->location, "invalid use of %qD", name);
          postfix_expression = error_mark_node;
        }
       else
@@ -5110,7 +5557,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
      constant-expressions.  */
   if (!for_offsetof
       && (cp_parser_non_integral_constant_expression
-         (parser, token_type == CPP_DEREF ? "%<->%>" : "%<.%>")))
+         (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
     postfix_expression = error_mark_node;
 
   return postfix_expression;
@@ -5132,25 +5579,25 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
    ALLOW_EXPANSION_P is true if this expression allows expansion of an
    argument pack.
 
-   Returns a TREE_LIST.  The TREE_VALUE of each node is a
-   representation of an assignment-expression.  Note that a TREE_LIST
-   is returned even if there is only a single expression in the list.
-   error_mark_node is returned if the ( and or ) are
-   missing. NULL_TREE is returned on no expressions. The parentheses
-   are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute
-   list being parsed.  If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P
-   indicates whether or not all of the expressions in the list were
-   constant.  */
-
-static tree
+   Returns a vector of trees.  Each element is a representation of an
+   assignment-expression.  NULL is returned if the ( and or ) are
+   missing.  An empty, but allocated, vector is returned on no
+   expressions.  The parentheses are eaten.  IS_ATTRIBUTE_LIST is id_attr
+   if we are parsing an attribute list for an attribute that wants a
+   plain identifier argument, normal_attr for an attribute that wants
+   an expression, or non_attr if we aren't parsing an attribute list.  If
+   NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
+   not all of the expressions in the list were constant.  */
+
+static VEC(tree,gc) *
 cp_parser_parenthesized_expression_list (cp_parser* parser,
-                                        bool is_attribute_list,
+                                        int is_attribute_list,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p)
 {
-  tree expression_list = NULL_TREE;
-  bool fold_expr_p = is_attribute_list;
+  VEC(tree,gc) *expression_list;
+  bool fold_expr_p = is_attribute_list != non_attr;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
 
@@ -5158,8 +5605,10 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
   if (non_constant_p)
     *non_constant_p = false;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
-    return error_mark_node;
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return NULL;
+
+  expression_list = make_tree_vector ();
 
   /* Within a parenthesized expression, a `>' token is always
      the greater-than operator.  */
@@ -5175,7 +5624,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 
        /* At the beginning of attribute lists, check to see if the
           next token is an identifier.  */
-       if (is_attribute_list
+       if (is_attribute_list == id_attr
            && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
          {
            cp_token *token;
@@ -5193,7 +5642,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
            if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
              {
                /* A braced-init-list.  */
-               maybe_warn_cpp0x ("extended initializer lists");
+               maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
                expr = cp_parser_braced_list (parser, &expr_non_constant_p);
                if (non_constant_p && expr_non_constant_p)
                  *non_constant_p = true;
@@ -5228,7 +5677,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
                expressions to the list, so that we can still tell if
                the correct form for a parenthesized expression-list
                is found. That gives better errors.  */
-           expression_list = tree_cons (NULL_TREE, expr, expression_list);
+           VEC_safe_push (tree, gc, expression_list, expr);
 
            if (expr == error_mark_node)
              goto skip_comma;
@@ -5236,7 +5685,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 
        /* After the first item, attribute lists look the same as
           expression lists.  */
-       is_attribute_list = false;
+       is_attribute_list = non_attr;
 
       get_comma:;
        /* If the next token isn't a `,', then we are done.  */
@@ -5247,7 +5696,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
        cp_lexer_consume_token (parser->lexer);
       }
 
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     {
       int ending;
 
@@ -5264,17 +5713,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
        {
          parser->greater_than_is_operator_p
            = saved_greater_than_is_operator_p;
-         return error_mark_node;
+         return NULL;
        }
     }
 
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
 
-  /* We built up the list in reverse order so we must reverse it now.  */
-  expression_list = nreverse (expression_list);
   if (identifier)
-    expression_list = tree_cons (NULL_TREE, identifier, expression_list);
+    VEC_safe_insert (tree, gc, expression_list, 0, identifier);
 
   return expression_list;
 }
@@ -5324,7 +5771,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
                             /*check_dependency_p=*/false,
                             /*is_declaration=*/true);
       /* Look for the `::' token.  */
-      cp_parser_require (parser, CPP_SCOPE, "%<::%>");
+      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
     }
   /* If the next token is not a `~', then there might be some
      additional qualification.  */
@@ -5350,13 +5797,13 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
        return;
 
       /* Look for the `::' token.  */
-      cp_parser_require (parser, CPP_SCOPE, "%<::%>");
+      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
     }
   else
     *scope = NULL_TREE;
 
   /* Look for the `~'.  */
-  cp_parser_require (parser, CPP_COMPL, "%<~%>");
+  cp_parser_require (parser, CPP_COMPL, RT_COMPL);
   /* Look for the type-name again.  We are not responsible for
      checking that it matches the first type-name.  */
   *type = cp_parser_nonclass_name (parser);
@@ -5463,6 +5910,51 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
          }
          break;
 
+       case RID_NOEXCEPT:
+         {
+           tree expr;
+           const char *saved_message;
+           bool saved_integral_constant_expression_p;
+           bool saved_non_integral_constant_expression_p;
+           bool saved_greater_than_is_operator_p;
+
+           cp_lexer_consume_token (parser->lexer);
+           cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+           saved_message = parser->type_definition_forbidden_message;
+           parser->type_definition_forbidden_message
+             = G_("types may not be defined in %<noexcept%> expressions");
+
+           saved_integral_constant_expression_p
+             = parser->integral_constant_expression_p;
+           saved_non_integral_constant_expression_p
+             = parser->non_integral_constant_expression_p;
+           parser->integral_constant_expression_p = false;
+
+           saved_greater_than_is_operator_p
+             = parser->greater_than_is_operator_p;
+           parser->greater_than_is_operator_p = true;
+
+           ++cp_unevaluated_operand;
+           ++c_inhibit_evaluation_warnings;
+           expr = cp_parser_expression (parser, false, NULL);
+           --c_inhibit_evaluation_warnings;
+           --cp_unevaluated_operand;
+
+           parser->greater_than_is_operator_p
+             = saved_greater_than_is_operator_p;
+
+           parser->integral_constant_expression_p
+             = saved_integral_constant_expression_p;
+           parser->non_integral_constant_expression_p
+             = saved_non_integral_constant_expression_p;
+
+           parser->type_definition_forbidden_message = saved_message;
+
+           cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+           return finish_noexcept_expr (expr, tf_warning_or_error);
+         }
+
        default:
          break;
        }
@@ -5512,7 +6004,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
          /* Create an expression representing the address.  */
          expression = finish_label_address_expr (identifier, loc);
          if (cp_parser_non_integral_constant_expression (parser,
-                                               "the address of a label"))
+                                                         NIC_ADDR_LABEL))
            expression = error_mark_node;
          return expression;
        }
@@ -5521,7 +6013,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
     {
       tree cast_expression;
       tree expression = error_mark_node;
-      const char *non_constant_p = NULL;
+      non_integral_constant non_constant_p = NIC_NONE;
 
       /* Consume the operator token.  */
       token = cp_lexer_consume_token (parser->lexer);
@@ -5534,13 +6026,13 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
       switch (unary_operator)
        {
        case INDIRECT_REF:
-         non_constant_p = "%<*%>";
-         expression = build_x_indirect_ref (cast_expression, "unary *",
+         non_constant_p = NIC_STAR;
+         expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
                                              tf_warning_or_error);
          break;
 
        case ADDR_EXPR:
-         non_constant_p = "%<&%>";
+          non_constant_p = NIC_ADDR;
          /* Fall through.  */
        case BIT_NOT_EXPR:
          expression = build_x_unary_op (unary_operator, cast_expression,
@@ -5549,8 +6041,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
 
        case PREINCREMENT_EXPR:
        case PREDECREMENT_EXPR:
-         non_constant_p = (unary_operator == PREINCREMENT_EXPR
-                           ? "%<++%>" : "%<--%>");
+         non_constant_p = unary_operator == PREINCREMENT_EXPR
+                          ? NIC_PREINCREMENT : NIC_PREDECREMENT;
          /* Fall through.  */
        case UNARY_PLUS_EXPR:
        case NEGATE_EXPR:
@@ -5562,7 +6054,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
          gcc_unreachable ();
        }
 
-      if (non_constant_p
+      if (non_constant_p != NIC_NONE
          && cp_parser_non_integral_constant_expression (parser,
                                                         non_constant_p))
        expression = error_mark_node;
@@ -5618,10 +6110,11 @@ static tree
 cp_parser_new_expression (cp_parser* parser)
 {
   bool global_scope_p;
-  tree placement;
+  VEC(tree,gc) *placement;
   tree type;
-  tree initializer;
+  VEC(tree,gc) *initializer;
   tree nelts;
+  tree ret;
 
   /* Look for the optional `::' operator.  */
   global_scope_p
@@ -5629,7 +6122,7 @@ cp_parser_new_expression (cp_parser* parser)
                                   /*current_scope_valid_p=*/false)
        != NULL_TREE);
   /* Look for the `new' operator.  */
-  cp_parser_require_keyword (parser, RID_NEW, "%<new%>");
+  cp_parser_require_keyword (parser, RID_NEW, RT_NEW);
   /* There's no easy way to tell a new-placement from the
      `( type-id )' construct.  */
   cp_parser_parse_tentatively (parser);
@@ -5637,7 +6130,11 @@ cp_parser_new_expression (cp_parser* parser)
   placement = cp_parser_new_placement (parser);
   /* If that didn't work out, there's no new-placement.  */
   if (!cp_parser_parse_definitely (parser))
-    placement = NULL_TREE;
+    {
+      if (placement != NULL)
+       release_tree_vector (placement);
+      placement = NULL;
+    }
 
   /* If the next token is a `(', then we have a parenthesized
      type-id.  */
@@ -5649,15 +6146,15 @@ cp_parser_new_expression (cp_parser* parser)
       /* Parse the type-id.  */
       type = cp_parser_type_id (parser);
       /* Look for the closing `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       token = cp_lexer_peek_token (parser->lexer);
       /* There should not be a direct-new-declarator in this production,
         but GCC used to allowed this, so we check and emit a sensible error
         message for this case.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
        {
-         error ("%Harray bound forbidden after parenthesized type-id",
-                &token->location);
+         error_at (token->location,
+                   "array bound forbidden after parenthesized type-id");
          inform (token->location, 
                  "try removing the parentheses around the type-id");
          cp_parser_direct_new_declarator (parser);
@@ -5673,16 +6170,25 @@ cp_parser_new_expression (cp_parser* parser)
       || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     initializer = cp_parser_new_initializer (parser);
   else
-    initializer = NULL_TREE;
+    initializer = NULL;
 
   /* A new-expression may not appear in an integral constant
      expression.  */
-  if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
-    return error_mark_node;
+  if (cp_parser_non_integral_constant_expression (parser, NIC_NEW))
+    ret = error_mark_node;
+  else
+    {
+      /* Create a representation of the new-expression.  */
+      ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
+                      tf_warning_or_error);
+    }
 
-  /* Create a representation of the new-expression.  */
-  return build_new (placement, type, nelts, initializer, global_scope_p,
-                    tf_warning_or_error);
+  if (placement != NULL)
+    release_tree_vector (placement);
+  if (initializer != NULL)
+    release_tree_vector (initializer);
+
+  return ret;
 }
 
 /* Parse a new-placement.
@@ -5692,14 +6198,15 @@ cp_parser_new_expression (cp_parser* parser)
 
    Returns the same representation as for an expression-list.  */
 
-static tree
+static VEC(tree,gc) *
 cp_parser_new_placement (cp_parser* parser)
 {
-  tree expression_list;
+  VEC(tree,gc) *expression_list;
 
   /* Parse the expression-list.  */
   expression_list = (cp_parser_parenthesized_expression_list
-                    (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+                    (parser, non_attr, /*cast_p=*/false,
+                     /*allow_expansion_p=*/true,
                      /*non_constant_p=*/NULL));
 
   return expression_list;
@@ -5730,9 +6237,10 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
      complete.)  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in a new-type-id";
+    = G_("types may not be defined in a new-type-id");
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               /*is_trailing_return=*/false,
                                &type_specifier_seq);
   /* Restore the old message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -5832,7 +6340,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
       tree expression;
 
       /* Look for the opening `['.  */
-      cp_parser_require (parser, CPP_OPEN_SQUARE, "%<[%>");
+      cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
       /* The first expression is not required to be constant.  */
       if (!declarator)
        {
@@ -5852,8 +6360,9 @@ cp_parser_direct_new_declarator (cp_parser* parser)
                                              /*complain=*/true);
              if (!expression)
                {
-                 error ("%Hexpression in new-declarator must have integral "
-                        "or enumeration type", &token->location);
+                 error_at (token->location,
+                           "expression in new-declarator must have integral "
+                           "or enumeration type");
                  expression = error_mark_node;
                }
            }
@@ -5865,7 +6374,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
                                           /*allow_non_constant=*/false,
                                           NULL);
       /* Look for the closing `]'.  */
-      cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
       /* Add this bound to the declarator.  */
       declarator = make_array_declarator (declarator, expression);
@@ -5885,28 +6394,27 @@ cp_parser_direct_new_declarator (cp_parser* parser)
      ( expression-list [opt] )
      braced-init-list
 
-   Returns a representation of the expression-list.  If there is no
-   expression-list, VOID_ZERO_NODE is returned.  */
+   Returns a representation of the expression-list.  */
 
-static tree
+static VEC(tree,gc) *
 cp_parser_new_initializer (cp_parser* parser)
 {
-  tree expression_list;
+  VEC(tree,gc) *expression_list;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
+      tree t;
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
-      expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
-      CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
-      expression_list = build_tree_list (NULL_TREE, expression_list);
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+      t = cp_parser_braced_list (parser, &expr_non_constant_p);
+      CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
+      expression_list = make_tree_vector_single (t);
     }
   else
     expression_list = (cp_parser_parenthesized_expression_list
-                      (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+                      (parser, non_attr, /*cast_p=*/false,
+                       /*allow_expansion_p=*/true,
                        /*non_constant_p=*/NULL));
-  if (!expression_list)
-    expression_list = void_zero_node;
 
   return expression_list;
 }
@@ -5932,14 +6440,14 @@ cp_parser_delete_expression (cp_parser* parser)
                                   /*current_scope_valid_p=*/false)
        != NULL_TREE);
   /* Look for the `delete' keyword.  */
-  cp_parser_require_keyword (parser, RID_DELETE, "%<delete%>");
+  cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE);
   /* See if the array syntax is in use.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
     {
       /* Consume the `[' token.  */
       cp_lexer_consume_token (parser->lexer);
       /* Look for the `]' token.  */
-      cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
       /* Remember that this is the `[]' construct.  */
       array_p = true;
     }
@@ -5951,7 +6459,7 @@ cp_parser_delete_expression (cp_parser* parser)
 
   /* A delete-expression may not appear in an integral constant
      expression.  */
-  if (cp_parser_non_integral_constant_expression (parser, "%<delete%>"))
+  if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
     return error_mark_node;
 
   return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
@@ -6043,7 +6551,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
       /* Types may not be defined in a cast.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in casts";
+       = G_("types may not be defined in casts");
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
       /* A very tricky bit is that `(struct S) { 3 }' is a
@@ -6084,7 +6592,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
          /* Look for the type-id.  */
          type = cp_parser_type_id (parser);
          /* Look for the closing `)'.  */
-         cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+         cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
          parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
        }
 
@@ -6113,14 +6621,12 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
          /* Only type conversions to integral or enumeration types
             can be used in constant-expressions.  */
          if (!cast_valid_in_integral_constant_expression_p (type)
-             && (cp_parser_non_integral_constant_expression
-                 (parser,
-                  "a cast to a type other than an integral or "
-                  "enumeration type")))
+             && cp_parser_non_integral_constant_expression (parser,
+                                                            NIC_CAST))
            return error_mark_node;
 
          /* Perform the cast.  */
-         expr = build_c_cast (type, expr);
+         expr = build_c_cast (input_location, type, expr);
          return expr;
        }
       else 
@@ -6238,11 +6744,11 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
           && token->type == CPP_RSHIFT
           && !parser->greater_than_is_operator_p)
         {
-          warning (OPT_Wc__0x_compat, 
-                   "%H%<>>%> operator will be treated as two right angle brackets in C++0x", 
-                   &token->location);
-          warning (OPT_Wc__0x_compat, 
-                   "suggest parentheses around %<>>%> expression");
+          if (warning_at (token->location, OPT_Wc__0x_compat, 
+                         "%<>>%> operator will be treated as"
+                         " two right angle brackets in C++0x"))
+           inform (token->location,
+                   "suggest parentheses around %<>>%> expression");
         }
 
       new_prec = TOKEN_PRECEDENCE (token);
@@ -6268,6 +6774,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
       /* We used the operator token.  */
       cp_lexer_consume_token (parser->lexer);
 
+      /* For "false && x" or "true || x", x will never be executed;
+        disable warnings while evaluating it.  */
+      if (tree_type == TRUTH_ANDIF_EXPR)
+       c_inhibit_evaluation_warnings += lhs == truthvalue_false_node;
+      else if (tree_type == TRUTH_ORIF_EXPR)
+       c_inhibit_evaluation_warnings += lhs == truthvalue_true_node;
+
       /* Extract another operand.  It may be the RHS of this expression
         or the LHS of a new, higher priority expression.  */
       rhs = cp_parser_simple_cast_expression (parser);
@@ -6313,6 +6826,12 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
          lhs_type = sp->lhs_type;
        }
 
+      /* Undo the disabling of warnings done above.  */
+      if (tree_type == TRUTH_ANDIF_EXPR)
+       c_inhibit_evaluation_warnings -= lhs == truthvalue_false_node;
+      else if (tree_type == TRUTH_ORIF_EXPR)
+       c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node;
+
       overloaded_p = false;
       /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
         ERROR_MARK for everything that is not a binary expression.
@@ -6338,8 +6857,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
         least one of the operands is of enumeration type.  */
 
       if (overloaded_p
-         && (cp_parser_non_integral_constant_expression
-             (parser, "calls to overloaded operators")))
+         && cp_parser_non_integral_constant_expression (parser,
+                                                        NIC_OVERLOADED))
        return error_mark_node;
     }
 
@@ -6365,21 +6884,36 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
 {
   tree expr;
   tree assignment_expr;
+  struct cp_token *token;
 
   /* Consume the `?' token.  */
   cp_lexer_consume_token (parser->lexer);
+  token = cp_lexer_peek_token (parser->lexer);
   if (cp_parser_allow_gnu_extensions_p (parser)
-      && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-    /* Implicit true clause.  */
-    expr = NULL_TREE;
+      && token->type == CPP_COLON)
+    {
+      pedwarn (token->location, OPT_pedantic, 
+               "ISO C++ does not allow ?: with omitted middle operand");
+      /* Implicit true clause.  */
+      expr = NULL_TREE;
+      c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
+      warn_for_omitted_condop (token->location, logical_or_expr);
+    }
   else
-    /* Parse the expression.  */
-    expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+    {
+      /* Parse the expression.  */
+      c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node;
+      expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      c_inhibit_evaluation_warnings +=
+       ((logical_or_expr == truthvalue_true_node)
+        - (logical_or_expr == truthvalue_false_node));
+    }
 
   /* The next token should be a `:'.  */
-  cp_parser_require (parser, CPP_COLON, "%<:%>");
+  cp_parser_require (parser, CPP_COLON, RT_COLON);
   /* Parse the assignment-expression.  */
   assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+  c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node;
 
   /* Build the conditional-expression.  */
   return build_x_conditional_expr (logical_or_expr,
@@ -6436,12 +6970,12 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
              tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
 
              if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
-               maybe_warn_cpp0x ("extended initializer lists");
+               maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
              /* An assignment may not appear in a
                 constant-expression.  */
              if (cp_parser_non_integral_constant_expression (parser,
-                                                             "an assignment"))
+                                                             NIC_ASSIGNMENT))
                return error_mark_node;
              /* Build the assignment expression.  */
              expr = build_x_modify_expr (expr,
@@ -6576,8 +7110,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
       /* Consume the `,'.  */
       cp_lexer_consume_token (parser->lexer);
       /* A comma operator cannot appear in a constant-expression.  */
-      if (cp_parser_non_integral_constant_expression (parser,
-                                                     "a comma operator"))
+      if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
        expression = error_mark_node;
     }
 
@@ -6683,11 +7216,11 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   /* Consume the "__builtin_offsetof" token.  */
   cp_lexer_consume_token (parser->lexer);
   /* Consume the opening `('.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   /* Parse the type-id.  */
   type = cp_parser_type_id (parser);
   /* Look for the `,'.  */
-  cp_parser_require (parser, CPP_COMMA, "%<,%>");
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   token = cp_lexer_peek_token (parser->lexer);
 
   /* Build the (type *)null that begins the traditional offsetof macro.  */
@@ -6728,7 +7261,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
        default:
          /* Error.  We know the following require will fail, but
             that gives the proper error message.  */
-         cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+         cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
          cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
          expr = error_mark_node;
          goto failure;
@@ -6812,6 +7345,12 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     case RID_IS_POLYMORPHIC:
       kind = CPTK_IS_POLYMORPHIC;
       break;
+    case RID_IS_STD_LAYOUT:
+      kind = CPTK_IS_STD_LAYOUT;
+      break;
+    case RID_IS_TRIVIAL:
+      kind = CPTK_IS_TRIVIAL;
+      break;
     case RID_IS_UNION:
       kind = CPTK_IS_UNION;
       break;
@@ -6822,7 +7361,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
   /* Consume the token.  */
   cp_lexer_consume_token (parser->lexer);
 
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
   type1 = cp_parser_type_id (parser);
 
@@ -6839,7 +7378,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
 
   if (binary)
     {
-      cp_parser_require (parser, CPP_COMMA, "%<,%>");
+      cp_parser_require (parser, CPP_COMMA, RT_COMMA);
  
       type2 = cp_parser_type_id (parser);
 
@@ -6855,88 +7394,605 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
                              /*initialized=*/0, /*attrlist=*/NULL);
     }
 
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   /* Complete the trait expression, which may mean either processing
      the trait expr now or saving it for template instantiation.  */
   return finish_trait_expr (kind, type1, type2);
 }
 
-/* Statements [gram.stmt.stmt]  */
-
-/* Parse a statement.
-
-   statement:
-     labeled-statement
-     expression-statement
-     compound-statement
-     selection-statement
-     iteration-statement
-     jump-statement
-     declaration-statement
-     try-block
-
-  IN_COMPOUND is true when the statement is nested inside a
-  cp_parser_compound_statement; this matters for certain pragmas.
+/* Lambdas that appear in variable initializer or default argument scope
+   get that in their mangling, so we need to record it.  We might as well
+   use the count for function and namespace scopes as well.  */
+static GTY(()) tree lambda_scope;
+static GTY(()) int lambda_count;
+typedef struct GTY(()) tree_int
+{
+  tree t;
+  int i;
+} tree_int;
+DEF_VEC_O(tree_int);
+DEF_VEC_ALLOC_O(tree_int,gc);
+static GTY(()) VEC(tree_int,gc) *lambda_scope_stack;
 
-  If IF_P is not NULL, *IF_P is set to indicate whether the statement
-  is a (possibly labeled) if statement which is not enclosed in braces
-  and has an else clause.  This is used to implement -Wparentheses.  */
+static void
+start_lambda_scope (tree decl)
+{
+  tree_int ti;
+  gcc_assert (decl);
+  /* Once we're inside a function, we ignore other scopes and just push
+     the function again so that popping works properly.  */
+  if (current_function_decl && TREE_CODE (decl) != FUNCTION_DECL)
+    decl = current_function_decl;
+  ti.t = lambda_scope;
+  ti.i = lambda_count;
+  VEC_safe_push (tree_int, gc, lambda_scope_stack, &ti);
+  if (lambda_scope != decl)
+    {
+      /* Don't reset the count if we're still in the same function.  */
+      lambda_scope = decl;
+      lambda_count = 0;
+    }
+}
 
 static void
-cp_parser_statement (cp_parser* parser, tree in_statement_expr,
-                    bool in_compound, bool *if_p)
+record_lambda_scope (tree lambda)
 {
-  tree statement;
-  cp_token *token;
-  location_t statement_location;
+  LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
+  LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
+}
 
- restart:
-  if (if_p != NULL)
-    *if_p = false;
-  /* There is no statement yet.  */
-  statement = NULL_TREE;
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  /* Remember the location of the first token in the statement.  */
-  statement_location = token->location;
-  /* If this is a keyword, then that will often determine what kind of
-     statement we have.  */
-  if (token->type == CPP_KEYWORD)
+static void
+finish_lambda_scope (void)
+{
+  tree_int *p = VEC_last (tree_int, lambda_scope_stack);
+  if (lambda_scope != p->t)
     {
-      enum rid keyword = token->keyword;
+      lambda_scope = p->t;
+      lambda_count = p->i;
+    }
+  VEC_pop (tree_int, lambda_scope_stack);
+}
 
-      switch (keyword)
-       {
-       case RID_CASE:
-       case RID_DEFAULT:
-         /* Looks like a labeled-statement with a case label.
-            Parse the label, and then use tail recursion to parse
-            the statement.  */
-         cp_parser_label_for_labeled_statement (parser);
-         goto restart;
+/* Parse a lambda expression.
 
-       case RID_IF:
-       case RID_SWITCH:
-         statement = cp_parser_selection_statement (parser, if_p);
-         break;
+   lambda-expression:
+     lambda-introducer lambda-declarator [opt] compound-statement
 
-       case RID_WHILE:
-       case RID_DO:
-       case RID_FOR:
-         statement = cp_parser_iteration_statement (parser);
-         break;
+   Returns a representation of the expression.  */
 
-       case RID_BREAK:
-       case RID_CONTINUE:
-       case RID_RETURN:
-       case RID_GOTO:
-         statement = cp_parser_jump_statement (parser);
-         break;
+static tree
+cp_parser_lambda_expression (cp_parser* parser)
+{
+  tree lambda_expr = build_lambda_expr ();
+  tree type;
 
-         /* Objective-C++ exception-handling constructs.  */
-       case RID_AT_TRY:
-       case RID_AT_CATCH:
+  LAMBDA_EXPR_LOCATION (lambda_expr)
+    = cp_lexer_peek_token (parser->lexer)->location;
+
+  if (cp_unevaluated_operand)
+    error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
+             "lambda-expression in unevaluated context");
+
+  /* We may be in the middle of deferred access check.  Disable
+     it now.  */
+  push_deferring_access_checks (dk_no_deferred);
+
+  cp_parser_lambda_introducer (parser, lambda_expr);
+
+  type = begin_lambda_type (lambda_expr);
+
+  record_lambda_scope (lambda_expr);
+
+  /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
+  determine_visibility (TYPE_NAME (type));
+
+  /* Now that we've started the type, add the capture fields for any
+     explicit captures.  */
+  register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
+  {
+    /* Inside the class, surrounding template-parameter-lists do not apply.  */
+    unsigned int saved_num_template_parameter_lists
+        = parser->num_template_parameter_lists;
+
+    parser->num_template_parameter_lists = 0;
+
+    /* By virtue of defining a local class, a lambda expression has access to
+       the private variables of enclosing classes.  */
+
+    cp_parser_lambda_declarator_opt (parser, lambda_expr);
+
+    cp_parser_lambda_body (parser, lambda_expr);
+
+    /* The capture list was built up in reverse order; fix that now.  */
+    {
+      tree newlist = NULL_TREE;
+      tree elt, next;
+
+      for (elt = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr);
+          elt; elt = next)
+       {
+         tree field = TREE_PURPOSE (elt);
+         char *buf;
+
+         next = TREE_CHAIN (elt);
+         TREE_CHAIN (elt) = newlist;
+         newlist = elt;
+
+         /* Also add __ to the beginning of the field name so that code
+            outside the lambda body can't see the captured name.  We could
+            just remove the name entirely, but this is more useful for
+            debugging.  */
+         if (field == LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
+           /* The 'this' capture already starts with __.  */
+           continue;
+
+         buf = (char *) alloca (IDENTIFIER_LENGTH (DECL_NAME (field)) + 3);
+         buf[1] = buf[0] = '_';
+         memcpy (buf + 2, IDENTIFIER_POINTER (DECL_NAME (field)),
+                 IDENTIFIER_LENGTH (DECL_NAME (field)) + 1);
+         DECL_NAME (field) = get_identifier (buf);
+       }
+      LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
+    }
+
+    maybe_add_lambda_conv_op (type);
+
+    type = finish_struct (type, /*attributes=*/NULL_TREE);
+
+    parser->num_template_parameter_lists = saved_num_template_parameter_lists;
+  }
+
+  pop_deferring_access_checks ();
+
+  return build_lambda_object (lambda_expr);
+}
+
+/* Parse the beginning of a lambda expression.
+
+   lambda-introducer:
+     [ lambda-capture [opt] ]
+
+   LAMBDA_EXPR is the current representation of the lambda expression.  */
+
+static void
+cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
+{
+  /* Need commas after the first capture.  */
+  bool first = true;
+
+  /* Eat the leading `['.  */
+  cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
+
+  /* Record default capture mode.  "[&" "[=" "[&," "[=,"  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
+      && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_NAME)
+    LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
+  else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+    LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;
+
+  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE)
+    {
+      cp_lexer_consume_token (parser->lexer);
+      first = false;
+    }
+
+  while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
+    {
+      cp_token* capture_token;
+      tree capture_id;
+      tree capture_init_expr;
+      cp_id_kind idk = CP_ID_KIND_NONE;
+      bool explicit_init_p = false;
+
+      enum capture_kind_type
+      {
+       BY_COPY,
+       BY_REFERENCE
+      };
+      enum capture_kind_type capture_kind = BY_COPY;
+
+      if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+       {
+         error ("expected end of capture-list");
+         return;
+       }
+
+      if (first)
+       first = false;
+      else
+       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+
+      /* Possibly capture `this'.  */
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS))
+       {
+         cp_lexer_consume_token (parser->lexer);
+         add_capture (lambda_expr,
+                      /*id=*/get_identifier ("__this"),
+                      /*initializer=*/finish_this_expr(),
+                      /*by_reference_p=*/false,
+                      explicit_init_p);
+         continue;
+       }
+
+      /* Remember whether we want to capture as a reference or not.  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_AND))
+       {
+         capture_kind = BY_REFERENCE;
+         cp_lexer_consume_token (parser->lexer);
+       }
+
+      /* Get the identifier.  */
+      capture_token = cp_lexer_peek_token (parser->lexer);
+      capture_id = cp_parser_identifier (parser);
+
+      if (capture_id == error_mark_node)
+       /* Would be nice to have a cp_parser_skip_to_closing_x for general
+           delimiters, but I modified this to stop on unnested ']' as well.  It
+           was already changed to stop on unnested '}', so the
+           "closing_parenthesis" name is no more misleading with my change.  */
+       {
+         cp_parser_skip_to_closing_parenthesis (parser,
+                                                /*recovering=*/true,
+                                                /*or_comma=*/true,
+                                                /*consume_paren=*/true);
+         break;
+       }
+
+      /* Find the initializer for this capture.  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+       {
+         /* An explicit expression exists.  */
+         cp_lexer_consume_token (parser->lexer);
+          pedwarn (input_location, OPT_pedantic,
+                   "ISO C++ does not allow initializers "
+                   "in lambda expression capture lists");
+         capture_init_expr = cp_parser_assignment_expression (parser,
+                                                              /*cast_p=*/true,
+                                                              &idk);
+         explicit_init_p = true;
+       }
+      else
+       {
+         const char* error_msg;
+
+         /* Turn the identifier into an id-expression.  */
+         capture_init_expr
+            = cp_parser_lookup_name
+                (parser,
+                capture_id,
+                 none_type,
+                 /*is_template=*/false,
+                 /*is_namespace=*/false,
+                 /*check_dependency=*/true,
+                 /*ambiguous_decls=*/NULL,
+                 capture_token->location);
+
+         capture_init_expr
+            = finish_id_expression
+                (capture_id,
+                capture_init_expr,
+                 parser->scope,
+                 &idk,
+                 /*integral_constant_expression_p=*/false,
+                 /*allow_non_integral_constant_expression_p=*/false,
+                 /*non_integral_constant_expression_p=*/NULL,
+                 /*template_p=*/false,
+                 /*done=*/true,
+                 /*address_p=*/false,
+                 /*template_arg_p=*/false,
+                 &error_msg,
+                 capture_token->location);
+       }
+
+      if (TREE_CODE (capture_init_expr) == IDENTIFIER_NODE)
+       capture_init_expr
+         = unqualified_name_lookup_error (capture_init_expr);
+
+      add_capture (lambda_expr,
+                  capture_id,
+                  capture_init_expr,
+                  /*by_reference_p=*/capture_kind == BY_REFERENCE,
+                  explicit_init_p);
+    }
+
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+}
+
+/* Parse the (optional) middle of a lambda expression.
+
+   lambda-declarator:
+     ( parameter-declaration-clause [opt] )
+       attribute-specifier [opt]
+       mutable [opt]
+       exception-specification [opt]
+       lambda-return-type-clause [opt]
+
+   LAMBDA_EXPR is the current representation of the lambda expression.  */
+
+static void
+cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
+{
+  /* 5.1.1.4 of the standard says:
+       If a lambda-expression does not include a lambda-declarator, it is as if
+       the lambda-declarator were ().
+     This means an empty parameter list, no attributes, and no exception
+     specification.  */
+  tree param_list = void_list_node;
+  tree attributes = NULL_TREE;
+  tree exception_spec = NULL_TREE;
+  tree t;
+
+  /* The lambda-declarator is optional, but must begin with an opening
+     parenthesis if present.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+    {
+      cp_lexer_consume_token (parser->lexer);
+
+      begin_scope (sk_function_parms, /*entity=*/NULL_TREE);
+
+      /* Parse parameters.  */
+      param_list = cp_parser_parameter_declaration_clause (parser);
+
+      /* Default arguments shall not be specified in the
+        parameter-declaration-clause of a lambda-declarator.  */
+      for (t = param_list; t; t = TREE_CHAIN (t))
+       if (TREE_PURPOSE (t))
+         pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_pedantic,
+                  "default argument specified for lambda parameter");
+
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+      attributes = cp_parser_attributes_opt (parser);
+
+      /* Parse optional `mutable' keyword.  */
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_MUTABLE))
+        {
+          cp_lexer_consume_token (parser->lexer);
+          LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
+        }
+
+      /* Parse optional exception specification.  */
+      exception_spec = cp_parser_exception_specification_opt (parser);
+
+      /* Parse optional trailing return type.  */
+      if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
+        {
+          cp_lexer_consume_token (parser->lexer);
+          LAMBDA_EXPR_RETURN_TYPE (lambda_expr) = cp_parser_type_id (parser);
+        }
+
+      /* The function parameters must be in scope all the way until after the
+         trailing-return-type in case of decltype.  */
+      for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
+       pop_binding (DECL_NAME (t), t);
+
+      leave_scope ();
+    }
+
+  /* Create the function call operator.
+
+     Messing with declarators like this is no uglier than building up the
+     FUNCTION_DECL by hand, and this is less likely to get out of sync with
+     other code.  */
+  {
+    cp_decl_specifier_seq return_type_specs;
+    cp_declarator* declarator;
+    tree fco;
+    int quals;
+    void *p;
+
+    clear_decl_specs (&return_type_specs);
+    if (LAMBDA_EXPR_RETURN_TYPE (lambda_expr))
+      return_type_specs.type = LAMBDA_EXPR_RETURN_TYPE (lambda_expr);
+    else
+      /* Maybe we will deduce the return type later, but we can use void
+        as a placeholder return type anyways.  */
+      return_type_specs.type = void_type_node;
+
+    p = obstack_alloc (&declarator_obstack, 0);
+
+    declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
+                                    sfk_none);
+
+    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
+            ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
+    declarator = make_call_declarator (declarator, param_list, quals,
+                                      exception_spec,
+                                       /*late_return_type=*/NULL_TREE);
+    declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
+
+    fco = grokmethod (&return_type_specs,
+                     declarator,
+                     attributes);
+    DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
+    DECL_ARTIFICIAL (fco) = 1;
+
+    finish_member_declaration (fco);
+
+    obstack_free (&declarator_obstack, p);
+  }
+}
+
+/* Parse the body of a lambda expression, which is simply
+
+   compound-statement
+
+   but which requires special handling.
+   LAMBDA_EXPR is the current representation of the lambda expression.  */
+
+static void
+cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
+{
+  bool nested = (current_function_decl != NULL_TREE);
+  if (nested)
+    push_function_context ();
+
+  /* Finish the function call operator
+     - class_specifier
+     + late_parsing_for_member
+     + function_definition_after_declarator
+     + ctor_initializer_opt_and_function_body  */
+  {
+    tree fco = lambda_function (lambda_expr);
+    tree body;
+    bool done = false;
+
+    /* Let the front end know that we are going to be defining this
+       function.  */
+    start_preparsed_function (fco,
+                             NULL_TREE,
+                             SF_PRE_PARSED | SF_INCLASS_INLINE);
+
+    start_lambda_scope (fco);
+    body = begin_function_body ();
+
+    /* 5.1.1.4 of the standard says:
+         If a lambda-expression does not include a trailing-return-type, it
+         is as if the trailing-return-type denotes the following type:
+         * if the compound-statement is of the form
+               { return attribute-specifier [opt] expression ; }
+             the type of the returned expression after lvalue-to-rvalue
+             conversion (_conv.lval_ 4.1), array-to-pointer conversion
+             (_conv.array_ 4.2), and function-to-pointer conversion
+             (_conv.func_ 4.3);
+          * otherwise, void.  */
+
+    /* In a lambda that has neither a lambda-return-type-clause
+       nor a deducible form, errors should be reported for return statements
+       in the body.  Since we used void as the placeholder return type, parsing
+       the body as usual will give such desired behavior.  */
+    if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)
+        && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+        && cp_lexer_peek_nth_token (parser->lexer, 2)->keyword == RID_RETURN
+        && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_SEMICOLON)
+      {
+       tree compound_stmt;
+       tree expr = NULL_TREE;
+       cp_id_kind idk = CP_ID_KIND_NONE;
+
+       /* Parse tentatively in case there's more after the initial return
+          statement.  */
+       cp_parser_parse_tentatively (parser);
+
+       cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+       cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN);
+
+       expr = cp_parser_expression (parser, /*cast_p=*/false, &idk);
+
+       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+       cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+
+       if (cp_parser_parse_definitely (parser))
+         {
+           apply_lambda_return_type (lambda_expr, lambda_return_type (expr));
+
+           compound_stmt = begin_compound_stmt (0);
+           /* Will get error here if type not deduced yet.  */
+           finish_return_stmt (expr);
+           finish_compound_stmt (compound_stmt);
+
+           done = true;
+         }
+      }
+
+    if (!done)
+      {
+       if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr))
+         LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = true;
+       /* TODO: does begin_compound_stmt want BCS_FN_BODY?
+          cp_parser_compound_stmt does not pass it.  */
+       cp_parser_function_body (parser);
+       LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false;
+      }
+
+    finish_function_body (body);
+    finish_lambda_scope ();
+
+    /* Finish the function and generate code for it if necessary.  */
+    expand_or_defer_fn (finish_function (/*inline*/2));
+  }
+
+  if (nested)
+    pop_function_context();
+}
+
+/* Statements [gram.stmt.stmt]  */
+
+/* Parse a statement.
+
+   statement:
+     labeled-statement
+     expression-statement
+     compound-statement
+     selection-statement
+     iteration-statement
+     jump-statement
+     declaration-statement
+     try-block
+
+  IN_COMPOUND is true when the statement is nested inside a
+  cp_parser_compound_statement; this matters for certain pragmas.
+
+  If IF_P is not NULL, *IF_P is set to indicate whether the statement
+  is a (possibly labeled) if statement which is not enclosed in braces
+  and has an else clause.  This is used to implement -Wparentheses.  */
+
+static void
+cp_parser_statement (cp_parser* parser, tree in_statement_expr,
+                    bool in_compound, bool *if_p)
+{
+  tree statement;
+  cp_token *token;
+  location_t statement_location;
+
+ restart:
+  if (if_p != NULL)
+    *if_p = false;
+  /* There is no statement yet.  */
+  statement = NULL_TREE;
+  /* Peek at the next token.  */
+  token = cp_lexer_peek_token (parser->lexer);
+  /* Remember the location of the first token in the statement.  */
+  statement_location = token->location;
+  /* If this is a keyword, then that will often determine what kind of
+     statement we have.  */
+  if (token->type == CPP_KEYWORD)
+    {
+      enum rid keyword = token->keyword;
+
+      switch (keyword)
+       {
+       case RID_CASE:
+       case RID_DEFAULT:
+         /* Looks like a labeled-statement with a case label.
+            Parse the label, and then use tail recursion to parse
+            the statement.  */
+         cp_parser_label_for_labeled_statement (parser);
+         goto restart;
+
+       case RID_IF:
+       case RID_SWITCH:
+         statement = cp_parser_selection_statement (parser, if_p);
+         break;
+
+       case RID_WHILE:
+       case RID_DO:
+       case RID_FOR:
+         statement = cp_parser_iteration_statement (parser);
+         break;
+
+       case RID_BREAK:
+       case RID_CONTINUE:
+       case RID_RETURN:
+       case RID_GOTO:
+         statement = cp_parser_jump_statement (parser);
+         break;
+
+         /* 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:
@@ -7037,6 +8093,7 @@ static void
 cp_parser_label_for_labeled_statement (cp_parser* parser)
 {
   cp_token *token;
+  tree label = NULL_TREE;
 
   /* The next token should be an identifier.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -7077,10 +8134,11 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
          expr_hi = NULL_TREE;
 
        if (parser->in_switch_statement_p)
-         finish_case_label (expr, expr_hi);
+         finish_case_label (token->location, expr, expr_hi);
        else
-         error ("%Hcase label %qE not within a switch statement",
-                &token->location, expr);
+         error_at (token->location,
+                   "case label %qE not within a switch statement",
+                   expr);
       }
       break;
 
@@ -7089,19 +8147,41 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
       cp_lexer_consume_token (parser->lexer);
 
       if (parser->in_switch_statement_p)
-       finish_case_label (NULL_TREE, NULL_TREE);
+       finish_case_label (token->location, NULL_TREE, NULL_TREE);
       else
-       error ("%Hcase label not within a switch statement", &token->location);
+       error_at (token->location, "case label not within a switch statement");
       break;
 
     default:
       /* Anything else must be an ordinary label.  */
-      finish_label_stmt (cp_parser_identifier (parser));
+      label = finish_label_stmt (cp_parser_identifier (parser));
       break;
     }
 
   /* Require the `:' token.  */
-  cp_parser_require (parser, CPP_COLON, "%<:%>");
+  cp_parser_require (parser, CPP_COLON, RT_COLON);
+
+  /* An ordinary label may optionally be followed by attributes.
+     However, this is only permitted if the attributes are then
+     followed by a semicolon.  This is because, for backward
+     compatibility, when parsing
+       lab: __attribute__ ((unused)) int i;
+     we want the attribute to attach to "i", not "lab".  */
+  if (label != NULL_TREE
+      && cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+    {
+      tree attrs;
+
+      cp_parser_parse_tentatively (parser);
+      attrs = cp_parser_attributes_opt (parser);
+      if (attrs == NULL_TREE
+         || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+       cp_parser_abort_tentative_parse (parser);
+      else if (!cp_parser_parse_definitely (parser))
+       ;
+      else
+       cplus_decl_attributes (&label, attrs, 0);
+    }
 }
 
 /* Parse an expression-statement.
@@ -7118,12 +8198,32 @@ static tree
 cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
 {
   tree statement = NULL_TREE;
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   /* If the next token is a ';', then there is no expression
      statement.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
+  /* Give a helpful message for "A<T>::type t;" and the like.  */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
+      && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+    {
+      if (TREE_CODE (statement) == SCOPE_REF)
+       error_at (token->location, "need %<typename%> before %qE because "
+                 "%qT is a dependent scope",
+                 statement, TREE_OPERAND (statement, 0));
+      else if (is_overloaded_fn (statement)
+              && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
+       {
+         /* A::A a; */
+         tree fn = get_first_fn (statement);
+         error_at (token->location,
+                   "%<%T::%D%> names the constructor, not the type",
+                   DECL_CONTEXT (fn), DECL_NAME (fn));
+       }
+    }
+
   /* Consume the final `;'.  */
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 
@@ -7163,7 +8263,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   tree compound_stmt;
 
   /* Consume the `{'.  */
-  if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
     return error_mark_node;
   /* Begin the compound-statement.  */
   compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0);
@@ -7175,7 +8275,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   /* Finish the compound-statement.  */
   finish_compound_stmt (compound_stmt);
   /* Consume the `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
   return compound_stmt;
 }
@@ -7209,7 +8309,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
          else
            {
              token = cp_lexer_consume_token (parser->lexer);
-             error ("%H%<else%> without a previous %<if%>", &token->location);
+             error_at (token->location, "%<else%> without a previous %<if%>");
            }
        }
 
@@ -7242,7 +8342,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
     *if_p = false;
 
   /* Peek at the next token.  */
-  token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement");
+  token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT);
 
   /* See what kind of keyword it is.  */
   keyword = token->keyword;
@@ -7255,7 +8355,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
        tree condition;
 
        /* Look for the `('.  */
-       if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+       if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
          {
            cp_parser_skip_to_end_of_statement (parser);
            return error_mark_node;
@@ -7270,7 +8370,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
        /* Parse the condition.  */
        condition = cp_parser_condition (parser);
        /* Look for the `)'.  */
-       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
          cp_parser_skip_to_closing_parenthesis (parser, true, false,
                                                 /*consume_paren=*/true);
 
@@ -7288,7 +8388,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
            if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
              {
                location_t loc = cp_lexer_peek_token (parser->lexer)->location;
-               add_stmt (build_empty_stmt ());
+               add_stmt (build_empty_stmt (loc));
                cp_lexer_consume_token (parser->lexer);
                if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
                  warning_at (loc, OPT_Wempty_body, "suggest braces around "
@@ -7311,10 +8411,12 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
                /* Parse the else-clause.  */
                if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
                  {
-                   warning_at (cp_lexer_peek_token (parser->lexer)->location,
+                   location_t loc;
+                   loc = cp_lexer_peek_token (parser->lexer)->location;
+                   warning_at (loc,
                                OPT_Wempty_body, "suggest braces around "
                                "empty body in an %<else%> statement");
-                   add_stmt (build_empty_stmt ());
+                   add_stmt (build_empty_stmt (loc));
                    cp_lexer_consume_token (parser->lexer);
                  }
                else
@@ -7337,10 +8439,9 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
                   statement which does have an else clause.  We warn
                   about the potential ambiguity.  */
                if (nested_if)
-                 warning (OPT_Wparentheses,
-                          ("%Hsuggest explicit braces "
-                           "to avoid ambiguous %<else%>"),
-                          EXPR_LOCUS (statement));
+                 warning_at (EXPR_LOCATION (statement), OPT_Wparentheses,
+                             "suggest explicit braces to avoid ambiguous"
+                             " %<else%>");
              }
 
            /* Now we're all done with the if-statement.  */
@@ -7404,9 +8505,10 @@ cp_parser_condition (cp_parser* parser)
      condition.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in conditions";
+    = G_("types may not be defined in conditions");
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition==*/true,
+  cp_parser_type_specifier_seq (parser, /*is_declaration==*/true,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -7463,11 +8565,11 @@ cp_parser_condition (cp_parser* parser)
          else
            {
              /* Consume the `='.  */
-             cp_parser_require (parser, CPP_EQ, "%<=%>");
+             cp_parser_require (parser, CPP_EQ, RT_EQ);
              initializer = cp_parser_initializer_clause (parser, &non_constant_p);
            }
          if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
          if (!non_constant_p)
            initializer = fold_non_dependent_expr (initializer);
@@ -7493,6 +8595,258 @@ cp_parser_condition (cp_parser* parser)
   return cp_parser_expression (parser, /*cast_p=*/false, NULL);
 }
 
+/* Parses a traditional for-statement until the closing ')', not included. */
+
+static tree
+cp_parser_c_for (cp_parser *parser)
+{
+  /* Normal for loop */
+  tree stmt;
+  tree condition = NULL_TREE;
+  tree expression = NULL_TREE;
+
+  /* Begin the for-statement.  */
+  stmt = begin_for_stmt ();
+
+  /* Parse the initialization.  */
+  cp_parser_for_init_statement (parser);
+  finish_for_init_stmt (stmt);
+
+  /* If there's a condition, process it.  */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+    condition = cp_parser_condition (parser);
+  finish_for_cond (condition, stmt);
+  /* Look for the `;'.  */
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+  /* If there's an expression, process it.  */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+    expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+  finish_for_expr (expression, stmt);
+
+  return stmt;
+}
+
+/* Tries to parse a range-based for-statement:
+
+  range-based-for:
+    type-specifier-seq declarator : expression
+
+  If succesful, assigns to *DECL the DECLARATOR and to *EXPR the
+  expression. Note that the *DECL is returned unfinished, so
+  later you should call cp_finish_decl().
+
+  Returns TRUE iff a range-based for is parsed. */
+
+static tree
+cp_parser_range_for (cp_parser *parser)
+{
+  tree stmt, range_decl, range_expr;
+  cp_decl_specifier_seq type_specifiers;
+  cp_declarator *declarator;
+  const char *saved_message;
+  tree attributes, pushed_scope;
+
+  cp_parser_parse_tentatively (parser);
+  /* New types are not allowed in the type-specifier-seq for a
+     range-based for loop.  */
+  saved_message = parser->type_definition_forbidden_message;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in range-based for loops");
+  /* Parse the type-specifier-seq.  */
+  cp_parser_type_specifier_seq (parser, /*is_declaration==*/true,
+                               /*is_trailing_return=*/false,
+                               &type_specifiers);
+  /* Restore the saved message.  */
+  parser->type_definition_forbidden_message = saved_message;
+  /* If all is well, we might be looking at a declaration.  */
+  if (cp_parser_error_occurred (parser))
+    {
+      cp_parser_abort_tentative_parse (parser);
+      return NULL_TREE;
+    }
+  /* Parse the declarator.  */
+  declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+                                    /*ctor_dtor_or_conv_p=*/NULL,
+                                    /*parenthesized_p=*/NULL,
+                                    /*member_p=*/false);
+  /* Parse the attributes.  */
+  attributes = cp_parser_attributes_opt (parser);
+  /* The next token should be `:'. */
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+    cp_parser_simulate_error (parser);
+
+  /* Check if it is a range-based for */
+  if (!cp_parser_parse_definitely (parser))
+    return NULL_TREE;
+
+  cp_parser_require (parser, CPP_COLON, RT_COLON);
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+    {
+      bool expr_non_constant_p;
+      range_expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+    }
+  else
+    range_expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+
+  /* If in template, STMT is converted to a normal for-statements
+     at instantiation. If not, it is done just ahead. */
+  if (processing_template_decl)
+    stmt = begin_range_for_stmt ();
+  else
+    stmt = begin_for_stmt ();
+
+  /* Create the declaration. It must be after begin{,_range}_for_stmt(). */
+  range_decl = start_decl (declarator, &type_specifiers,
+                          /*initialized_p=*/SD_INITIALIZED,
+                          attributes, /*prefix_attributes=*/NULL_TREE,
+                          &pushed_scope);
+  /* No scope allowed here */
+  pop_scope (pushed_scope);
+
+  if (TREE_CODE (stmt) == RANGE_FOR_STMT)
+    finish_range_for_decl (stmt, range_decl, range_expr);
+  else
+    /* Convert the range-based for loop into a normal for-statement. */
+    stmt = cp_convert_range_for (stmt, range_decl, range_expr);
+
+  return stmt;
+}
+
+/* Converts a range-based for-statement into a normal
+   for-statement, as per the definition.
+
+      for (RANGE_DECL : RANGE_EXPR)
+       BLOCK
+
+   should be equivalent to:
+
+      {
+       auto &&__range = RANGE_EXPR;
+       for (auto __begin = BEGIN_EXPR, end = END_EXPR;
+             __begin != __end;
+             ++__begin)
+         {
+             RANGE_DECL = *__begin;
+             BLOCK
+         }
+      }
+
+   If RANGE_EXPR is an array:
+       BEGIN_EXPR = __range
+       END_EXPR = __range + ARRAY_SIZE(__range)
+   Else:
+       BEGIN_EXPR = begin(__range)
+       END_EXPR = end(__range);
+
+   When calling begin()/end() we must use argument dependent
+   lookup, but always considering 'std' as an associated namespace.  */
+
+tree
+cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
+{
+  tree range_type, range_temp;
+  tree begin, end;
+  tree iter_type, begin_expr, end_expr;
+  tree condition, expression;
+
+  /* Find out the type deduced by the declaration
+   * `auto &&__range = range_expr' */
+  range_type = cp_build_reference_type (make_auto (), true);
+  range_type = do_auto_deduction (range_type, range_expr,
+                                 type_uses_auto (range_type));
+
+  /* Create the __range variable */
+  range_temp = build_decl (input_location, VAR_DECL,
+                          get_identifier ("__for_range"), range_type);
+  TREE_USED (range_temp) = 1;
+  DECL_ARTIFICIAL (range_temp) = 1;
+  pushdecl (range_temp);
+  finish_expr_stmt (cp_build_modify_expr (range_temp, INIT_EXPR, range_expr,
+                                         tf_warning_or_error));
+  range_temp = convert_from_reference (range_temp);
+
+  if (TREE_CODE (TREE_TYPE (range_temp)) == ARRAY_TYPE)
+    {
+      /* If RANGE_TEMP is an array we will use pointer arithmetic */
+      iter_type = build_pointer_type (TREE_TYPE (TREE_TYPE (range_temp)));
+      begin_expr = range_temp;
+      end_expr
+       = build_binary_op (input_location, PLUS_EXPR,
+                          range_temp,
+                          array_type_nelts_top (TREE_TYPE (range_temp)), 0);
+    }
+  else
+    {
+      /* If it is not an array, we must call begin(__range)/end__range() */
+      VEC(tree,gc) *vec;
+
+      begin_expr = get_identifier ("begin");
+      vec = make_tree_vector ();
+      VEC_safe_push (tree, gc, vec, range_temp);
+      begin_expr = perform_koenig_lookup (begin_expr, vec,
+                                         /*include_std=*/true);
+      begin_expr = finish_call_expr (begin_expr, &vec, false, true,
+                                    tf_warning_or_error);
+      release_tree_vector (vec);
+
+      end_expr = get_identifier ("end");
+      vec = make_tree_vector ();
+      VEC_safe_push (tree, gc, vec, range_temp);
+      end_expr = perform_koenig_lookup (end_expr, vec,
+                                       /*include_std=*/true);
+      end_expr = finish_call_expr (end_expr, &vec, false, true,
+                                  tf_warning_or_error);
+      release_tree_vector (vec);
+
+      /* The unqualified type of the __begin and __end temporaries should
+      * be the same as required by the multiple auto declaration */
+      iter_type = cv_unqualified (TREE_TYPE (begin_expr));
+      if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (end_expr))))
+       error ("inconsistent begin/end types in range-based for: %qT and %qT",
+              TREE_TYPE (begin_expr), TREE_TYPE (end_expr));
+    }
+
+  /* The new for initialization statement */
+  begin = build_decl (input_location, VAR_DECL,
+                     get_identifier ("__for_begin"), iter_type);
+  TREE_USED (begin) = 1;
+  DECL_ARTIFICIAL (begin) = 1;
+  pushdecl (begin);
+  finish_expr_stmt (cp_build_modify_expr (begin, INIT_EXPR, begin_expr,
+                                         tf_warning_or_error));
+  end = build_decl (input_location, VAR_DECL,
+                   get_identifier ("__for_end"), iter_type);
+  TREE_USED (end) = 1;
+  DECL_ARTIFICIAL (end) = 1;
+  pushdecl (end);
+
+  finish_expr_stmt (cp_build_modify_expr (end, INIT_EXPR, end_expr,
+                                         tf_warning_or_error));
+
+  finish_for_init_stmt (statement);
+
+/* The new for condition */
+  condition = build_x_binary_op (NE_EXPR,
+                                begin, ERROR_MARK,
+                                end, ERROR_MARK,
+                                NULL, tf_warning_or_error);
+  finish_for_cond (condition, statement);
+
+  /* The new increment expression */
+  expression = finish_unary_op_expr (PREINCREMENT_EXPR, begin);
+  finish_for_expr (expression, statement);
+
+  /* The declaration is initialized with *__begin inside the loop body */
+  cp_finish_decl (range_decl,
+                 build_x_indirect_ref (begin, RO_NULL, tf_warning_or_error),
+                 /*is_constant_init*/false, NULL_TREE,
+                 LOOKUP_ONLYCONVERTING);
+
+  return statement;
+}
+
+
 /* Parse an iteration-statement.
 
    iteration-statement:
@@ -7501,7 +8855,7 @@ cp_parser_condition (cp_parser* parser)
      for ( for-init-statement condition [opt] ; expression [opt] )
        statement
 
-   Returns the new WHILE_STMT, DO_STMT, or FOR_STMT.  */
+   Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT.  */
 
 static tree
 cp_parser_iteration_statement (cp_parser* parser)
@@ -7512,7 +8866,7 @@ cp_parser_iteration_statement (cp_parser* parser)
   unsigned char in_statement;
 
   /* Peek at the next token.  */
-  token = cp_parser_require (parser, CPP_KEYWORD, "iteration-statement");
+  token = cp_parser_require (parser, CPP_KEYWORD, RT_INTERATION);
   if (!token)
     return error_mark_node;
 
@@ -7531,12 +8885,12 @@ cp_parser_iteration_statement (cp_parser* parser)
        /* Begin the while-statement.  */
        statement = begin_while_stmt ();
        /* Look for the `('.  */
-       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
        /* Parse the condition.  */
        condition = cp_parser_condition (parser);
        finish_while_stmt_cond (condition, statement);
        /* Look for the `)'.  */
-       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
        /* Parse the dependent statement.  */
        parser->in_statement = IN_ITERATION_STMT;
        cp_parser_already_scoped_statement (parser);
@@ -7558,46 +8912,34 @@ cp_parser_iteration_statement (cp_parser* parser)
        parser->in_statement = in_statement;
        finish_do_body (statement);
        /* Look for the `while' keyword.  */
-       cp_parser_require_keyword (parser, RID_WHILE, "%<while%>");
+       cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
        /* Look for the `('.  */
-       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
        /* Parse the expression.  */
        expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
        /* We're done with the do-statement.  */
        finish_do_stmt (expression, statement);
        /* Look for the `)'.  */
-       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
        /* Look for the `;'.  */
-       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       }
       break;
 
     case RID_FOR:
       {
-       tree condition = NULL_TREE;
-       tree expression = NULL_TREE;
-
-       /* Begin the for-statement.  */
-       statement = begin_for_stmt ();
        /* Look for the `('.  */
-       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
-       /* Parse the initialization.  */
-       cp_parser_for_init_statement (parser);
-       finish_for_init_stmt (statement);
-
-       /* If there's a condition, process it.  */
-       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-         condition = cp_parser_condition (parser);
-       finish_for_cond (condition, statement);
-       /* Look for the `;'.  */
-       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+       if (cxx_dialect == cxx0x)
+         statement = cp_parser_range_for (parser);
+       else
+         statement = NULL_TREE;
+       if (statement == NULL_TREE)
+         statement = cp_parser_c_for (parser);
 
-       /* If there's an expression, process it.  */
-       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
-         expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
-       finish_for_expr (expression, statement);
        /* Look for the `)'.  */
-       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
        /* Parse the body of the for-statement.  */
        parser->in_statement = IN_ITERATION_STMT;
@@ -7647,7 +8989,7 @@ cp_parser_for_init_statement (cp_parser* parser)
        return;
     }
 
-  cp_parser_expression_statement (parser, false);
+  cp_parser_expression_statement (parser, NULL_TREE);
 }
 
 /* Parse a jump-statement.
@@ -7675,7 +9017,7 @@ cp_parser_jump_statement (cp_parser* parser)
   unsigned char in_statement;
 
   /* Peek at the next token.  */
-  token = cp_parser_require (parser, CPP_KEYWORD, "jump-statement");
+  token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP);
   if (!token)
     return error_mark_node;
 
@@ -7688,7 +9030,7 @@ cp_parser_jump_statement (cp_parser* parser)
       switch (in_statement)
        {
        case 0:
-         error ("%Hbreak statement not within loop or switch", &token->location);
+         error_at (token->location, "break statement not within loop or switch");
          break;
        default:
          gcc_assert ((in_statement & IN_SWITCH_STMT)
@@ -7696,32 +9038,32 @@ cp_parser_jump_statement (cp_parser* parser)
          statement = finish_break_stmt ();
          break;
        case IN_OMP_BLOCK:
-         error ("%Hinvalid exit from OpenMP structured block", &token->location);
+         error_at (token->location, "invalid exit from OpenMP structured block");
          break;
        case IN_OMP_FOR:
-         error ("%Hbreak statement used with OpenMP for loop", &token->location);
+         error_at (token->location, "break statement used with OpenMP for loop");
          break;
        }
-      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       break;
 
     case RID_CONTINUE:
       switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
        {
        case 0:
-         error ("%Hcontinue statement not within a loop", &token->location);
+         error_at (token->location, "continue statement not within a loop");
          break;
        case IN_ITERATION_STMT:
        case IN_OMP_FOR:
          statement = finish_continue_stmt ();
          break;
        case IN_OMP_BLOCK:
-         error ("%Hinvalid exit from OpenMP structured block", &token->location);
+         error_at (token->location, "invalid exit from OpenMP structured block");
          break;
        default:
          gcc_unreachable ();
        }
-      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       break;
 
     case RID_RETURN:
@@ -7731,7 +9073,7 @@ cp_parser_jump_statement (cp_parser* parser)
 
        if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
          {
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
            expr = cp_parser_braced_list (parser, &expr_non_constant_p);
          }
        else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -7743,7 +9085,7 @@ cp_parser_jump_statement (cp_parser* parser)
        /* Build the return-statement.  */
        statement = finish_return_stmt (expr);
        /* Look for the final `;'.  */
-       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       }
       break;
 
@@ -7761,7 +9103,7 @@ cp_parser_jump_statement (cp_parser* parser)
       else
        finish_goto_stmt (cp_parser_identifier (parser));
       /* Look for the final `;'.  */
-      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       break;
 
     default:
@@ -7822,8 +9164,9 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
   /* Mark if () ; with a special NOP_EXPR.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
     {
+      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
       cp_lexer_consume_token (parser->lexer);
-      statement = add_stmt (build_empty_stmt ());
+      statement = add_stmt (build_empty_stmt (loc));
     }
   /* if a compound is opened, we simply parse the statement directly.  */
   else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
@@ -7858,13 +9201,13 @@ cp_parser_already_scoped_statement (cp_parser* parser)
     {
       /* Avoid calling cp_parser_compound_statement, so that we
         don't create a new scope.  Do everything else by hand.  */
-      cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>");
+      cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
       /* If the next keyword is `__label__' we have a label declaration.  */
       while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
        cp_parser_label_declaration (parser);
       /* Parse an (optional) statement-seq.  */
       cp_parser_statement_seq_opt (parser, NULL_TREE);
-      cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
     }
 }
 
@@ -7951,6 +9294,7 @@ cp_parser_declaration (cp_parser* parser)
   cp_token token2;
   int saved_pedantic;
   void *p;
+  tree attributes = NULL_TREE;
 
   /* Check for the `__extension__' keyword.  */
   if (cp_parser_extension_opt (parser, &saved_pedantic))
@@ -8028,7 +9372,11 @@ cp_parser_declaration (cp_parser* parser)
     cp_parser_namespace_definition (parser);
   /* Objective-C++ declaration/definition.  */
   else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword))
-    cp_parser_objc_declaration (parser);
+    cp_parser_objc_declaration (parser, NULL_TREE);
+  else if (c_dialect_objc ()
+          && token1.keyword == RID_ATTRIBUTE
+          && cp_parser_objc_valid_prefix_attributes (parser, &attributes))
+    cp_parser_objc_declaration (parser, attributes);
   /* We must have either a block declaration or a function
      definition.  */
   else
@@ -8117,7 +9465,7 @@ cp_parser_block_declaration (cp_parser *parser,
   else if (token1->keyword == RID_LABEL)
     {
       cp_lexer_consume_token (parser->lexer);
-      error ("%H%<__label__%> not at the beginning of a block", &token1->location);
+      error_at (token1->location, "%<__label__%> not at the beginning of a block");
       cp_parser_skip_to_end_of_statement (parser);
       /* If the next token is now a `;', consume it.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -8190,7 +9538,7 @@ cp_parser_simple_declaration (cp_parser* parser,
        T t;
 
      where "T" should name a type -- but does not.  */
-  if (!decl_specifiers.type
+  if (!decl_specifiers.any_type_specifiers_p
       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     {
       /* If parsing tentatively, we should commit; we really are
@@ -8254,8 +9602,9 @@ cp_parser_simple_declaration (cp_parser* parser,
          if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
            {
              cp_token *token = cp_lexer_peek_token (parser->lexer);
-             error ("%Hmixing declarations and function-definitions is forbidden",
-                    &token->location);
+             error_at (token->location,
+                       "mixing"
+                       " declarations and function-definitions is forbidden");
            }
          /* Otherwise, we're done with the list of declarators.  */
          else
@@ -8308,7 +9657,7 @@ cp_parser_simple_declaration (cp_parser* parser,
     }
 
   /* Consume the `;'.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
  done:
   pop_deferring_access_checks ();
@@ -8390,11 +9739,12 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
       switch (token->keyword)
        {
          /* decl-specifier:
-              friend  */
+              friend
+               constexpr */
        case RID_FRIEND:
          if (!at_class_scope_p ())
            {
-             error ("%H%<friend%> used outside of class", &token->location);
+             error_at (token->location, "%<friend%> used outside of class");
              cp_lexer_purge_token (parser->lexer);
            }
          else
@@ -8405,6 +9755,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
            }
          break;
 
+        case RID_CONSTEXPR:
+          ++decl_specs->specs[(int) ds_constexpr];
+          cp_lexer_consume_token (parser->lexer);
+          break;
+
          /* function-specifier:
               inline
               virtual
@@ -8448,10 +9803,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
 
               /* Complain about `auto' as a storage specifier, if
                  we're complaining about C++0x compatibility.  */
-              warning 
-                (OPT_Wc__0x_compat, 
-                 "%H%<auto%> will change meaning in C++0x; please remove it",
-                &token->location);
+              warning_at (token->location, OPT_Wc__0x_compat, "%<auto%>"
+                         " will change meaning in C++0x; please remove it");
 
               /* Set the storage class anyway.  */
               cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
@@ -8550,6 +9903,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
            {
              constructor_possible_p = false;
              found_decl_spec = true;
+             if (!is_cv_qualifier)
+               decl_specs->any_type_specifiers_p = true;
            }
        }
 
@@ -8569,8 +9924,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
   /* Don't allow a friend specifier with a class definition.  */
   if (decl_specs->specs[(int) ds_friend] != 0
       && (*declares_class_or_enum & 2))
-    error ("%Hclass definition may not be declared a friend",
-           &start_token->location);
+    error_at (start_token->location,
+             "class definition may not be declared a friend");
 }
 
 /* Parse an (optional) storage-class-specifier.
@@ -8639,7 +9994,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
 
         A member function template shall not be virtual.  */
       if (PROCESSING_REAL_TEMPLATE_DECL_P ())
-       error ("%Htemplates may not be %<virtual%>", &token->location);
+       error_at (token->location, "templates may not be %<virtual%>");
       else if (decl_specs)
        ++decl_specs->specs[(int) ds_virtual];
       break;
@@ -8669,7 +10024,7 @@ cp_parser_linkage_specification (cp_parser* parser)
   tree linkage;
 
   /* Look for the `extern' keyword.  */
-  cp_parser_require_keyword (parser, RID_EXTERN, "%<extern%>");
+  cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN);
 
   /* Look for the string-literal.  */
   linkage = cp_parser_string_literal (parser, false, false);
@@ -8699,7 +10054,7 @@ cp_parser_linkage_specification (cp_parser* parser)
       /* Parse the declarations.  */
       cp_parser_declaration_seq_opt (parser);
       /* Look for the closing `}'.  */
-      cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
     }
   /* Otherwise, there's just one declaration.  */
   else
@@ -8740,7 +10095,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
 
   /* Look for the `static_assert' keyword.  */
   if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT, 
-                                  "%<static_assert%>"))
+                                  RT_STATIC_ASSERT))
     return;
 
   /*  We know we are in a static assertion; commit to any tentative
@@ -8749,7 +10104,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
     cp_parser_commit_to_tentative_parse (parser);
 
   /* Parse the `(' starting the static assertion condition.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
   /* Parse the constant-expression.  */
   condition = 
@@ -8758,7 +10113,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
                                    /*non_constant_p=*/NULL);
 
   /* Parse the separating `,'.  */
-  cp_parser_require (parser, CPP_COMMA, "%<,%>");
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
 
   /* Parse the string-literal message.  */
   message = cp_parser_string_literal (parser, 
@@ -8766,14 +10121,14 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
                                       /*wide_ok=*/true);
 
   /* A `)' completes the static assertion.  */
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, 
                                            /*recovering=*/true, 
                                            /*or_comma=*/false,
                                           /*consume_paren=*/true);
 
   /* A semicolon terminates the declaration.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   /* Complete the static assertion, which may mean either processing 
      the static assert now or saving it for template instantiation.  */
@@ -8796,7 +10151,7 @@ cp_parser_decltype (cp_parser *parser)
   cp_token *id_expr_start_token;
 
   /* Look for the `decltype' token.  */
-  if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>"))
+  if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
     return error_mark_node;
 
   /* Types cannot be defined in a `decltype' expression.  Save away the
@@ -8805,7 +10160,7 @@ cp_parser_decltype (cp_parser *parser)
 
   /* And create the new one.  */
   parser->type_definition_forbidden_message
-    = "types may not be defined in %<decltype%> expressions";
+    = G_("types may not be defined in %<decltype%> expressions");
 
   /* The restrictions on constant-expressions do not apply inside
      decltype expressions.  */
@@ -8816,10 +10171,13 @@ cp_parser_decltype (cp_parser *parser)
   parser->integral_constant_expression_p = false;
 
   /* Do not actually evaluate the expression.  */
-  ++skip_evaluation;
+  ++cp_unevaluated_operand;
+
+  /* Do not warn about problems with the expression.  */
+  ++c_inhibit_evaluation_warnings;
 
   /* Parse the opening `('.  */
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return error_mark_node;
   
   /* First, try parsing an id-expression.  */
@@ -8911,16 +10269,30 @@ cp_parser_decltype (cp_parser *parser)
     cp_parser_parse_definitely (parser);
   else
     {
+      bool saved_greater_than_is_operator_p;
+
       /* Abort our attempt to parse an id-expression or member access
          expression.  */
       cp_parser_abort_tentative_parse (parser);
 
+      /* Within a parenthesized expression, a `>' token is always
+        the greater-than operator.  */
+      saved_greater_than_is_operator_p
+       = parser->greater_than_is_operator_p;
+      parser->greater_than_is_operator_p = true;
+
       /* Parse a full expression.  */
       expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+
+      /* The `>' token might be the end of a template-id or
+        template-parameter-list now.  */
+      parser->greater_than_is_operator_p
+       = saved_greater_than_is_operator_p;
     }
 
   /* Go back to evaluating expressions.  */
-  --skip_evaluation;
+  --cp_unevaluated_operand;
+  --c_inhibit_evaluation_warnings;
 
   /* Restore the old message and the integral constant expression
      flags.  */
@@ -8939,7 +10311,7 @@ cp_parser_decltype (cp_parser *parser)
     }
   
   /* Parse to the closing `)'.  */
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     {
       cp_parser_skip_to_closing_parenthesis (parser, true, false,
                                             /*consume_paren=*/true);
@@ -8968,7 +10340,7 @@ cp_parser_conversion_function_id (cp_parser* parser)
   tree pushed_scope = NULL_TREE;
 
   /* Look for the `operator' token.  */
-  if (!cp_parser_require_keyword (parser, RID_OPERATOR, "%<operator%>"))
+  if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
     return error_mark_node;
   /* When we parse the conversion-type-id, the current scope will be
      reset.  However, we need that information in able to look up the
@@ -9024,7 +10396,8 @@ cp_parser_conversion_type_id (cp_parser* parser)
   /* Parse the attributes.  */
   attributes = cp_parser_attributes_opt (parser);
   /* Parse the type-specifiers.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* If that didn't work, stop.  */
   if (type_specifiers.type == error_mark_node)
@@ -9126,8 +10499,8 @@ cp_parser_mem_initializer_list (cp_parser* parser)
   /* Let the semantic analysis code know that we are starting the
      mem-initializer-list.  */
   if (!DECL_CONSTRUCTOR_P (current_function_decl))
-    error ("%Honly constructors take base initializers",
-          &token->location);
+    error_at (token->location,
+             "only constructors take member initializers");
 
   /* Loop through the list.  */
   while (true)
@@ -9148,8 +10521,9 @@ cp_parser_mem_initializer_list (cp_parser* parser)
           if (mem_initializer != error_mark_node
               && !TYPE_P (TREE_PURPOSE (mem_initializer)))
             {
-              error ("%Hcannot expand initializer for member %<%D%>",
-                     &token->location, TREE_PURPOSE (mem_initializer));
+              error_at (token->location,
+                       "cannot expand initializer for member %<%D%>",
+                       TREE_PURPOSE (mem_initializer));
               mem_initializer = error_mark_node;
             }
 
@@ -9219,17 +10593,24 @@ cp_parser_mem_initializer (cp_parser* parser)
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       expression_list = build_tree_list (NULL_TREE, expression_list);
     }
   else
-    expression_list
-      = cp_parser_parenthesized_expression_list (parser, false,
-                                                /*cast_p=*/false,
-                                                /*allow_expansion_p=*/true,
-                                                /*non_constant_p=*/NULL);
+    {
+      VEC(tree,gc)* vec;
+      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+                                                    /*cast_p=*/false,
+                                                    /*allow_expansion_p=*/true,
+                                                    /*non_constant_p=*/NULL);
+      if (vec == NULL)
+       return error_mark_node;
+      expression_list = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
+
   if (expression_list == error_mark_node)
     return error_mark_node;
   if (!expression_list)
@@ -9263,9 +10644,9 @@ cp_parser_mem_initializer_id (cp_parser* parser)
   /* `typename' is not allowed in this context ([temp.res]).  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
     {
-      error ("%Hkeyword %<typename%> not allowed in this context (a qualified "
-            "member initializer is implicitly a type)",
-            &token->location);
+      error_at (token->location, 
+               "keyword %<typename%> not allowed in this context (a qualified "
+               "member initializer is implicitly a type)");
       cp_lexer_consume_token (parser->lexer);
     }
   /* Look for the optional `::' operator.  */
@@ -9300,7 +10681,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
     return cp_parser_class_name (parser,
                                 /*typename_keyword_p=*/true,
                                 /*template_keyword_p=*/template_p,
-                                none_type,
+                                typename_type,
                                 /*check_dependency_p=*/true,
                                 /*class_head_p=*/false,
                                 /*is_declaration=*/true);
@@ -9335,7 +10716,7 @@ static tree
 cp_parser_operator_function_id (cp_parser* parser)
 {
   /* Look for the `operator' keyword.  */
-  if (!cp_parser_require_keyword (parser, RID_OPERATOR, "%<operator%>"))
+  if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
     return error_mark_node;
   /* And then the name of the operator itself.  */
   return cp_parser_operator (parser);
@@ -9391,7 +10772,7 @@ cp_parser_operator (cp_parser* parser)
            /* Consume the `[' token.  */
            cp_lexer_consume_token (parser->lexer);
            /* Look for the `]' token.  */
-           cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+           cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
            id = ansi_opname (op == NEW_EXPR
                              ? VEC_NEW_EXPR : VEC_DELETE_EXPR);
          }
@@ -9550,14 +10931,14 @@ cp_parser_operator (cp_parser* parser)
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
       /* Look for the matching `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       return ansi_opname (CALL_EXPR);
 
     case CPP_OPEN_SQUARE:
       /* Consume the `['.  */
       cp_lexer_consume_token (parser->lexer);
       /* Look for the matching `]'.  */
-      cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
       return ansi_opname (ARRAY_REF);
 
     default:
@@ -9635,14 +11016,17 @@ cp_parser_template_parameter_list (cp_parser* parser)
       tree parameter;
       bool is_non_type;
       bool is_parameter_pack;
+      location_t parm_loc;
 
       /* Parse the template-parameter.  */
+      parm_loc = cp_lexer_peek_token (parser->lexer)->location;
       parameter = cp_parser_template_parameter (parser, 
                                                 &is_non_type,
                                                 &is_parameter_pack);
       /* Add it to the list.  */
       if (parameter != error_mark_node)
        parameter_list = process_template_parm (parameter_list,
+                                               parm_loc,
                                                parameter,
                                                is_non_type,
                                                 is_parameter_pack);
@@ -9791,11 +11175,12 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
        id_declarator = id_declarator->declarator;
       
       if (id_declarator && id_declarator->kind == cdk_id)
-       error ("%Htemplate parameter pack %qD cannot have a default argument",
-              &start_token->location, id_declarator->u.id.unqualified_name);
+       error_at (start_token->location,
+                 "template parameter pack %qD cannot have a default argument",
+                 id_declarator->u.id.unqualified_name);
       else
-       error ("%Htemplate parameter pack cannot have a default argument",
-              &start_token->location);
+       error_at (start_token->location,
+                 "template parameter pack cannot have a default argument");
       
       /* Parse the default argument, but throw away the result.  */
       cp_parser_default_argument (parser, /*template_parm_p=*/true);
@@ -9803,7 +11188,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
 
   parm = grokdeclarator (parameter_declarator->declarator,
                         &parameter_declarator->decl_specifiers,
-                        PARM, /*initialized=*/0,
+                        TPARM, /*initialized=*/0,
                         /*attrlist=*/NULL);
   if (parm == error_mark_node)
     return error_mark_node;
@@ -9841,8 +11226,7 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
   tree parameter;
 
   /* Look for a keyword to tell us what kind of parameter this is.  */
-  token = cp_parser_require (parser, CPP_KEYWORD,
-                            "%<class%>, %<typename%>, or %<template%>");
+  token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE);
   if (!token)
     return error_mark_node;
 
@@ -9889,11 +11273,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
             if (*is_parameter_pack)
               {
                 if (identifier)
-                  error ("%Htemplate parameter pack %qD cannot have a "
-                        "default argument", &token->location, identifier);
+                  error_at (token->location,
+                           "template parameter pack %qD cannot have a "
+                           "default argument", identifier);
                 else
-                  error ("%Htemplate parameter packs cannot have "
-                        "default arguments", &token->location);
+                  error_at (token->location,
+                           "template parameter packs cannot have "
+                           "default arguments");
                 default_argument = NULL_TREE;
               }
            pop_deferring_access_checks ();
@@ -9909,18 +11295,17 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
 
     case RID_TEMPLATE:
       {
-       tree parameter_list;
        tree identifier;
        tree default_argument;
 
        /* Look for the `<'.  */
-       cp_parser_require (parser, CPP_LESS, "%<<%>");
+       cp_parser_require (parser, CPP_LESS, RT_LESS);
        /* Parse the template-parameter-list.  */
-       parameter_list = cp_parser_template_parameter_list (parser);
+       cp_parser_template_parameter_list (parser);
        /* Look for the `>'.  */
-       cp_parser_require (parser, CPP_GREATER, "%<>%>");
+       cp_parser_require (parser, CPP_GREATER, RT_GREATER);
        /* Look for the `class' keyword.  */
-       cp_parser_require_keyword (parser, RID_CLASS, "%<class%>");
+       cp_parser_require_keyword (parser, RID_CLASS, RT_CLASS);
         /* If the next token is an ellipsis, we have a template
            argument pack. */
         if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
@@ -9995,13 +11380,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
             if (*is_parameter_pack)
               {
                 if (identifier)
-                  error ("%Htemplate parameter pack %qD cannot "
-                        "have a default argument",
-                        &token->location, identifier);
+                  error_at (token->location,
+                           "template parameter pack %qD cannot "
+                           "have a default argument",
+                           identifier);
                 else
-                  error ("%Htemplate parameter packs cannot "
-                        "have default arguments",
-                        &token->location);
+                  error_at (token->location, "template parameter packs cannot "
+                           "have default arguments");
                 default_argument = NULL_TREE;
               }
            pop_deferring_access_checks ();
@@ -10050,7 +11435,7 @@ cp_parser_template_id (cp_parser *parser,
   cp_token_position start_of_id = 0;
   deferred_access_check *chk;
   VEC (deferred_access_check,gc) *access_check;
-  cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL;
+  cp_token *next_token = NULL, *next_token_2 = NULL;
   bool is_identifier;
 
   /* If the next token corresponds to a template-id, there is no need
@@ -10066,14 +11451,10 @@ cp_parser_template_id (cp_parser *parser,
       access_check = check_value->checks;
       if (access_check)
        {
-         for (i = 0 ;
-              VEC_iterate (deferred_access_check, access_check, i, chk) ;
-              ++i)
-           {
-             perform_or_defer_access_check (chk->binfo,
-                                            chk->decl,
-                                            chk->diag_decl);
-           }
+         FOR_EACH_VEC_ELT (deferred_access_check, access_check, i, chk)
+           perform_or_defer_access_check (chk->binfo,
+                                          chk->decl,
+                                          chk->diag_decl);
        }
       /* Return the stored value.  */
       return check_value->value;
@@ -10098,7 +11479,6 @@ cp_parser_template_id (cp_parser *parser,
 
   /* Parse the template-name.  */
   is_identifier = false;
-  token = cp_lexer_peek_token (parser->lexer);
   templ = cp_parser_template_name (parser, template_keyword_p,
                                   check_dependency_p,
                                   is_declaration,
@@ -10158,7 +11538,7 @@ cp_parser_template_id (cp_parser *parser,
   else
     {
       /* Look for the `<' that starts the template-argument-list.  */
-      if (!cp_parser_require (parser, CPP_LESS, "%<<%>"))
+      if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
        {
          pop_deferring_access_checks ();
          return error_mark_node;
@@ -10210,7 +11590,7 @@ cp_parser_template_id (cp_parser *parser,
       token->type = CPP_TEMPLATE_ID;
       /* Retrieve any deferred checks.  Do not pop this access checks yet
         so the memory will not be reclaimed during token replacing below.  */
-      token->u.tree_check_value = GGC_CNEW (struct tree_check);
+      token->u.tree_check_value = ggc_alloc_cleared_tree_check ();
       token->u.tree_check_value->value = template_id;
       token->u.tree_check_value->checks = get_deferred_access_checks ();
       token->keyword = RID_MAX;
@@ -10223,8 +11603,7 @@ cp_parser_template_id (cp_parser *parser,
         user, as opposed to simply marking the tentative parse as
         failed?  */
       if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
-       error ("%Hparse error in template argument list",
-              &token->location);
+       error_at (token->location, "parse error in template argument list");
     }
 
   pop_deferring_access_checks ();
@@ -10338,9 +11717,9 @@ cp_parser_template_name (cp_parser* parser,
          cp_token_position start = 0;
 
          /* Explain what went wrong.  */
-         error ("%Hnon-template %qD used as template",
-                &token->location, identifier);
-         inform (input_location, "use %<%T::template %D%> to indicate that it is a template",
+         error_at (token->location, "non-template %qD used as template",
+                   identifier);
+         inform (token->location, "use %<%T::template %D%> to indicate that it is a template",
                  parser->scope, identifier);
          /* If parsing tentatively, find the location of the "<" token.  */
          if (cp_parser_simulate_error (parser))
@@ -10380,12 +11759,11 @@ cp_parser_template_name (cp_parser* parser,
   /* Look up the name.  */
   decl = cp_parser_lookup_name (parser, identifier,
                                none_type,
-                               /*is_template=*/false,
+                               /*is_template=*/true,
                                /*is_namespace=*/false,
                                check_dependency_p,
                                /*ambiguous_decls=*/NULL,
                                token->location);
-  decl = maybe_get_template_decl_from_type_decl (decl);
 
   /* If DECL is a template, then the name was a template-name.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
@@ -10473,8 +11851,8 @@ cp_parser_template_argument_list (cp_parser* parser)
          if (argument == error_mark_node)
            {
              cp_token *token = cp_lexer_peek_token (parser->lexer);
-             error ("%Hexpected parameter pack before %<...%>",
-                    &token->location);
+             error_at (token->location,
+                       "expected parameter pack before %<...%>");
            }
           /* Consume the `...' token. */
           cp_lexer_consume_token (parser->lexer);
@@ -10510,6 +11888,9 @@ cp_parser_template_argument_list (cp_parser* parser)
   parser->non_integral_constant_expression_p = saved_non_ice_p;
   parser->integral_constant_expression_p = saved_ice_p;
   parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+#ifdef ENABLE_CHECKING
+  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+#endif
   return vec;
 }
 
@@ -10672,18 +12053,26 @@ cp_parser_template_argument (cp_parser* parser)
        cp_parser_abort_tentative_parse (parser);
       else
        {
+         tree probe;
+
          if (TREE_CODE (argument) == INDIRECT_REF)
            {
              gcc_assert (REFERENCE_REF_P (argument));
              argument = TREE_OPERAND (argument, 0);
            }
 
-         if (TREE_CODE (argument) == VAR_DECL)
+         /* If we're in a template, we represent a qualified-id referring
+            to a static data member as a SCOPE_REF even if the scope isn't
+            dependent so that we can check access control later.  */
+         probe = argument;
+         if (TREE_CODE (probe) == SCOPE_REF)
+           probe = TREE_OPERAND (probe, 1);
+         if (TREE_CODE (probe) == VAR_DECL)
            {
              /* A variable without external linkage might still be a
                 valid constant-expression, so no error is issued here
                 if the external-linkage check fails.  */
-             if (!address_p && !DECL_EXTERNAL_LINKAGE_P (argument))
+             if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe))
                cp_parser_simulate_error (parser);
            }
          else if (is_overloaded_fn (argument))
@@ -10769,7 +12158,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   int declares_class_or_enum;
   cp_decl_specifier_seq decl_specifiers;
   tree extension_specifier = NULL_TREE;
-  cp_token *token;
 
   /* Look for an (optional) storage-class-specifier or
      function-specifier.  */
@@ -10784,7 +12172,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
     }
 
   /* Look for the `template' keyword.  */
-  cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>");
+  cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
   /* Let the front end know that we are processing an explicit
      instantiation.  */
   begin_explicit_instantiation ();
@@ -10792,7 +12180,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
      control while processing explicit instantiation directives.  */
   push_deferring_access_checks (dk_no_check);
   /* Parse a decl-specifier-seq.  */
-  token = cp_lexer_peek_token (parser->lexer);
   cp_parser_decl_specifier_seq (parser,
                                CP_PARSER_FLAGS_OPTIONAL,
                                &decl_specifiers,
@@ -10870,11 +12257,11 @@ cp_parser_explicit_specialization (cp_parser* parser)
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   /* Look for the `template' keyword.  */
-  cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>");
+  cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
   /* Look for the `<'.  */
-  cp_parser_require (parser, CPP_LESS, "%<<%>");
+  cp_parser_require (parser, CPP_LESS, RT_LESS);
   /* Look for the `>'.  */
-  cp_parser_require (parser, CPP_GREATER, "%<>%>");
+  cp_parser_require (parser, CPP_GREATER, RT_GREATER);
   /* We have processed another parameter list.  */
   ++parser->num_template_parameter_lists;
   /* [temp]
@@ -10883,7 +12270,7 @@ cp_parser_explicit_specialization (cp_parser* parser)
      linkage.  */
   if (current_lang_name == lang_name_c)
     {
-      error ("%Htemplate specialization with C linkage", &token->location);
+      error_at (token->location, "template specialization with C linkage");
       /* Give it C++ linkage to avoid confusing other parts of the
         front end.  */
       push_lang_context (lang_name_cplusplus);
@@ -10987,6 +12374,9 @@ cp_parser_type_specifier (cp_parser* parser,
   switch (keyword)
     {
     case RID_ENUM:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+       goto elaborated_type_specifier;
+
       /* Look for the enum-specifier.  */
       type_spec = cp_parser_enum_specifier (parser);
       /* If that worked, we're done.  */
@@ -11009,6 +12399,9 @@ cp_parser_type_specifier (cp_parser* parser,
     case RID_CLASS:
     case RID_STRUCT:
     case RID_UNION:
+      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
+       goto elaborated_type_specifier;
+
       /* Parse tentatively so that we can back up if we don't find a
         class-specifier.  */
       cp_parser_parse_tentatively (parser);
@@ -11132,6 +12525,7 @@ cp_parser_type_specifier (cp_parser* parser,
    GNU Extension:
 
    simple-type-specifier:
+     __int128
      __typeof__ unary-expression
      __typeof__ ( type-id )
 
@@ -11179,6 +12573,13 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        decl_specs->explicit_int_p = true;
       type = integer_type_node;
       break;
+    case RID_INT128:
+      if (!int128_integer_type_node)
+       break;
+      if (decl_specs)
+        decl_specs->explicit_int128_p = true;
+      type = int128_integer_type_node;
+      break;
     case RID_LONG:
       if (decl_specs)
        ++decl_specs->specs[(int) ds_long];
@@ -11205,7 +12606,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       break;
       
     case RID_AUTO:
-      maybe_warn_cpp0x ("C++0x auto");
+      maybe_warn_cpp0x (CPP0X_AUTO);
       type = make_auto ();
       break;
 
@@ -11243,8 +12644,6 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   /* If the type-specifier was for a built-in type, we're done.  */
   if (type)
     {
-      tree id;
-
       /* Record the type.  */
       if (decl_specs
          && (token->keyword != RID_SIGNED
@@ -11259,7 +12658,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        decl_specs->any_specifiers_p = true;
 
       /* Consume the token.  */
-      id = cp_lexer_consume_token (parser->lexer)->u.value;
+      cp_lexer_consume_token (parser->lexer);
 
       /* There is no valid C++ program where a non-template type is
         followed by a "<".  That usually indicates that the user thought
@@ -11447,7 +12846,7 @@ cp_parser_nonclass_name (cp_parser* parser)
     {
       if (!cp_parser_simulate_error (parser))
        cp_parser_name_lookup_error (parser, identifier, type_decl,
-                                    "is not a type", token->location);
+                                    NLE_TYPE, token->location);
       return error_mark_node;
     }
   /* Remember that the name was used in the definition of the
@@ -11496,6 +12895,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
   tree identifier;
   tree type = NULL_TREE;
   tree attributes = NULL_TREE;
+  tree globalscope;
   cp_token *token = NULL;
 
   /* See if we're looking at the `enum' keyword.  */
@@ -11511,7 +12911,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
           || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
         {
           if (cxx_dialect == cxx98)
-            maybe_warn_cpp0x ("scoped enums");
+            maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
           /* Consume the `struct' or `class'.  */
           cp_lexer_consume_token (parser->lexer);
@@ -11527,9 +12927,6 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       cp_lexer_consume_token (parser->lexer);
       /* Remember that it's a `typename' type.  */
       tag_type = typename_type;
-      /* The `typename' keyword is only allowed in templates.  */
-      if (!processing_template_decl)
-       permerror (input_location, "using %<typename%> outside of template");
     }
   /* Otherwise it must be a class-key.  */
   else
@@ -11542,10 +12939,10 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
     }
 
   /* Look for the `::' operator.  */
-  cp_parser_global_scope_opt (parser,
-                             /*current_scope_valid_p=*/false);
+  globalscope =  cp_parser_global_scope_opt (parser,
+                                            /*current_scope_valid_p=*/false);
   /* Look for the nested-name-specifier.  */
-  if (tag_type == typename_type)
+  if (tag_type == typename_type && !globalscope)
     {
       if (!cp_parser_nested_name_specifier (parser,
                                           /*typename_keyword_p=*/true,
@@ -11851,7 +13248,7 @@ cp_parser_enum_specifier (cp_parser* parser)
       || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
     {
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       /* Consume the `struct' or `class' token.  */
       cp_lexer_consume_token (parser->lexer);
@@ -11866,27 +13263,29 @@ cp_parser_enum_specifier (cp_parser* parser)
   else
     identifier = make_anon_name ();
 
-  /* Check for the `:' that denotes a specified underlying type in C++0x.  */
+  /* Check for the `:' that denotes a specified underlying type in C++0x.
+     Note that a ':' could also indicate a bitfield width, however.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
     {
       cp_decl_specifier_seq type_specifiers;
 
+      /* Consume the `:'.  */
+      cp_lexer_consume_token (parser->lexer);
+
+      /* Parse the type-specifier-seq.  */
+      cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                                   /*is_trailing_return=*/false,
+                                    &type_specifiers);
+
       /* At this point this is surely not elaborated type specifier.  */
       if (!cp_parser_parse_definitely (parser))
        return NULL_TREE;
 
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
-
-      /* Consume the `:'.  */
-      cp_lexer_consume_token (parser->lexer);
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       has_underlying_type = true;
 
-      /* Parse the type-specifier-seq.  */
-      cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
-                                    &type_specifiers);
-
       /* If that didn't work, stop.  */
       if (type_specifiers.type != error_mark_node)
         {
@@ -11931,7 +13330,7 @@ cp_parser_enum_specifier (cp_parser* parser)
     cp_parser_enumerator_list (parser, type);
 
   /* Consume the final '}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
   /* Look for trailing attributes to apply to this enumeration, and
      apply them if appropriate.  */
@@ -11996,6 +13395,11 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
 {
   tree identifier;
   tree value;
+  location_t loc;
+
+  /* Save the input location because we are interested in the location
+     of the identifier and not the location of the explicit value.  */
+  loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Look for the identifier.  */
   identifier = cp_parser_identifier (parser);
@@ -12021,7 +13425,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
     value = error_mark_node;
 
   /* Create the enumerator.  */
-  build_enumerator (identifier, value, type);
+  build_enumerator (identifier, value, type, loc);
 }
 
 /* Parse a namespace-name.
@@ -12075,7 +13479,7 @@ cp_parser_namespace_name (cp_parser* parser)
       || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
     {
       if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-       error ("%H%qD is not a namespace-name", &token->location, identifier);
+       error_at (token->location, "%qD is not a namespace-name", identifier);
       cp_parser_error (parser, "expected namespace-name");
       namespace_decl = error_mark_node;
     }
@@ -12111,6 +13515,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
     {
+      maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
       is_inline = true;
       cp_lexer_consume_token (parser->lexer);
     }
@@ -12118,7 +13523,7 @@ cp_parser_namespace_definition (cp_parser* parser)
     is_inline = false;
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
+  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
   /* Get the name of the namespace.  We do not attempt to distinguish
      between an original-namespace-definition and an
@@ -12133,7 +13538,7 @@ cp_parser_namespace_definition (cp_parser* parser)
   attribs = cp_parser_attributes_opt (parser);
 
   /* Look for the `{' to start the namespace.  */
-  cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>");
+  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
   /* Start the namespace.  */
   push_namespace (identifier);
 
@@ -12159,13 +13564,13 @@ cp_parser_namespace_definition (cp_parser* parser)
 
 #ifdef HANDLE_PRAGMA_VISIBILITY
   if (has_visibility)
-    pop_visibility ();
+    pop_visibility (1);
 #endif
 
   /* Finish the namespace.  */
   pop_namespace ();
   /* Look for the final `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 }
 
 /* Parse a namespace-body.
@@ -12193,7 +13598,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
+  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
   /* Look for the identifier.  */
   identifier = cp_parser_identifier (parser);
   if (identifier == error_mark_node)
@@ -12202,19 +13607,19 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
   if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
       && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) 
     {
-      error ("%H%<namespace%> definition is not allowed here", &token->location);
+      error_at (token->location, "%<namespace%> definition is not allowed here");
       /* Skip the definition.  */
       cp_lexer_consume_token (parser->lexer);
       if (cp_parser_skip_to_closing_brace (parser))
        cp_lexer_consume_token (parser->lexer);
       return;
     }
-  cp_parser_require (parser, CPP_EQ, "%<=%>");
+  cp_parser_require (parser, CPP_EQ, RT_EQ);
   /* Look for the qualified-namespace-specifier.  */
   namespace_specifier
     = cp_parser_qualified_namespace_specifier (parser);
   /* Look for the `;' token.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   /* Register the alias in the symbol table.  */
   do_namespace_alias (identifier, namespace_specifier);
@@ -12273,7 +13678,7 @@ cp_parser_using_declaration (cp_parser* parser,
   else
     {
       /* Look for the `using' keyword.  */
-      cp_parser_require_keyword (parser, RID_USING, "%<using%>");
+      cp_parser_require_keyword (parser, RID_USING, RT_USING);
       
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
@@ -12342,8 +13747,8 @@ cp_parser_using_declaration (cp_parser* parser,
     /* [namespace.udecl]
 
        A using declaration shall not name a template-id.  */
-    error ("%Ha template-id may not appear in a using-declaration",
-            &token->location);
+    error_at (token->location,
+             "a template-id may not appear in a using-declaration");
   else
     {
       if (at_class_scope_p ())
@@ -12364,7 +13769,7 @@ cp_parser_using_declaration (cp_parser* parser,
                                               token->location);
          if (decl == error_mark_node)
            cp_parser_name_lookup_error (parser, identifier,
-                                        decl, NULL,
+                                        decl, NLE_NULL,
                                         token->location);
          else if (check_for_bare_parameter_packs (decl))
            return false;
@@ -12376,7 +13781,7 @@ cp_parser_using_declaration (cp_parser* parser,
     }
 
   /* Look for the final `;'.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   
   return true;
 }
@@ -12394,9 +13799,9 @@ cp_parser_using_directive (cp_parser* parser)
   tree attribs;
 
   /* Look for the `using' keyword.  */
-  cp_parser_require_keyword (parser, RID_USING, "%<using%>");
+  cp_parser_require_keyword (parser, RID_USING, RT_USING);
   /* And the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
+  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
   /* Look for the optional `::' operator.  */
   cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
   /* And the optional nested-name-specifier.  */
@@ -12412,7 +13817,7 @@ cp_parser_using_directive (cp_parser* parser)
   /* Update the symbol table.  */
   parse_using_directive (namespace_decl, attribs);
   /* Look for the final `;'.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 }
 
 /* Parse an asm-definition.
@@ -12429,7 +13834,10 @@ cp_parser_using_directive (cp_parser* parser)
                          : asm-operand-list [opt] ) ;
      asm volatile [opt] ( string-literal : asm-operand-list [opt]
                          : asm-operand-list [opt]
-                         : asm-operand-list [opt] ) ;  */
+                         : asm-clobber-list [opt] ) ;
+     asm volatile [opt] goto ( string-literal : : asm-operand-list [opt]
+                              : asm-clobber-list [opt]
+                              : asm-goto-list ) ;  */
 
 static void
 cp_parser_asm_definition (cp_parser* parser)
@@ -12438,14 +13846,17 @@ cp_parser_asm_definition (cp_parser* parser)
   tree outputs = NULL_TREE;
   tree inputs = NULL_TREE;
   tree clobbers = NULL_TREE;
+  tree labels = NULL_TREE;
   tree asm_stmt;
   bool volatile_p = false;
   bool extended_p = false;
   bool invalid_inputs_p = false;
   bool invalid_outputs_p = false;
+  bool goto_p = false;
+  required_token missing = RT_NONE;
 
   /* Look for the `asm' keyword.  */
-  cp_parser_require_keyword (parser, RID_ASM, "%<asm%>");
+  cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
   /* See if the next token is `volatile'.  */
   if (cp_parser_allow_gnu_extensions_p (parser)
       && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE))
@@ -12455,8 +13866,17 @@ cp_parser_asm_definition (cp_parser* parser)
       /* Consume the token.  */
       cp_lexer_consume_token (parser->lexer);
     }
+  if (cp_parser_allow_gnu_extensions_p (parser)
+      && parser->in_function_body
+      && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO))
+    {
+      /* Remember that we saw the `goto' keyword.  */
+      goto_p = true;
+      /* Consume the token.  */
+      cp_lexer_consume_token (parser->lexer);
+    }
   /* Look for the opening `('.  */
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return;
   /* Look for the string.  */
   string = cp_parser_string_literal (parser, false, false);
@@ -12479,6 +13899,7 @@ cp_parser_asm_definition (cp_parser* parser)
     {
       bool inputs_p = false;
       bool clobbers_p = false;
+      bool labels_p = false;
 
       /* The extended syntax was used.  */
       extended_p = true;
@@ -12494,7 +13915,8 @@ cp_parser_asm_definition (cp_parser* parser)
              && cp_lexer_next_token_is_not (parser->lexer,
                                             CPP_SCOPE)
              && cp_lexer_next_token_is_not (parser->lexer,
-                                            CPP_CLOSE_PAREN))
+                                            CPP_CLOSE_PAREN)
+             && !goto_p)
            outputs = cp_parser_asm_operand_list (parser);
 
            if (outputs == error_mark_node)
@@ -12516,6 +13938,8 @@ cp_parser_asm_definition (cp_parser* parser)
          if (cp_lexer_next_token_is_not (parser->lexer,
                                          CPP_COLON)
              && cp_lexer_next_token_is_not (parser->lexer,
+                                            CPP_SCOPE)
+             && cp_lexer_next_token_is_not (parser->lexer,
                                             CPP_CLOSE_PAREN))
            inputs = cp_parser_asm_operand_list (parser);
 
@@ -12530,19 +13954,44 @@ cp_parser_asm_definition (cp_parser* parser)
       if (clobbers_p
          || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
        {
+         clobbers_p = true;
          /* Consume the `:' or `::'.  */
          cp_lexer_consume_token (parser->lexer);
          /* Parse the clobbers.  */
          if (cp_lexer_next_token_is_not (parser->lexer,
-                                         CPP_CLOSE_PAREN))
+                                         CPP_COLON)
+             && cp_lexer_next_token_is_not (parser->lexer,
+                                            CPP_CLOSE_PAREN))
            clobbers = cp_parser_asm_clobber_list (parser);
        }
+      else if (goto_p
+              && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+       /* The labels are coming next.  */
+       labels_p = true;
+
+      /* Look for labels.  */
+      if (labels_p
+         || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON)))
+       {
+         labels_p = true;
+         /* Consume the `:' or `::'.  */
+         cp_lexer_consume_token (parser->lexer);
+         /* Parse the labels.  */
+         labels = cp_parser_asm_label_list (parser);
+       }
+
+      if (goto_p && !labels_p)
+       missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE;
     }
+  else if (goto_p)
+    missing = RT_COLON_SCOPE;
+
   /* Look for the closing `)'.  */
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
+                         missing ? missing : RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, true, false,
                                           /*consume_paren=*/true);
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
   if (!invalid_inputs_p && !invalid_outputs_p)
     {
@@ -12550,7 +13999,7 @@ cp_parser_asm_definition (cp_parser* parser)
       if (parser->in_function_body)
        {
          asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
-                                     inputs, clobbers);
+                                     inputs, clobbers, labels);
          /* If the extended syntax was not used, mark the ASM_EXPR.  */
          if (!extended_p)
            {
@@ -12679,6 +14128,11 @@ cp_parser_init_declarator (cp_parser* parser,
      we compute it now.  */
   scope = get_scope_of_declarator (declarator);
 
+  /* Perform any lookups in the declared type which were thought to be
+     dependent, but are not in the scope of the declarator.  */
+  decl_specifiers->type
+    = maybe_update_decl_type (decl_specifiers->type, scope);
+
   /* If we're allowing GNU extensions, look for an asm-specification
      and attributes.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
@@ -12719,12 +14173,12 @@ cp_parser_init_declarator (cp_parser* parser,
          /* Neither attributes nor an asm-specification are allowed
             on a function-definition.  */
          if (asm_specification)
-           error ("%Han asm-specification is not allowed "
-                  "on a function-definition",
-                  &asm_spec_start_token->location);
+           error_at (asm_spec_start_token->location,
+                     "an asm-specification is not allowed "
+                     "on a function-definition");
          if (attributes)
-           error ("%Hattributes are not allowed on a function-definition",
-                  &attributes_start_token->location);
+           error_at (attributes_start_token->location,
+                     "attributes are not allowed on a function-definition");
          /* This is a function-definition.  */
          *function_definition_p = true;
 
@@ -12826,6 +14280,13 @@ cp_parser_init_declarator (cp_parser* parser,
       decl = start_decl (declarator, decl_specifiers,
                         is_initialized, attributes, prefix_attributes,
                         &pushed_scope);
+      /* Adjust location of decl if declarator->id_loc is more appropriate:
+        set, and decl wasn't merged with another decl, in which case its
+        location would be different from input_location, and more accurate.  */
+      if (DECL_P (decl)
+         && declarator->id_loc != UNKNOWN_LOCATION
+         && DECL_SOURCE_LOCATION (decl) == input_location)
+       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
     }
   else if (scope)
     /* Enter the SCOPE.  That way unqualified names appearing in the
@@ -12876,8 +14337,8 @@ cp_parser_init_declarator (cp_parser* parser,
                  know what the user intended, so just silently
                  consume the initializer.  */
               if (decl != error_mark_node)
-                error ("%Hinitializer provided for function",
-                       &initializer_start_token->location);
+                error_at (initializer_start_token->location,
+                          "initializer provided for function");
               cp_parser_skip_to_closing_parenthesis (parser,
                                                      /*recovering=*/true,
                                                      /*or_comma=*/false,
@@ -12885,9 +14346,21 @@ cp_parser_init_declarator (cp_parser* parser,
             }
        }
       else
-       initializer = cp_parser_initializer (parser,
-                                            &is_direct_init,
-                                            &is_non_constant_init);
+       {
+         /* We want to record the extra mangling scope for in-class
+            initializers of class members and initializers of static data
+            member templates.  The former is a C++0x feature which isn't
+            implemented yet, and I expect it will involve deferring
+            parsing of the initializer until end of class as with default
+            arguments.  So right here we only handle the latter.  */
+         if (!member_p && processing_template_decl)
+           start_lambda_scope (decl);
+         initializer = cp_parser_initializer (parser,
+                                              &is_direct_init,
+                                              &is_non_constant_init);
+         if (!member_p && processing_template_decl)
+           finish_lambda_scope ();
+       }
     }
 
   /* The old parser allows attributes to appear after a parenthesized
@@ -12929,7 +14402,7 @@ cp_parser_init_declarator (cp_parser* parser,
                         `explicit' constructor is OK.  Otherwise, an
                         `explicit' constructor cannot be used.  */
                      ((is_direct_init || !is_initialized)
-                      ? 0 : LOOKUP_ONLYCONVERTING));
+                      ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
     }
   else if ((cxx_dialect != cxx98) && friend_p
           && decl && TREE_CODE (decl) == FUNCTION_DECL)
@@ -12991,7 +14464,6 @@ cp_parser_declarator (cp_parser* parser,
                      bool* parenthesized_p,
                      bool member_p)
 {
-  cp_token *token;
   cp_declarator *declarator;
   enum tree_code code;
   cp_cv_quals cv_quals;
@@ -13006,9 +14478,6 @@ cp_parser_declarator (cp_parser* parser,
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-
   /* Check for the ptr-operator production.  */
   cp_parser_parse_tentatively (parser);
   /* Parse the ptr-operator.  */
@@ -13198,7 +14667,7 @@ cp_parser_direct_declarator (cp_parser* parser,
                    *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
                  first = false;
                  /* Consume the `)'.  */
-                 cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+                 cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
                  /* Parse the cv-qualifier-seq.  */
                  cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
@@ -13222,7 +14691,7 @@ cp_parser_direct_declarator (cp_parser* parser,
                }
 
              /* Remove the function parms from scope.  */
-             for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
+             for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
                pop_binding (DECL_NAME (t), t);
              leave_scope();
 
@@ -13252,7 +14721,7 @@ cp_parser_direct_declarator (cp_parser* parser,
              parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
              first = false;
              /* Expect a `)'.  */
-             if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+             if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
                declarator = cp_error_declarator;
              if (declarator == cp_error_declarator)
                break;
@@ -13291,27 +14760,28 @@ cp_parser_direct_declarator (cp_parser* parser,
                                                 &non_constant_p);
              if (!non_constant_p)
                bounds = fold_non_dependent_expr (bounds);
-             else if (processing_template_decl)
-               {
-                 /* Remember this wasn't a constant-expression.  */
-                 bounds = build_nop (TREE_TYPE (bounds), bounds);
-                 TREE_SIDE_EFFECTS (bounds) = 1;
-               }
-
              /* Normally, the array bound must be an integral constant
                 expression.  However, as an extension, we allow VLAs
-                in function scopes.  */
-             else if (!parser->in_function_body)
+                in function scopes as long as they aren't part of a
+                parameter declaration.  */
+             else if (!parser->in_function_body
+                      || current_binding_level->kind == sk_function_parms)
                {
-                 error ("%Harray bound is not an integer constant",
-                        &token->location);
+                 cp_parser_error (parser,
+                                  "array bound is not an integer constant");
                  bounds = error_mark_node;
                }
+             else if (processing_template_decl && !error_operand_p (bounds))
+               {
+                 /* Remember this wasn't a constant-expression.  */
+                 bounds = build_nop (TREE_TYPE (bounds), bounds);
+                 TREE_SIDE_EFFECTS (bounds) = 1;
+               }
            }
          else
            bounds = NULL_TREE;
          /* Look for the closing `]'.  */
-         if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>"))
+         if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
            {
              declarator = cp_error_declarator;
              break;
@@ -13321,181 +14791,195 @@ cp_parser_direct_declarator (cp_parser* parser,
        }
       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
        {
-         tree qualifying_scope;
-         tree unqualified_name;
-         special_function_kind sfk;
-         bool abstract_ok;
-          bool pack_expansion_p = false;
-         cp_token *declarator_id_start_token;
-
-         /* Parse a declarator-id */
-         abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
-         if (abstract_ok)
-            {
-              cp_parser_parse_tentatively (parser);
+         {
+           tree qualifying_scope;
+           tree unqualified_name;
+           special_function_kind sfk;
+           bool abstract_ok;
+           bool pack_expansion_p = false;
+           cp_token *declarator_id_start_token;
+
+           /* Parse a declarator-id */
+           abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
+           if (abstract_ok)
+             {
+               cp_parser_parse_tentatively (parser);
 
-              /* If we see an ellipsis, we should be looking at a
-                 parameter pack. */
-              if (token->type == CPP_ELLIPSIS)
-                {
-                  /* Consume the `...' */
-                  cp_lexer_consume_token (parser->lexer);
+               /* If we see an ellipsis, we should be looking at a
+                  parameter pack. */
+               if (token->type == CPP_ELLIPSIS)
+                 {
+                   /* Consume the `...' */
+                   cp_lexer_consume_token (parser->lexer);
 
-                  pack_expansion_p = true;
-                }
-            }
+                   pack_expansion_p = true;
+                 }
+             }
 
-         declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
-         unqualified_name
-           = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
-         qualifying_scope = parser->scope;
-         if (abstract_ok)
-           {
-              bool okay = false;
-
-              if (!unqualified_name && pack_expansion_p)
-                {
-                  /* Check whether an error occurred. */
-                  okay = !cp_parser_error_occurred (parser);
-
-                  /* We already consumed the ellipsis to mark a
-                     parameter pack, but we have no way to report it,
-                     so abort the tentative parse. We will be exiting
-                     immediately anyway. */
-                  cp_parser_abort_tentative_parse (parser);
-                }
-              else
-                okay = cp_parser_parse_definitely (parser);
-
-             if (!okay)
-               unqualified_name = error_mark_node;
-             else if (unqualified_name
-                      && (qualifying_scope
-                          || (TREE_CODE (unqualified_name)
-                              != IDENTIFIER_NODE)))
-               {
-                 cp_parser_error (parser, "expected unqualified-id");
-                 unqualified_name = error_mark_node;
-               }
-           }
+           declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
+           unqualified_name
+             = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
+           qualifying_scope = parser->scope;
+           if (abstract_ok)
+             {
+               bool okay = false;
 
-         if (!unqualified_name)
-           return NULL;
-         if (unqualified_name == error_mark_node)
-           {
-             declarator = cp_error_declarator;
-              pack_expansion_p = false;
-              declarator->parameter_pack_p = false;
-             break;
-           }
+               if (!unqualified_name && pack_expansion_p)
+                 {
+                   /* Check whether an error occurred. */
+                   okay = !cp_parser_error_occurred (parser);
+
+                   /* We already consumed the ellipsis to mark a
+                      parameter pack, but we have no way to report it,
+                      so abort the tentative parse. We will be exiting
+                      immediately anyway. */
+                   cp_parser_abort_tentative_parse (parser);
+                 }
+               else
+                 okay = cp_parser_parse_definitely (parser);
 
-         if (qualifying_scope && at_namespace_scope_p ()
-             && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
-           {
-             /* In the declaration of a member of a template class
-                outside of the class itself, the SCOPE will sometimes
-                be a TYPENAME_TYPE.  For example, given:
-
-                template <typename T>
-                int S<T>::R::i = 3;
-
-                the SCOPE will be a TYPENAME_TYPE for `S<T>::R'.  In
-                this context, we must resolve S<T>::R to an ordinary
-                type, rather than a typename type.
-
-                The reason we normally avoid resolving TYPENAME_TYPEs
-                is that a specialization of `S' might render
-                `S<T>::R' not a type.  However, if `S' is
-                specialized, then this `i' will not be used, so there
-                is no harm in resolving the types here.  */
-             tree type;
+               if (!okay)
+                 unqualified_name = error_mark_node;
+               else if (unqualified_name
+                        && (qualifying_scope
+                            || (TREE_CODE (unqualified_name)
+                                != IDENTIFIER_NODE)))
+                 {
+                   cp_parser_error (parser, "expected unqualified-id");
+                   unqualified_name = error_mark_node;
+                 }
+             }
 
-             /* Resolve the TYPENAME_TYPE.  */
-             type = resolve_typename_type (qualifying_scope,
-                                           /*only_current_p=*/false);
-             /* If that failed, the declarator is invalid.  */
-             if (TREE_CODE (type) == TYPENAME_TYPE)
-               error ("%H%<%T::%E%> is not a type",
-                      &declarator_id_start_token->location,
-                      TYPE_CONTEXT (qualifying_scope),
-                      TYPE_IDENTIFIER (qualifying_scope));
-             qualifying_scope = type;
-           }
+           if (!unqualified_name)
+             return NULL;
+           if (unqualified_name == error_mark_node)
+             {
+               declarator = cp_error_declarator;
+               pack_expansion_p = false;
+               declarator->parameter_pack_p = false;
+               break;
+             }
 
-         sfk = sfk_none;
+           if (qualifying_scope && at_namespace_scope_p ()
+               && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
+             {
+               /* In the declaration of a member of a template class
+                  outside of the class itself, the SCOPE will sometimes
+                  be a TYPENAME_TYPE.  For example, given:
+
+                  template <typename T>
+                  int S<T>::R::i = 3;
+
+                  the SCOPE will be a TYPENAME_TYPE for `S<T>::R'.  In
+                  this context, we must resolve S<T>::R to an ordinary
+                  type, rather than a typename type.
+
+                  The reason we normally avoid resolving TYPENAME_TYPEs
+                  is that a specialization of `S' might render
+                  `S<T>::R' not a type.  However, if `S' is
+                  specialized, then this `i' will not be used, so there
+                  is no harm in resolving the types here.  */
+               tree type;
+
+               /* Resolve the TYPENAME_TYPE.  */
+               type = resolve_typename_type (qualifying_scope,
+                                             /*only_current_p=*/false);
+               /* If that failed, the declarator is invalid.  */
+               if (TREE_CODE (type) == TYPENAME_TYPE)
+                 {
+                   if (typedef_variant_p (type))
+                     error_at (declarator_id_start_token->location,
+                               "cannot define member of dependent typedef "
+                               "%qT", type);
+                   else
+                     error_at (declarator_id_start_token->location,
+                               "%<%T::%E%> is not a type",
+                               TYPE_CONTEXT (qualifying_scope),
+                               TYPE_IDENTIFIER (qualifying_scope));
+                 }
+               qualifying_scope = type;
+             }
 
-         if (unqualified_name)
-           {
-             tree class_type;
+           sfk = sfk_none;
 
-             if (qualifying_scope
-                 && CLASS_TYPE_P (qualifying_scope))
-               class_type = qualifying_scope;
-             else
-               class_type = current_class_type;
+           if (unqualified_name)
+             {
+               tree class_type;
 
-             if (TREE_CODE (unqualified_name) == TYPE_DECL)
-               {
-                 tree name_type = TREE_TYPE (unqualified_name);
-                 if (class_type && same_type_p (name_type, class_type))
-                   {
-                     if (qualifying_scope
-                         && CLASSTYPE_USE_TEMPLATE (name_type))
-                       {
-                         error ("%Hinvalid use of constructor as a template",
-                                &declarator_id_start_token->location);
-                         inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to "
-                                 "name the constructor in a qualified name",
-                                 class_type,
-                                 DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
-                                 class_type, name_type);
-                         declarator = cp_error_declarator;
-                         break;
-                       }
-                     else
-                       unqualified_name = constructor_name (class_type);
-                   }
-                 else
-                   {
-                     /* We do not attempt to print the declarator
-                        here because we do not have enough
-                        information about its original syntactic
-                        form.  */
-                     cp_parser_error (parser, "invalid declarator");
-                     declarator = cp_error_declarator;
-                     break;
-                   }
-               }
+               if (qualifying_scope
+                   && CLASS_TYPE_P (qualifying_scope))
+                 class_type = qualifying_scope;
+               else
+                 class_type = current_class_type;
 
-             if (class_type)
-               {
-                 if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
-                   sfk = sfk_destructor;
-                 else if (IDENTIFIER_TYPENAME_P (unqualified_name))
-                   sfk = sfk_conversion;
-                 else if (/* There's no way to declare a constructor
-                             for an anonymous type, even if the type
-                             got a name for linkage purposes.  */
-                          !TYPE_WAS_ANONYMOUS (class_type)
-                          && constructor_name_p (unqualified_name,
-                                                 class_type))
-                   {
-                     unqualified_name = constructor_name (class_type);
-                     sfk = sfk_constructor;
-                   }
+               if (TREE_CODE (unqualified_name) == TYPE_DECL)
+                 {
+                   tree name_type = TREE_TYPE (unqualified_name);
+                   if (class_type && same_type_p (name_type, class_type))
+                     {
+                       if (qualifying_scope
+                           && CLASSTYPE_USE_TEMPLATE (name_type))
+                         {
+                           error_at (declarator_id_start_token->location,
+                                     "invalid use of constructor as a template");
+                           inform (declarator_id_start_token->location,
+                                   "use %<%T::%D%> instead of %<%T::%D%> to "
+                                   "name the constructor in a qualified name",
+                                   class_type,
+                                   DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+                                   class_type, name_type);
+                           declarator = cp_error_declarator;
+                           break;
+                         }
+                       else
+                         unqualified_name = constructor_name (class_type);
+                     }
+                   else
+                     {
+                       /* We do not attempt to print the declarator
+                          here because we do not have enough
+                          information about its original syntactic
+                          form.  */
+                       cp_parser_error (parser, "invalid declarator");
+                       declarator = cp_error_declarator;
+                       break;
+                     }
+                 }
 
-                 if (ctor_dtor_or_conv_p && sfk != sfk_none)
-                   *ctor_dtor_or_conv_p = -1;
-               }
-           }
-         declarator = make_id_declarator (qualifying_scope,
-                                          unqualified_name,
-                                          sfk);
-         declarator->id_loc = token->location;
-          declarator->parameter_pack_p = pack_expansion_p;
+               if (class_type)
+                 {
+                   if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
+                     sfk = sfk_destructor;
+                   else if (IDENTIFIER_TYPENAME_P (unqualified_name))
+                     sfk = sfk_conversion;
+                   else if (/* There's no way to declare a constructor
+                               for an anonymous type, even if the type
+                               got a name for linkage purposes.  */
+                            !TYPE_WAS_ANONYMOUS (class_type)
+                            && constructor_name_p (unqualified_name,
+                                                   class_type))
+                     {
+                       unqualified_name = constructor_name (class_type);
+                       sfk = sfk_constructor;
+                     }
+                   else if (is_overloaded_fn (unqualified_name)
+                            && DECL_CONSTRUCTOR_P (get_first_fn
+                                                   (unqualified_name)))
+                     sfk = sfk_constructor;
 
-          if (pack_expansion_p)
-            maybe_warn_variadic_templates ();
+                   if (ctor_dtor_or_conv_p && sfk != sfk_none)
+                     *ctor_dtor_or_conv_p = -1;
+                 }
+             }
+           declarator = make_id_declarator (qualifying_scope,
+                                            unqualified_name,
+                                            sfk);
+           declarator->id_loc = token->location;
+           declarator->parameter_pack_p = pack_expansion_p;
+
+           if (pack_expansion_p)
+             maybe_warn_variadic_templates ();
+         }
 
        handle_declarator:;
          scope = get_scope_of_declarator (declarator);
@@ -13611,13 +15095,13 @@ cp_parser_ptr_operator (cp_parser* parser,
       /* If we found it, and the next token is a `*', then we are
         indeed looking at a pointer-to-member operator.  */
       if (!cp_parser_error_occurred (parser)
-         && cp_parser_require (parser, CPP_MULT, "%<*%>"))
+         && cp_parser_require (parser, CPP_MULT, RT_MULT))
        {
          /* Indicate that the `*' operator was used.  */
          code = INDIRECT_REF;
 
          if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
-           error ("%H%qD is a namespace", &token->location, parser->scope);
+           error_at (token->location, "%qD is a namespace", parser->scope);
          else
            {
              /* The type of which the member is a member is given by the
@@ -13692,7 +15176,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 
       if (cv_quals & cv_qualifier)
        {
-         error ("%Hduplicate cv-qualifier", &token->location);
+         error_at (token->location, "duplicate cv-qualifier");
          cp_lexer_purge_token (parser->lexer);
        }
       else
@@ -13708,7 +15192,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 /* Parse a late-specified return type, if any.  This is not a separate
    non-terminal, but part of a function declarator, which looks like
 
-   -> type-id
+   -> trailing-type-specifier-seq abstract-declarator(opt)
 
    Returns the type indicated by the type-id.  */
 
@@ -13726,7 +15210,7 @@ cp_parser_late_return_type_opt (cp_parser* parser)
   /* Consume the ->.  */
   cp_lexer_consume_token (parser->lexer);
 
-  return cp_parser_type_id (parser);
+  return cp_parser_trailing_type_id (parser);
 }
 
 /* Parse a declarator-id.
@@ -13779,13 +15263,15 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
    Returns the TYPE specified.  */
 
 static tree
-cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
+cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
+                    bool is_trailing_return)
 {
   cp_decl_specifier_seq type_specifier_seq;
   cp_declarator *abstract_declarator;
 
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
+                               is_trailing_return,
                                &type_specifier_seq);
   if (type_specifier_seq.type == error_mark_node)
     return error_mark_node;
@@ -13804,8 +15290,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
   if (type_specifier_seq.type
       && type_uses_auto (type_specifier_seq.type))
     {
-      error ("invalid use of %<auto%>");
-      return error_mark_node;
+      /* A type-id with type 'auto' is only ok if the abstract declarator
+        is a function declarator with a late-specified return type.  */
+      if (abstract_declarator
+         && abstract_declarator->kind == cdk_function
+         && abstract_declarator->u.function.late_return_type)
+       /* OK */;
+      else
+       {
+         error ("invalid use of %<auto%>");
+         return error_mark_node;
+       }
     }
   
   return groktypename (&type_specifier_seq, abstract_declarator,
@@ -13814,12 +15309,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
 
 static tree cp_parser_type_id (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, false);
+  return cp_parser_type_id_1 (parser, false, false);
 }
 
 static tree cp_parser_template_type_arg (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, true);
+  return cp_parser_type_id_1 (parser, true, false);
+}
+
+static tree cp_parser_trailing_type_id (cp_parser *parser)
+{
+  return cp_parser_type_id_1 (parser, false, true);
 }
 
 /* Parse a type-specifier-seq.
@@ -13832,14 +15332,18 @@ static tree cp_parser_template_type_arg (cp_parser *parser)
    type-specifier-seq:
      attributes type-specifier-seq [opt]
 
-   If IS_CONDITION is true, we are at the start of a "condition",
-   e.g., we've just seen "if (".
+   If IS_DECLARATION is true, we are at the start of a "condition" or
+   exception-declaration, so we might be followed by a declarator-id.
+
+   If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
+   i.e. we've just seen "->".
 
    Sets *TYPE_SPECIFIER_SEQ to represent the sequence.  */
 
 static void
 cp_parser_type_specifier_seq (cp_parser* parser,
-                             bool is_condition,
+                             bool is_declaration,
+                             bool is_trailing_return,
                              cp_decl_specifier_seq *type_specifier_seq)
 {
   bool seen_type_specifier = false;
@@ -13849,6 +15353,12 @@ cp_parser_type_specifier_seq (cp_parser* parser,
   /* Clear the TYPE_SPECIFIER_SEQ.  */
   clear_decl_specs (type_specifier_seq);
 
+  /* In the context of a trailing return type, enum E { } is an
+     elaborated-type-specifier followed by a function-body, not an
+     enum-specifier.  */
+  if (is_trailing_return)
+    flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
+
   /* Parse the type-specifiers and attributes.  */
   while (true)
     {
@@ -13908,7 +15418,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
         would be clearer just to allow a decl-specifier-seq here, and
         then add a semantic restriction that if any decl-specifiers
         that are not type-specifiers appear, the program is invalid.  */
-      if (is_condition && !is_cv_qualifier)
+      if (is_declaration && !is_cv_qualifier)
        flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
     }
 
@@ -13981,7 +15491,7 @@ cp_parser_parameter_declaration_clause (cp_parser* parser)
       cp_lexer_consume_token (parser->lexer);
       /* Expect an ellipsis.  */
       ellipsis_p
-       = (cp_parser_require (parser, CPP_ELLIPSIS, "%<...%>") != NULL);
+       = (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL);
     }
   /* It might also be `...' if the optional trailing `,' was
      omitted.  */
@@ -14019,6 +15529,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
   tree parameters = NULL_TREE;
   tree *tail = &parameters; 
   bool saved_in_unbraced_linkage_specification_p;
+  int index = 0;
 
   /* Assume all will go well.  */
   *is_error = false;
@@ -14070,6 +15581,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
       if (DECL_NAME (decl))
        decl = pushdecl (decl);
 
+      if (decl != error_mark_node)
+       {
+         retrofit_lang_decl (decl);
+         DECL_PARM_INDEX (decl) = ++index;
+       }
+
       /* Add the new parameter to the list.  */
       *tail = build_tree_list (parameter->default_argument, decl);
       tail = &TREE_CHAIN (*tail);
@@ -14157,7 +15674,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
                                 bool *parenthesized_p)
 {
   int declares_class_or_enum;
-  bool greater_than_is_operator_p;
   cp_decl_specifier_seq decl_specifiers;
   cp_declarator *declarator;
   tree default_argument;
@@ -14172,18 +15688,22 @@ cp_parser_parameter_declaration (cp_parser *parser,
      template-parameter, the first non-nested `>' is taken as the end
      of the template parameter-list rather than a greater-than
      operator.  */
-  greater_than_is_operator_p = !template_parm_p;
 
   /* Type definitions may not appear in parameter types.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in parameter types";
+    = G_("types may not be defined in parameter types");
 
   /* Parse the declaration-specifiers.  */
   cp_parser_decl_specifier_seq (parser,
                                CP_PARSER_FLAGS_NONE,
                                &decl_specifiers,
                                &declares_class_or_enum);
+
+  /* Complain about missing 'typename' or other invalid type names.  */
+  if (!decl_specifiers.any_type_specifiers_p)
+    cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
   /* If an error occurred, there's no reason to attempt to parse the
      rest of the declaration.  */
   if (cp_parser_error_occurred (parser))
@@ -14287,7 +15807,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
       /* If we are defining a class, then the tokens that make up the
         default argument must be saved and processed later.  */
       if (!template_parm_p && at_class_scope_p ()
-         && TYPE_BEING_DEFINED (current_class_type))
+         && TYPE_BEING_DEFINED (current_class_type)
+         && !LAMBDA_TYPE_P (current_class_type))
        {
          unsigned depth = 0;
          int maybe_template_id = 0;
@@ -14320,6 +15841,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
                         the default argument; otherwise the default
                         argument continues.  */
                      bool error = false;
+                     tree t;
 
                      /* Set ITALP so cp_parser_parameter_declaration_list
                         doesn't decide to commit to this parse.  */
@@ -14328,7 +15850,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
 
                      cp_parser_parse_tentatively (parser);
                      cp_lexer_consume_token (parser->lexer);
+                     begin_scope (sk_function_parms, NULL_TREE);
                      cp_parser_parameter_declaration_list (parser, &error);
+                     for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
+                       pop_binding (DECL_NAME (t), t);
+                     leave_scope ();
                      if (!cp_parser_error_occurred (parser) && !error)
                        done = true;
                      cp_parser_abort_tentative_parse (parser);
@@ -14389,7 +15915,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
                  /* If we run out of tokens, issue an error message.  */
                case CPP_EOF:
                case CPP_PRAGMA_EOL:
-                 error ("%Hfile ends in default argument", &token->location);
+                 error_at (token->location, "file ends in default argument");
                  done = true;
                  break;
 
@@ -14438,9 +15964,9 @@ cp_parser_parameter_declaration (cp_parser *parser,
            warning (0, "deprecated use of default argument for parameter of non-function");
          else
            {
-             error ("%Hdefault arguments are only "
-                    "permitted for function parameters",
-                    &token->location);
+             error_at (token->location,
+                       "default arguments are only "
+                       "permitted for function parameters");
              default_argument = NULL_TREE;
            }
        }
@@ -14448,20 +15974,23 @@ cp_parser_parameter_declaration (cp_parser *parser,
               || (decl_specifiers.type
                   && PACK_EXPANSION_P (decl_specifiers.type)))
        {
-         const char* kind = template_parm_p? "template " : "";
-         
          /* Find the name of the parameter pack.  */     
          cp_declarator *id_declarator = declarator;
          while (id_declarator && id_declarator->kind != cdk_id)
            id_declarator = id_declarator->declarator;
          
          if (id_declarator && id_declarator->kind == cdk_id)
-           error ("%H%sparameter pack %qD cannot have a default argument",
-                  &declarator_token_start->location,
-                  kind, id_declarator->u.id.unqualified_name);
+           error_at (declarator_token_start->location,
+                     template_parm_p 
+                     ? "template parameter pack %qD"
+                     " cannot have a default argument"
+                     : "parameter pack %qD cannot have a default argument",
+                     id_declarator->u.id.unqualified_name);
          else
-           error ("%H%sparameter pack cannot have a default argument",
-                  &declarator_token_start->location, kind);
+           error_at (declarator_token_start->location,
+                     template_parm_p 
+                     ? "template parameter pack cannot have a default argument"
+                     : "parameter pack cannot have a default argument");
          
          default_argument = NULL_TREE;
        }
@@ -14493,12 +16022,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
      appear in a default argument.  */
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
   parser->local_variables_forbidden_p = true;
-  /* The default argument expression may cause implicitly
-     defined member functions to be synthesized, which will
-     result in garbage collection.  We must treat this
-     situation as if we were within the body of function so as
-     to avoid collecting live data on the stack.  */
-  ++function_depth;
   /* Parse the assignment-expression.  */
   if (template_parm_p)
     push_deferring_access_checks (dk_no_deferred);
@@ -14506,8 +16029,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
     = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
   if (template_parm_p)
     pop_deferring_access_checks ();
-  /* Restore saved state.  */
-  --function_depth;
   parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
   parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
 
@@ -14585,13 +16106,20 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
       init = cp_parser_initializer_clause (parser, non_constant_p);
     }
   else if (token->type == CPP_OPEN_PAREN)
-    init = cp_parser_parenthesized_expression_list (parser, false,
-                                                   /*cast_p=*/false,
-                                                    /*allow_expansion_p=*/true,
-                                                   non_constant_p);
+    {
+      VEC(tree,gc) *vec;
+      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+                                                    /*cast_p=*/false,
+                                                    /*allow_expansion_p=*/true,
+                                                    non_constant_p);
+      if (vec == NULL)
+       return error_mark_node;
+      init = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
   else if (token->type == CPP_OPEN_BRACE)
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       init = cp_parser_braced_list (parser, non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
     }
@@ -14676,7 +16204,7 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
        cp_lexer_consume_token (parser->lexer);
     }
   /* Now, there should be a trailing `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
   TREE_TYPE (initializer) = init_list_type_node;
   return initializer;
 }
@@ -14876,14 +16404,8 @@ cp_parser_class_name (cp_parser *parser,
                                        identifier_token->location);
          if (ambiguous_decls)
            {
-             error ("%Hreference to %qD is ambiguous",
-                    &identifier_token->location, identifier);
-             print_candidates (ambiguous_decls);
              if (cp_parser_parsing_tentatively (parser))
-               {
-                 identifier_token->ambiguous_p = true;
-                 cp_parser_simulate_error (parser);
-               }
+               cp_parser_simulate_error (parser);
              return error_mark_node;
            }
        }
@@ -14978,7 +16500,7 @@ cp_parser_class_specifier (cp_parser* parser)
     }
 
   /* Look for the `{'.  */
-  if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
     {
       pop_deferring_access_checks ();
       return error_mark_node;
@@ -15029,7 +16551,7 @@ cp_parser_class_specifier (cp_parser* parser)
     cp_parser_member_specification_opt (parser);
 
   /* Look for the trailing `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
   /* Look for trailing attributes to apply to this class.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
@@ -15059,10 +16581,11 @@ cp_parser_class_specifier (cp_parser* parser)
      there is no need to delay the parsing of `A::B::f'.  */
   if (--parser->num_classes_being_defined == 0)
     {
-      tree queue_entry;
       tree fn;
       tree class_type = NULL_TREE;
       tree pushed_scope = NULL_TREE;
+      unsigned ix;
+      cp_default_arg_entry *e;
 
       /* In a first pass, parse default arguments to the functions.
         Then, in a second pass, parse the bodies of the functions.
@@ -15074,20 +16597,17 @@ cp_parser_class_specifier (cp_parser* parser)
            };
 
         */
-      for (TREE_PURPOSE (parser->unparsed_functions_queues)
-            = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues));
-          (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues));
-          TREE_PURPOSE (parser->unparsed_functions_queues)
-            = TREE_CHAIN (TREE_PURPOSE (parser->unparsed_functions_queues)))
+      FOR_EACH_VEC_ELT (cp_default_arg_entry, unparsed_funs_with_default_args,
+                       ix, e)
        {
-         fn = TREE_VALUE (queue_entry);
+         fn = e->decl;
          /* If there are default arguments that have not yet been processed,
             take care of them now.  */
-         if (class_type != TREE_PURPOSE (queue_entry))
+         if (class_type != e->class_type)
            {
              if (pushed_scope)
                pop_scope (pushed_scope);
-             class_type = TREE_PURPOSE (queue_entry);
+             class_type = e->class_type;
              pushed_scope = push_scope (class_type);
            }
          /* Make sure that any template parameters are in scope.  */
@@ -15099,18 +16619,11 @@ cp_parser_class_specifier (cp_parser* parser)
        }
       if (pushed_scope)
        pop_scope (pushed_scope);
+      VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
       /* Now parse the body of the functions.  */
-      for (TREE_VALUE (parser->unparsed_functions_queues)
-            = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
-          (queue_entry = TREE_VALUE (parser->unparsed_functions_queues));
-          TREE_VALUE (parser->unparsed_functions_queues)
-            = TREE_CHAIN (TREE_VALUE (parser->unparsed_functions_queues)))
-       {
-         /* Figure out which function we need to process.  */
-         fn = TREE_VALUE (queue_entry);
-         /* Parse the function.  */
-         cp_parser_late_parsing_for_member (parser, fn);
-       }
+      FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, fn)
+       cp_parser_late_parsing_for_member (parser, fn);
+      VEC_truncate (tree, unparsed_funs_with_definitions, 0);
     }
 
   /* Put back any saved access checks.  */
@@ -15342,8 +16855,9 @@ cp_parser_class_head (cp_parser* parser,
       /* Reject typedef-names in class heads.  */
       if (!DECL_IMPLICIT_TYPEDEF_P (type))
        {
-         error ("%Hinvalid class name in declaration of %qD",
-                &type_start_token->location, type);
+         error_at (type_start_token->location,
+                   "invalid class name in declaration of %qD",
+                   type);
          type = NULL_TREE;
          goto done;
        }
@@ -15355,14 +16869,14 @@ cp_parser_class_head (cp_parser* parser,
       if (scope && !is_ancestor (scope, nested_name_specifier))
        {
          if (at_namespace_scope_p ())
-           error ("%Hdeclaration of %qD in namespace %qD which does not "
-                  "enclose %qD",
-                  &type_start_token->location,
-                  type, scope, nested_name_specifier);
+           error_at (type_start_token->location,
+                     "declaration of %qD in namespace %qD which does not "
+                     "enclose %qD",
+                     type, scope, nested_name_specifier);
          else
-           error ("%Hdeclaration of %qD in %qD which does not enclose %qD",
-                  &type_start_token->location,
-                  type, scope, nested_name_specifier);
+           error_at (type_start_token->location,
+                     "declaration of %qD in %qD which does not enclose %qD",
+                     type, scope, nested_name_specifier);
          type = NULL_TREE;
          goto done;
        }
@@ -15374,8 +16888,8 @@ cp_parser_class_head (cp_parser* parser,
         class member of a namespace outside of its namespace.  */
       if (scope == nested_name_specifier)
        {
-         permerror (input_location, "%Hextra qualification not allowed",
-                    &nested_name_specifier_token_start->location);
+         permerror (nested_name_specifier_token_start->location,
+                    "extra qualification not allowed");
          nested_name_specifier = NULL_TREE;
          num_templates = 0;
        }
@@ -15386,8 +16900,8 @@ cp_parser_class_head (cp_parser* parser,
       && parser->num_template_parameter_lists == 0
       && template_id_p)
     {
-      error ("%Han explicit specialization must be preceded by %<template <>%>",
-            &type_start_token->location);
+      error_at (type_start_token->location,
+               "an explicit specialization must be preceded by %<template <>%>");
       invalid_explicit_specialization_p = true;
       /* Take the same action that would have been taken by
         cp_parser_explicit_specialization.  */
@@ -15416,8 +16930,8 @@ cp_parser_class_head (cp_parser* parser,
          && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
              || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
        {
-         error ("%Hfunction template %qD redeclared as a class template",
-                &type_start_token->location, id);
+         error_at (type_start_token->location,
+                   "function template %qD redeclared as a class template", id);
          type = error_mark_node;
        }
       else
@@ -15498,10 +17012,10 @@ cp_parser_class_head (cp_parser* parser,
      that's an error.  */
   if (type != error_mark_node && COMPLETE_TYPE_P (type))
     {
-      error ("%Hredefinition of %q#T",
-            &type_start_token->location, type);
-      error ("%Hprevious definition of %q+#T",
-            &type_start_token->location, type);
+      error_at (type_start_token->location, "redefinition of %q#T",
+               type);
+      error_at (type_start_token->location, "previous definition of %q+#T",
+               type);
       type = NULL_TREE;
       goto done;
     }
@@ -15531,6 +17045,9 @@ cp_parser_class_head (cp_parser* parser,
       end_specialization ();
       --parser->num_template_parameter_lists;
     }
+
+  if (type)
+    DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
   *attributes_p = attributes;
   return type;
 }
@@ -15552,7 +17069,7 @@ cp_parser_class_key (cp_parser* parser)
   enum tag_types tag_type;
 
   /* Look for the class-key.  */
-  token = cp_parser_require (parser, CPP_KEYWORD, "class-key");
+  token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY);
   if (!token)
     return none_type;
 
@@ -15597,7 +17114,7 @@ cp_parser_member_specification_opt (cp_parser* parser)
          /* Remember which access-specifier is active.  */
          current_access_specifier = token->u.value;
          /* Look for the `:'.  */
-         cp_parser_require (parser, CPP_COLON, "%<:%>");
+         cp_parser_require (parser, CPP_COLON, RT_COLON);
          break;
 
        default:
@@ -15730,7 +17247,7 @@ cp_parser_member_declaration (cp_parser* parser)
   prefix_attributes = decl_specifiers.attributes;
   decl_specifiers.attributes = NULL_TREE;
   /* Check for an invalid type-name.  */
-  if (!decl_specifiers.type
+  if (!decl_specifiers.any_type_specifiers_p
       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     return;
   /* If there is no declarator, then the decl-specifier-seq should
@@ -15768,8 +17285,8 @@ cp_parser_member_declaration (cp_parser* parser)
              /* If the `friend' keyword was present, the friend must
                 be introduced with a class-key.  */
               if (!declares_class_or_enum)
-                error ("%Ha class-key must be used when declaring a friend",
-                        &decl_spec_token_start->location);
+                error_at (decl_spec_token_start->location,
+                          "a class-key must be used when declaring a friend");
               /* In this case:
 
                    template <typename T> struct A {
@@ -15783,8 +17300,9 @@ cp_parser_member_declaration (cp_parser* parser)
                   && TYPE_P (decl_specifiers.type))
                 type = decl_specifiers.type;
               if (!type || !TYPE_P (type))
-                error ("%Hfriend declaration does not name a class or "
-                       "function", &decl_spec_token_start->location);
+                error_at (decl_spec_token_start->location,
+                          "friend declaration does not name a class or "
+                          "function");
               else
                 make_friend_class (current_class_type, type,
                                    /*complain=*/true);
@@ -15802,7 +17320,8 @@ cp_parser_member_declaration (cp_parser* parser)
                 know it is an anonymous aggregate.  */
              fixup_anonymous_aggr (type);
              /* And make the corresponding data member.  */
-             decl = build_decl (FIELD_DECL, NULL_TREE, type);
+             decl = build_decl (decl_spec_token_start->location,
+                                FIELD_DECL, NULL_TREE, type);
              /* Add it to the class.  */
              finish_member_declaration (decl);
            }
@@ -15963,8 +17482,8 @@ cp_parser_member_declaration (cp_parser* parser)
                     standard, since a pure function may be defined
                     outside of the class-specifier.  */
                  if (initializer)
-                   error ("%Hpure-specifier on function-definition",
-                          &initializer_token_start->location);
+                   error_at (initializer_token_start->location,
+                             "pure-specifier on function-definition");
                  decl = cp_parser_save_member_function_body (parser,
                                                              &decl_specifiers,
                                                              declarator,
@@ -16026,7 +17545,7 @@ cp_parser_member_declaration (cp_parser* parser)
        }
     }
 
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 }
 
 /* Parse a pure-specifier.
@@ -16043,7 +17562,7 @@ cp_parser_pure_specifier (cp_parser* parser)
   cp_token *token;
 
   /* Look for the `=' token.  */
-  if (!cp_parser_require (parser, CPP_EQ, "%<=%>"))
+  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
     return error_mark_node;
   /* Look for the `0' token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -16058,7 +17577,7 @@ cp_parser_pure_specifier (cp_parser* parser)
   if (token->keyword == RID_DEFAULT
       || token->keyword == RID_DELETE)
     {
-      maybe_warn_cpp0x ("defaulted and deleted functions");
+      maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
       return token->u.value;
     }
 
@@ -16072,7 +17591,7 @@ cp_parser_pure_specifier (cp_parser* parser)
     }
   if (PROCESSING_REAL_TEMPLATE_DECL_P ())
     {
-      error ("%Htemplates may not be %<virtual%>", &token->location);
+      error_at (token->location, "templates may not be %<virtual%>");
       return error_mark_node;
     }
 
@@ -16090,7 +17609,7 @@ static tree
 cp_parser_constant_initializer (cp_parser* parser)
 {
   /* Look for the `=' token.  */
-  if (!cp_parser_require (parser, CPP_EQ, "%<=%>"))
+  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
     return error_mark_node;
 
   /* It is invalid to write:
@@ -16107,7 +17626,7 @@ cp_parser_constant_initializer (cp_parser* parser)
       /* Skip the initializer.  */
       cp_parser_skip_to_closing_brace (parser);
       /* Look for the trailing `}'.  */
-      cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
       return error_mark_node;
     }
@@ -16141,7 +17660,7 @@ cp_parser_base_clause (cp_parser* parser)
   tree bases = NULL_TREE;
 
   /* Look for the `:' that begins the list.  */
-  cp_parser_require (parser, CPP_COLON, "%<:%>");
+  cp_parser_require (parser, CPP_COLON, RT_COLON);
 
   /* Scan the base-specifier-list.  */
   while (true)
@@ -16276,12 +17795,12 @@ cp_parser_base_specifier (cp_parser* parser)
     {
       token = cp_lexer_peek_token (parser->lexer);
       if (!processing_template_decl)
-       error ("%Hkeyword %<typename%> not allowed outside of templates",
-              &token->location);
+       error_at (token->location,
+                 "keyword %<typename%> not allowed outside of templates");
       else
-       error ("%Hkeyword %<typename%> not allowed in this context "
-              "(the base class is implicitly a type)",
-              &token->location);
+       error_at (token->location,
+                 "keyword %<typename%> not allowed in this context "
+                 "(the base class is implicitly a type)");
       cp_lexer_consume_token (parser->lexer);
     }
 
@@ -16339,30 +17858,65 @@ cp_parser_exception_specification_opt (cp_parser* parser)
 {
   cp_token *token;
   tree type_id_list;
+  const char *saved_message;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
+
+  /* Is it a noexcept-specification?  */
+  if (cp_parser_is_keyword (token, RID_NOEXCEPT))
+    {
+      tree expr;
+      cp_lexer_consume_token (parser->lexer);
+
+      if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+       {
+         cp_lexer_consume_token (parser->lexer);
+
+         /* Types may not be defined in an exception-specification.  */
+         saved_message = parser->type_definition_forbidden_message;
+         parser->type_definition_forbidden_message
+           = G_("types may not be defined in an exception-specification");
+
+         expr = cp_parser_constant_expression (parser, false, NULL);
+
+         /* Restore the saved message.  */
+         parser->type_definition_forbidden_message = saved_message;
+
+         cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+       }
+      else
+       expr = boolean_true_node;
+
+      return build_noexcept_spec (expr, tf_warning_or_error);
+    }
+
   /* If it's not `throw', then there's no exception-specification.  */
   if (!cp_parser_is_keyword (token, RID_THROW))
     return NULL_TREE;
 
+#if 0
+  /* Enable this once a lot of code has transitioned to noexcept?  */
+  if (cxx_dialect == cxx0x && !in_system_header)
+    warning (OPT_Wdeprecated, "dynamic exception specifications are "
+            "deprecated in C++0x; use %<noexcept%> instead.");
+#endif
+
   /* Consume the `throw'.  */
   cp_lexer_consume_token (parser->lexer);
 
   /* Look for the `('.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
   /* If it's not a `)', then there is a type-id-list.  */
   if (token->type != CPP_CLOSE_PAREN)
     {
-      const char *saved_message;
-
       /* Types may not be defined in an exception-specification.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in an exception-specification";
+       = G_("types may not be defined in an exception-specification");
       /* Parse the type-id-list.  */
       type_id_list = cp_parser_type_id_list (parser);
       /* Restore the saved message.  */
@@ -16372,7 +17926,7 @@ cp_parser_exception_specification_opt (cp_parser* parser)
     type_id_list = empty_except_spec;
 
   /* Look for the `)'.  */
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   return type_id_list;
 }
@@ -16431,7 +17985,7 @@ cp_parser_try_block (cp_parser* parser)
 {
   tree try_block;
 
-  cp_parser_require_keyword (parser, RID_TRY, "%<try%>");
+  cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
   try_block = begin_try_block ();
   cp_parser_compound_statement (parser, NULL, true);
   finish_try_block (try_block);
@@ -16454,7 +18008,7 @@ cp_parser_function_try_block (cp_parser* parser)
   bool ctor_initializer_p;
 
   /* Look for the `try' keyword.  */
-  if (!cp_parser_require_keyword (parser, RID_TRY, "%<try%>"))
+  if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY))
     return false;
   /* Let the rest of the front end know where we are.  */
   try_block = begin_function_try_block (&compound_stmt);
@@ -16504,12 +18058,12 @@ cp_parser_handler (cp_parser* parser)
   tree handler;
   tree declaration;
 
-  cp_parser_require_keyword (parser, RID_CATCH, "%<catch%>");
+  cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
   handler = begin_handler ();
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   declaration = cp_parser_exception_declaration (parser);
   finish_handler_parms (declaration, handler);
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
   cp_parser_compound_statement (parser, NULL, false);
   finish_handler (handler);
 }
@@ -16543,10 +18097,11 @@ cp_parser_exception_declaration (cp_parser* parser)
   /* Types may not be defined in exception-declarations.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in exception-declarations";
+    = G_("types may not be defined in exception-declarations");
 
   /* Parse the type-specifier-seq.  */
-  cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+  cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+                               /*is_trailing_return=*/false,
                                &type_specifiers);
   /* If it's a `)', then there is no declarator.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
@@ -16579,7 +18134,7 @@ cp_parser_throw_expression (cp_parser* parser)
   tree expression;
   cp_token* token;
 
-  cp_parser_require_keyword (parser, RID_THROW, "%<throw%>");
+  cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
   token = cp_lexer_peek_token (parser->lexer);
   /* Figure out whether or not there is an assignment-expression
      following the "throw" keyword.  */
@@ -16624,13 +18179,13 @@ cp_parser_asm_specification_opt (cp_parser* parser)
   /* Consume the `asm' token.  */
   cp_lexer_consume_token (parser->lexer);
   /* Look for the `('.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
   /* Look for the string-literal.  */
   asm_specification = cp_parser_string_literal (parser, false, false);
 
   /* Look for the `)'.  */
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   return asm_specification;
 }
@@ -16674,7 +18229,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
            name = build_string (IDENTIFIER_LENGTH (name),
                                 IDENTIFIER_POINTER (name));
          /* Look for the closing `]'.  */
-         cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
+         cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
        }
       else
        name = NULL_TREE;
@@ -16682,11 +18237,11 @@ cp_parser_asm_operand_list (cp_parser* parser)
       string_literal = cp_parser_string_literal (parser, false, false);
 
       /* Look for the `('.  */
-      cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+      cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
       /* Parse the expression.  */
       expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
       /* Look for the `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
       if (name == error_mark_node 
          || string_literal == error_mark_node 
@@ -16741,6 +18296,49 @@ cp_parser_asm_clobber_list (cp_parser* parser)
   return clobbers;
 }
 
+/* Parse an asm-label-list.
+
+   asm-label-list:
+     identifier
+     asm-label-list , identifier
+
+   Returns a TREE_LIST, indicating the labels in the order that they
+   appeared.  The TREE_VALUE of each node is a label.  */
+
+static tree
+cp_parser_asm_label_list (cp_parser* parser)
+{
+  tree labels = NULL_TREE;
+
+  while (true)
+    {
+      tree identifier, label, name;
+
+      /* Look for the identifier.  */
+      identifier = cp_parser_identifier (parser);
+      if (!error_operand_p (identifier))
+        {
+         label = lookup_label (identifier);
+         if (TREE_CODE (label) == LABEL_DECL)
+           {
+             TREE_USED (label) = 1;
+             check_goto (label);
+             name = build_string (IDENTIFIER_LENGTH (identifier),
+                                  IDENTIFIER_POINTER (identifier));
+             labels = tree_cons (name, label, labels);
+           }
+       }
+      /* If the next token is not a `,', then the list is
+        complete.  */
+      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+       break;
+      /* Consume the `,' token.  */
+      cp_lexer_consume_token (parser->lexer);
+    }
+
+  return nreverse (labels);
+}
+
 /* Parse an (optional) series of attributes.
 
    attributes:
@@ -16770,8 +18368,8 @@ cp_parser_attributes_opt (cp_parser* parser)
       /* Consume the `__attribute__' keyword.  */
       cp_lexer_consume_token (parser->lexer);
       /* Look for the two `(' tokens.  */
-      cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
-      cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+      cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+      cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
 
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
@@ -16784,8 +18382,8 @@ cp_parser_attributes_opt (cp_parser* parser)
        attribute_list = NULL;
 
       /* Look for the two `)' tokens.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
       /* Add these new attributes to the list.  */
       attributes = chainon (attributes, attribute_list);
@@ -16850,10 +18448,20 @@ cp_parser_attribute_list (cp_parser* parser)
          /* If it's an `(', then parse the attribute arguments.  */
          if (token->type == CPP_OPEN_PAREN)
            {
-             arguments = cp_parser_parenthesized_expression_list
-                         (parser, true, /*cast_p=*/false,
-                           /*allow_expansion_p=*/false,
-                          /*non_constant_p=*/NULL);
+             VEC(tree,gc) *vec;
+             int attr_flag = (attribute_takes_identifier_p (identifier)
+                              ? id_attr : normal_attr);
+             vec = cp_parser_parenthesized_expression_list
+                   (parser, attr_flag, /*cast_p=*/false,
+                    /*allow_expansion_p=*/false,
+                    /*non_constant_p=*/NULL);
+             if (vec == NULL)
+               arguments = error_mark_node;
+             else
+               {
+                 arguments = build_tree_list_vec (vec);
+                 release_tree_vector (vec);
+               }
              /* Save the arguments away.  */
              TREE_VALUE (attribute) = arguments;
            }
@@ -16920,7 +18528,7 @@ static void
 cp_parser_label_declaration (cp_parser* parser)
 {
   /* Look for the `__label__' keyword.  */
-  cp_parser_require_keyword (parser, RID_LABEL, "%<__label__%>");
+  cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL);
 
   while (true)
     {
@@ -16937,11 +18545,11 @@ cp_parser_label_declaration (cp_parser* parser)
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
        break;
       /* Look for the `,' separating the label declarations.  */
-      cp_parser_require (parser, CPP_COMMA, "%<,%>");
+      cp_parser_require (parser, CPP_COMMA, RT_COMMA);
     }
 
   /* Look for the final `;'.  */
-  cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 }
 
 /* Support Functions */
@@ -17080,6 +18688,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
             lookup_member, we must enter the scope here.  */
          if (dependent_p)
            pushed_scope = push_scope (parser->scope);
+
          /* If the PARSER->SCOPE is a template specialization, it
             may be instantiated during name lookup.  In that case,
             errors may be issued.  Even if we rollback the current
@@ -17088,6 +18697,27 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
                                        tag_type != none_type,
                                        /*complain=*/true);
 
+         /* 3.4.3.1: In a lookup in which the constructor is an acceptable
+            lookup result and the nested-name-specifier nominates a class C:
+              * if the name specified after the nested-name-specifier, when
+              looked up in C, is the injected-class-name of C (Clause 9), or
+              * if the name specified after the nested-name-specifier is the
+              same as the identifier or the simple-template-id's template-
+              name in the last component of the nested-name-specifier,
+            the name is instead considered to name the constructor of
+            class C. [ Note: for example, the constructor is not an
+            acceptable lookup result in an elaborated-type-specifier so
+            the constructor would not be used in place of the
+            injected-class-name. --end note ] Such a constructor name
+            shall be used only in the declarator-id of a declaration that
+            names a constructor or in a using-declaration.  */
+         if (tag_type == none_type
+             && DECL_SELF_REFERENCE_P (decl)
+             && same_type_p (DECL_CONTEXT (decl), parser->scope))
+           decl = lookup_qualified_name (parser->scope, ctor_identifier,
+                                         tag_type != none_type,
+                                         /*complain=*/true);
+
          /* If we have a single function from a using decl, pull it out.  */
          if (TREE_CODE (decl) == OVERLOAD
              && !really_overloaded_fn (decl))
@@ -17164,6 +18794,10 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
   if (!decl || decl == error_mark_node)
     return error_mark_node;
 
+  /* Pull out the template from an injected-class-name (or multiple).  */
+  if (is_template)
+    decl = maybe_get_template_decl_from_type_decl (decl);
+
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   if (TREE_CODE (decl) == TREE_LIST)
     {
@@ -17173,8 +18807,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
         cp_parser_error, so we incorporate its actions directly.  */
       if (!cp_parser_simulate_error (parser))
        {
-         error ("%Hreference to %qD is ambiguous",
-                &name_location, name);
+         error_at (name_location, "reference to %qD is ambiguous",
+                   name);
          print_candidates (decl);
        }
       return error_mark_node;
@@ -17279,10 +18913,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
       if (declarator->u.id.qualifying_scope)
        {
          tree scope;
-         tree member;
 
          scope = declarator->u.id.qualifying_scope;
-         member = declarator->u.id.unqualified_name;
 
          while (scope && CLASS_TYPE_P (scope))
            {
@@ -17361,11 +18993,15 @@ cp_parser_check_template_parameters (cp_parser* parser,
        template <class T> void S<T>::R<T>::f ();  */
   if (parser->num_template_parameter_lists < num_templates)
     {
-      if (declarator)
+      if (declarator && !current_function_decl)
        error_at (location, "specializing member %<%T::%E%> "
                  "requires %<template<>%> syntax", 
                  declarator->u.id.qualifying_scope,
                  declarator->u.id.unqualified_name);
+      else if (declarator)
+       error_at (location, "invalid declaration of %<%T::%E%>",
+                 declarator->u.id.qualifying_scope,
+                 declarator->u.id.unqualified_name);
       else 
        error_at (location, "too few template-parameter-lists");
       return false;
@@ -17374,7 +19010,7 @@ cp_parser_check_template_parameters (cp_parser* parser,
      something like:
 
      template <class T> template <class U> void S::f();  */
-  error ("%Htoo many template-parameter-lists", &location);
+  error_at (location, "too many template-parameter-lists");
   return false;
 }
 
@@ -17423,8 +19059,7 @@ static bool
 cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
 {
   bool constructor_p;
-  tree type_decl = NULL_TREE;
-  bool nested_name_p;
+  tree nested_name_specifier;
   cp_token *next_token;
 
   /* The common case is that this is not a constructor declarator, so
@@ -17450,34 +19085,48 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
   cp_parser_global_scope_opt (parser,
                              /*current_scope_valid_p=*/false);
   /* Look for the nested-name-specifier.  */
-  nested_name_p
+  nested_name_specifier
     = (cp_parser_nested_name_specifier_opt (parser,
                                            /*typename_keyword_p=*/false,
                                            /*check_dependency_p=*/false,
                                            /*type_p=*/false,
-                                           /*is_declaration=*/false)
-       != NULL_TREE);
+                                           /*is_declaration=*/false));
   /* Outside of a class-specifier, there must be a
      nested-name-specifier.  */
-  if (!nested_name_p &&
+  if (!nested_name_specifier &&
       (!at_class_scope_p () || !TYPE_BEING_DEFINED (current_class_type)
        || friend_p))
     constructor_p = false;
+  else if (nested_name_specifier == error_mark_node)
+    constructor_p = false;
+
+  /* If we have a class scope, this is easy; DR 147 says that S::S always
+     names the constructor, and no other qualified name could.  */
+  if (constructor_p && nested_name_specifier
+      && TYPE_P (nested_name_specifier))
+    {
+      tree id = cp_parser_unqualified_id (parser,
+                                         /*template_keyword_p=*/false,
+                                         /*check_dependency_p=*/false,
+                                         /*declarator_p=*/true,
+                                         /*optional_p=*/false);
+      if (is_overloaded_fn (id))
+       id = DECL_NAME (get_first_fn (id));
+      if (!constructor_name_p (id, nested_name_specifier))
+       constructor_p = false;
+    }
   /* If we still think that this might be a constructor-declarator,
      look for a class-name.  */
-  if (constructor_p)
+  else if (constructor_p)
     {
       /* If we have:
 
-          template <typename T> struct S { S(); };
-          template <typename T> S<T>::S ();
+          template <typename T> struct S {
+            S();
+          };
 
-        we must recognize that the nested `S' names a class.
-        Similarly, for:
-
-          template <typename T> S<T>::S<T> ();
-
-        we must recognize that the nested `S' names a template.  */
+        we must recognize that the nested `S' names a class.  */
+      tree type_decl;
       type_decl = cp_parser_class_name (parser,
                                        /*typename_keyword_p=*/false,
                                        /*template_keyword_p=*/false,
@@ -17487,22 +19136,23 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
                                        /*is_declaration=*/false);
       /* If there was no class-name, then this is not a constructor.  */
       constructor_p = !cp_parser_error_occurred (parser);
-    }
 
-  /* If we're still considering a constructor, we have to see a `(',
-     to begin the parameter-declaration-clause, followed by either a
-     `)', an `...', or a decl-specifier.  We need to check for a
-     type-specifier to avoid being fooled into thinking that:
+      /* If we're still considering a constructor, we have to see a `(',
+        to begin the parameter-declaration-clause, followed by either a
+        `)', an `...', or a decl-specifier.  We need to check for a
+        type-specifier to avoid being fooled into thinking that:
 
-       S::S (f) (int);
+          S (f) (int);
 
-     is a constructor.  (It is actually a function named `f' that
-     takes one parameter (of type `int') and returns a value of type
-     `S::S'.  */
-  if (constructor_p
-      && cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
-    {
-      if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
+        is a constructor.  (It is actually a function named `f' that
+        takes one parameter (of type `int') and returns a value of type
+        `S'.  */
+      if (constructor_p
+         && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+       constructor_p = false;
+
+      if (constructor_p
+         && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
          && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
          /* A parameter declaration begins with a decl-specifier,
             which is either the "attribute" keyword, a storage class
@@ -17557,8 +19207,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
          constructor_p = !cp_parser_error_occurred (parser);
        }
     }
-  else
-    constructor_p = false;
+
   /* We did not really want to consume any tokens.  */
   cp_parser_abort_tentative_parse (parser);
 
@@ -17619,7 +19268,7 @@ cp_parser_function_definition_from_specifiers_and_declarator
 
 /* Parse the part of a function-definition that follows the
    declarator.  INLINE_P is TRUE iff this function is an inline
-   function defined with a class-specifier.
+   function defined within a class-specifier.
 
    Returns the function defined.  */
 
@@ -17648,8 +19297,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
         returned.  */
       cp_parser_identifier (parser);
       /* Issue an error message.  */
-      error ("%Hnamed return values are no longer supported",
-            &token->location);
+      error_at (token->location,
+               "named return values are no longer supported");
       /* Skip tokens until we reach the start of the function body.  */
       while (true)
        {
@@ -17671,6 +19320,9 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
   saved_num_template_parameter_lists
     = parser->num_template_parameter_lists;
   parser->num_template_parameter_lists = 0;
+
+  start_lambda_scope (current_function_decl);
+
   /* If the next token is `try', then we are looking at a
      function-try-block.  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
@@ -17681,6 +19333,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
     ctor_initializer_p
       = cp_parser_ctor_initializer_opt_and_function_body (parser);
 
+  finish_lambda_scope ();
+
   /* Finish the function.  */
   fn = finish_function ((ctor_initializer_p ? 1 : 0) |
                        (inline_p ? 2 : 0));
@@ -17712,19 +19366,19 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
 
   /* Look for the `template' keyword.  */
   token = cp_lexer_peek_token (parser->lexer);
-  if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"))
+  if (!cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE))
     return;
 
   /* And the `<'.  */
-  if (!cp_parser_require (parser, CPP_LESS, "%<<%>"))
+  if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
     return;
   if (at_class_scope_p () && current_function_decl)
     {
       /* 14.5.2.2 [temp.mem]
 
          A local class shall not have member templates.  */
-      error ("%Hinvalid declaration of member template in local class",
-            &token->location);
+      error_at (token->location,
+               "invalid declaration of member template in local class");
       cp_parser_skip_to_end_of_block_or_statement (parser);
       return;
     }
@@ -17733,7 +19387,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
      A template ... shall not have C linkage.  */
   if (current_lang_name == lang_name_c)
     {
-      error ("%Htemplate with C linkage", &token->location);
+      error_at (token->location, "template with C linkage");
       /* Give it C++ linkage to avoid confusing other parts of the
         front end.  */
       push_lang_context (lang_name_cplusplus);
@@ -17822,9 +19476,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   if (member_p && decl
       && (TREE_CODE (decl) == FUNCTION_DECL
          || DECL_FUNCTION_TEMPLATE_P (decl)))
-    TREE_VALUE (parser->unparsed_functions_queues)
-      = tree_cons (NULL_TREE, decl,
-                  TREE_VALUE (parser->unparsed_functions_queues));
+    VEC_safe_push (tree, gc, unparsed_funs_with_definitions, decl);
 }
 
 /* Perform the deferred access checks from a template-parameter-list.
@@ -17880,8 +19532,8 @@ cp_parser_single_declaration (cp_parser* parser,
   /* There are no template typedefs.  */
   if (decl_specifiers.specs[(int) ds_typedef])
     {
-      error ("%Htemplate declaration of %qs",
-            &decl_spec_token_start->location, "typedef");
+      error_at (decl_spec_token_start->location,
+               "template declaration of %<typedef%>");
       decl = error_mark_node;
     }
 
@@ -17919,6 +19571,11 @@ cp_parser_single_declaration (cp_parser* parser,
          cp_parser_perform_template_parameter_access_checks (checks);
        }
     }
+
+  /* Complain about missing 'typename' or other invalid type names.  */
+  if (!decl_specifiers.any_type_specifiers_p)
+    cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
   /* If it's not a template class, try for a template function.  If
      the next token is a `;', then this declaration does not declare
      anything.  But, if there were errors in the decl-specifiers, then
@@ -17944,8 +19601,8 @@ cp_parser_single_declaration (cp_parser* parser,
         && explicit_specialization_p
         && decl_specifiers.storage_class != sc_none)
       {
-        error ("%Hexplicit template specialization cannot have a storage class",
-              &decl_spec_token_start->location);
+        error_at (decl_spec_token_start->location,
+                 "explicit template specialization cannot have a storage class");
         decl = error_mark_node;
       }
     }
@@ -17960,7 +19617,7 @@ cp_parser_single_declaration (cp_parser* parser,
   /* Look for a trailing `;' after the declaration.  */
   if (!function_definition_p
       && (decl == error_mark_node
-         || !cp_parser_require (parser, CPP_SEMICOLON, "%<;%>")))
+         || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
     cp_parser_skip_to_end_of_block_or_statement (parser);
 
   return decl;
@@ -17981,13 +19638,14 @@ cp_parser_simple_cast_expression (cp_parser *parser)
 static tree
 cp_parser_functional_cast (cp_parser* parser, tree type)
 {
+  VEC(tree,gc) *vec;
   tree expression_list;
   tree cast;
   bool nonconst_p;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &nonconst_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       if (TREE_CODE (type) == TYPE_DECL)
@@ -17995,11 +19653,18 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
       return finish_compound_literal (type, expression_list);
     }
 
-  expression_list
-    = cp_parser_parenthesized_expression_list (parser, false,
-                                              /*cast_p=*/true,
-                                              /*allow_expansion_p=*/true,
-                                              /*non_constant_p=*/NULL);
+
+  vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+                                                /*cast_p=*/true,
+                                                /*allow_expansion_p=*/true,
+                                                /*non_constant_p=*/NULL);
+  if (vec == NULL)
+    expression_list = error_mark_node;
+  else
+    {
+      expression_list = build_tree_list_vec (vec);
+      release_tree_vector (vec);
+    }
 
   cast = build_functional_cast (type, expression_list,
                                 tf_warning_or_error);
@@ -18009,8 +19674,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
     type = TREE_TYPE (type);
   if (cast != error_mark_node
       && !cast_valid_in_integral_constant_expression_p (type)
-      && (cp_parser_non_integral_constant_expression
-         (parser, "a call to a constructor")))
+      && cp_parser_non_integral_constant_expression (parser,
+                                                    NIC_CONSTRUCTOR))
     return error_mark_node;
   return cast;
 }
@@ -18031,8 +19696,8 @@ cp_parser_save_member_function_body (cp_parser* parser,
   cp_token *last;
   tree fn;
 
-  /* Create the function-declaration.  */
-  fn = start_method (decl_specifiers, declarator, attributes);
+  /* Create the FUNCTION_DECL.  */
+  fn = grokmethod (decl_specifiers, declarator, attributes);
   /* If something went badly wrong, bail out now.  */
   if (fn == error_mark_node)
     {
@@ -18080,13 +19745,8 @@ cp_parser_save_member_function_body (cp_parser* parser,
      friend templates are handled correctly.  */
   DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
 
-  /* We're done with the inline definition.  */
-  finish_method (fn);
-
   /* Add FN to the queue of functions to be parsed later.  */
-  TREE_VALUE (parser->unparsed_functions_queues)
-    = tree_cons (NULL_TREE, fn,
-                TREE_VALUE (parser->unparsed_functions_queues));
+  VEC_safe_push (tree, gc, unparsed_funs_with_definitions, fn);
 
   return fn;
 }
@@ -18103,7 +19763,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   tree saved_qualifying_scope;
   tree saved_object_scope;
   bool saved_greater_than_is_operator_p;
-  bool saved_skip_evaluation;
+  int saved_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings;
 
   /* [temp.names]
 
@@ -18120,8 +19781,10 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   saved_object_scope = parser->object_scope;
   /* We need to evaluate the template arguments, even though this
      template-id may be nested within a "sizeof".  */
-  saved_skip_evaluation = skip_evaluation;
-  skip_evaluation = false;
+  saved_unevaluated_operand = cp_unevaluated_operand;
+  cp_unevaluated_operand = 0;
+  saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  c_inhibit_evaluation_warnings = 0;
   /* Parse the template-argument-list itself.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
       || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
@@ -18162,9 +19825,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
            global source location is still on the token before the
            '>>', so we need to say explicitly where we want it.  */
          cp_token *token = cp_lexer_peek_token (parser->lexer);
-         error ("%H%<>>%> should be %<> >%> "
-                "within a nested template argument list",
-                &token->location);
+         error_at (token->location, "%<>>%> should be %<> >%> "
+                   "within a nested template argument list");
 
          token->type = CPP_GREATER;
        }
@@ -18175,8 +19837,9 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
            Same deal about the token location, but here we can get it
            right by consuming the '>>' before issuing the diagnostic.  */
          cp_token *token = cp_lexer_consume_token (parser->lexer);
-         error ("%Hspurious %<>>%>, use %<>%> to terminate "
-                "a template argument list", &token->location);
+         error_at (token->location,
+                   "spurious %<>>%>, use %<>%> to terminate "
+                   "a template argument list");
        }
     }
   else
@@ -18188,7 +19851,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   parser->scope = saved_scope;
   parser->qualifying_scope = saved_qualifying_scope;
   parser->object_scope = saved_object_scope;
-  skip_evaluation = saved_skip_evaluation;
+  cp_unevaluated_operand = saved_unevaluated_operand;
+  c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
   return arguments;
 }
@@ -18213,8 +19877,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
      classes.  We want to handle them right away, but we don't want
      them getting mixed up with functions that are currently in the
      queue.  */
-  parser->unparsed_functions_queues
-    = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues);
+  push_unparsed_function_queues (parser);
 
   /* Make sure that any template parameters are in scope.  */
   maybe_begin_member_template_processing (member_function);
@@ -18266,8 +19929,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
   maybe_end_member_template_processing ();
 
   /* Restore the queue.  */
-  parser->unparsed_functions_queues
-    = TREE_CHAIN (parser->unparsed_functions_queues);
+  pop_unparsed_function_queues (parser);
 }
 
 /* If DECL contains any default args, remember it on the unparsed
@@ -18283,9 +19945,11 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
        probe = TREE_CHAIN (probe))
     if (TREE_PURPOSE (probe))
       {
-       TREE_PURPOSE (parser->unparsed_functions_queues)
-         = tree_cons (current_class_type, decl,
-                      TREE_PURPOSE (parser->unparsed_functions_queues));
+       cp_default_arg_entry *entry
+         = VEC_safe_push (cp_default_arg_entry, gc,
+                          unparsed_funs_with_default_args, NULL);
+       entry->class_type = current_class_type;
+       entry->decl = decl;
        break;
       }
 }
@@ -18299,23 +19963,24 @@ static void
 cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
 {
   bool saved_local_variables_forbidden_p;
-  tree parm;
+  tree parm, parmdecl;
 
   /* While we're parsing the default args, we might (due to the
      statement expression extension) encounter more classes.  We want
      to handle them right away, but we don't want them getting mixed
      up with default args that are currently in the queue.  */
-  parser->unparsed_functions_queues
-    = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues);
+  push_unparsed_function_queues (parser);
 
   /* Local variable names (and the `this' keyword) may not appear
      in a default argument.  */
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
   parser->local_variables_forbidden_p = true;
 
-  for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
-       parm;
-       parm = TREE_CHAIN (parm))
+  for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
+        parmdecl = DECL_ARGUMENTS (fn);
+       parm && parm != void_list_node;
+       parm = TREE_CHAIN (parm),
+        parmdecl = DECL_CHAIN (parmdecl))
     {
       cp_token_cache *tokens;
       tree default_arg = TREE_PURPOSE (parm);
@@ -18337,6 +20002,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       tokens = DEFARG_TOKENS (default_arg);
       cp_parser_push_lexer_for_tokens (parser, tokens);
 
+      start_lambda_scope (parmdecl);
+
       /* Parse the assignment-expression.  */
       parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
       if (parsed_arg == error_mark_node)
@@ -18355,6 +20022,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
           VEC_iterate (tree, insts, ix, copy); ix++)
        TREE_PURPOSE (copy) = parsed_arg;
 
+      finish_lambda_scope ();
+
       /* If the token stream has not been completely used up, then
         there was extra junk after the end of the default
         argument.  */
@@ -18372,8 +20041,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
   parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
 
   /* Restore the queue.  */
-  parser->unparsed_functions_queues
-    = TREE_CHAIN (parser->unparsed_functions_queues);
+  pop_unparsed_function_queues (parser);
 }
 
 /* Parse the operand of `sizeof' (or a similar operator).  Returns
@@ -18422,7 +20090,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
     }
 
   /* Do not actually evaluate the expression.  */
-  ++skip_evaluation;
+  ++cp_unevaluated_operand;
+  ++c_inhibit_evaluation_warnings;
   /* If it's a `(', then we might be looking at the type-id
      construction.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -18441,7 +20110,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
       type = cp_parser_type_id (parser);
       parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
       /* Now, look for the trailing `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       /* If all went well, then we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
@@ -18471,7 +20140,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
     expr = make_pack_expansion (expr);
 
   /* Go back to evaluating expressions.  */
-  --skip_evaluation;
+  --cp_unevaluated_operand;
+  --c_inhibit_evaluation_warnings;
 
   /* Free the message we created.  */
   free (tmp);
@@ -18509,8 +20179,8 @@ cp_parser_set_storage_class (cp_parser *parser,
 
   if (parser->in_unbraced_linkage_specification_p)
     {
-      error ("%Hinvalid use of %qD in linkage specification",
-            &location, ridpointers[keyword]);
+      error_at (location, "invalid use of %qD in linkage specification",
+               ridpointers[keyword]);
       return;
     }
   else if (decl_specs->storage_class != sc_none)
@@ -18522,7 +20192,7 @@ cp_parser_set_storage_class (cp_parser *parser,
   if ((keyword == RID_EXTERN || keyword == RID_STATIC)
       && decl_specs->specs[(int) ds_thread])
     {
-      error ("%H%<__thread%> before %qD", &location, ridpointers[keyword]);
+      error_at (location, "%<__thread%> before %qD", ridpointers[keyword]);
       decl_specs->specs[(int) ds_thread] = 0;
     }
 
@@ -18613,6 +20283,171 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
   return decl_specifiers->specs[(int) ds_friend] != 0;
 }
 
+/* Issue an error message indicating that TOKEN_DESC was expected.
+   If KEYWORD is true, it indicated this function is called by
+   cp_parser_require_keword and the required token can only be
+   a indicated keyword. */
+
+static void
+cp_parser_required_error (cp_parser *parser,
+                         required_token token_desc,
+                         bool keyword)
+{
+  switch (token_desc)
+    {
+      case RT_NEW:
+       cp_parser_error (parser, "expected %<new%>");
+       return;
+      case RT_DELETE:
+       cp_parser_error (parser, "expected %<delete%>");
+       return;
+      case RT_RETURN:
+       cp_parser_error (parser, "expected %<return%>");
+       return;
+      case RT_WHILE:
+       cp_parser_error (parser, "expected %<while%>");
+       return;
+      case RT_EXTERN:
+       cp_parser_error (parser, "expected %<extern%>");
+       return;
+      case RT_STATIC_ASSERT:
+       cp_parser_error (parser, "expected %<static_assert%>");
+       return;
+      case RT_DECLTYPE:
+       cp_parser_error (parser, "expected %<decltype%>");
+       return;
+      case RT_OPERATOR:
+       cp_parser_error (parser, "expected %<operator%>");
+       return;
+      case RT_CLASS:
+       cp_parser_error (parser, "expected %<class%>");
+       return;
+      case RT_TEMPLATE:
+       cp_parser_error (parser, "expected %<template%>");
+       return;
+      case RT_NAMESPACE:
+       cp_parser_error (parser, "expected %<namespace%>");
+       return;
+      case RT_USING:
+       cp_parser_error (parser, "expected %<using%>");
+       return;
+      case RT_ASM:
+       cp_parser_error (parser, "expected %<asm%>");
+       return;
+      case RT_TRY:
+       cp_parser_error (parser, "expected %<try%>");
+       return;
+      case RT_CATCH:
+       cp_parser_error (parser, "expected %<catch%>");
+       return;
+      case RT_THROW:
+       cp_parser_error (parser, "expected %<throw%>");
+       return;
+      case RT_LABEL:
+       cp_parser_error (parser, "expected %<__label__%>");
+       return;
+      case RT_AT_TRY:
+       cp_parser_error (parser, "expected %<@try%>");
+       return;
+      case RT_AT_SYNCHRONIZED:
+       cp_parser_error (parser, "expected %<@synchronized%>");
+       return;
+      case RT_AT_THROW:
+       cp_parser_error (parser, "expected %<@throw%>");
+       return;
+      default:
+       break;
+    }
+  if (!keyword)
+    {
+      switch (token_desc)
+        {
+         case RT_SEMICOLON:
+           cp_parser_error (parser, "expected %<;%>");
+           return;
+         case RT_OPEN_PAREN:
+           cp_parser_error (parser, "expected %<(%>");
+           return;
+         case RT_CLOSE_BRACE:
+           cp_parser_error (parser, "expected %<}%>");
+           return;
+         case RT_OPEN_BRACE:
+           cp_parser_error (parser, "expected %<{%>");
+           return;
+         case RT_CLOSE_SQUARE:
+           cp_parser_error (parser, "expected %<]%>");
+           return;
+         case RT_OPEN_SQUARE:
+           cp_parser_error (parser, "expected %<[%>");
+           return;
+         case RT_COMMA:
+           cp_parser_error (parser, "expected %<,%>");
+           return;
+         case RT_SCOPE:
+           cp_parser_error (parser, "expected %<::%>");
+           return;
+         case RT_LESS:
+           cp_parser_error (parser, "expected %<<%>");
+           return;
+         case RT_GREATER:
+           cp_parser_error (parser, "expected %<>%>");
+           return;
+         case RT_EQ:
+           cp_parser_error (parser, "expected %<=%>");
+           return;
+         case RT_ELLIPSIS:
+           cp_parser_error (parser, "expected %<...%>");
+           return;
+         case RT_MULT:
+           cp_parser_error (parser, "expected %<*%>");
+           return;
+         case RT_COMPL:
+           cp_parser_error (parser, "expected %<~%>");
+           return;
+         case RT_COLON:
+           cp_parser_error (parser, "expected %<:%>");
+           return;
+         case RT_COLON_SCOPE:
+           cp_parser_error (parser, "expected %<:%> or %<::%>");
+           return;
+         case RT_CLOSE_PAREN:
+           cp_parser_error (parser, "expected %<)%>");
+           return;
+         case RT_COMMA_CLOSE_PAREN:
+           cp_parser_error (parser, "expected %<,%> or %<)%>");
+           return;
+         case RT_PRAGMA_EOL:
+           cp_parser_error (parser, "expected end of line");
+           return;
+         case RT_NAME:
+           cp_parser_error (parser, "expected identifier");
+           return;
+         case RT_SELECT:
+           cp_parser_error (parser, "expected selection-statement");
+           return;
+         case RT_INTERATION:
+           cp_parser_error (parser, "expected iteration-statement");
+           return;
+         case RT_JUMP:
+           cp_parser_error (parser, "expected jump-statement");
+           return;
+         case RT_CLASS_KEY:
+           cp_parser_error (parser, "expected class-key");
+           return;
+         case RT_CLASS_TYPENAME_TEMPLATE:
+           cp_parser_error (parser,
+                "expected %<class%>, %<typename%>, or %<template%>");
+           return;
+         default:
+           gcc_unreachable ();
+       }
+    }
+  else
+    gcc_unreachable ();
+}
+
+
+
 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
    issue an error message indicating that TOKEN_DESC was expected.
 
@@ -18622,7 +20457,7 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
 static cp_token *
 cp_parser_require (cp_parser* parser,
                   enum cpp_ttype type,
-                  const char* token_desc)
+                  required_token token_desc)
 {
   if (cp_lexer_next_token_is (parser->lexer, type))
     return cp_lexer_consume_token (parser->lexer);
@@ -18630,11 +20465,7 @@ cp_parser_require (cp_parser* parser,
     {
       /* Output the MESSAGE -- unless we're parsing tentatively.  */
       if (!cp_parser_simulate_error (parser))
-       {
-         char *message = concat ("expected ", token_desc, NULL);
-         cp_parser_error (parser, message);
-         free (message);
-       }
+       cp_parser_required_error (parser, token_desc, /*keyword=*/false);
       return NULL;
     }
 }
@@ -18652,7 +20483,7 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
   unsigned nesting_depth = 0;
 
   /* Are we ready, yet?  If not, issue error message.  */
-  if (cp_parser_require (parser, CPP_GREATER, "%<>%>"))
+  if (cp_parser_require (parser, CPP_GREATER, RT_GREATER))
     return;
 
   /* Skip tokens until the desired token is found.  */
@@ -18729,20 +20560,13 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
 static cp_token *
 cp_parser_require_keyword (cp_parser* parser,
                           enum rid keyword,
-                          const char* token_desc)
+                          required_token token_desc)
 {
   cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc);
 
   if (token && token->keyword != keyword)
     {
-      dyn_string_t error_msg;
-
-      /* Format the error message.  */
-      error_msg = dyn_string_new (0);
-      dyn_string_append_cstr (error_msg, "expected ");
-      dyn_string_append_cstr (error_msg, token_desc);
-      cp_parser_error (parser, error_msg->s);
-      dyn_string_delete (error_msg);
+      cp_parser_required_error (parser, token_desc, /*keyword=*/true); 
       return NULL;
     }
 
@@ -18864,7 +20688,7 @@ cp_parser_check_access_in_redeclaration (tree decl, location_t location)
        != (current_access_specifier == access_private_node))
       || (TREE_PROTECTED (decl)
          != (current_access_specifier == access_protected_node)))
-    error ("%H%qD redeclared with different access", &location, decl);
+    error_at (location, "%qD redeclared with different access", decl);
 }
 
 /* Look for the `template' keyword, as a syntactic disambiguator.
@@ -18882,8 +20706,9 @@ cp_parser_optional_template_keyword (cp_parser *parser)
       if (!processing_template_decl)
        {
          cp_token *token = cp_lexer_peek_token (parser->lexer);
-         error ("%H%<template%> (as a disambiguator) is only allowed "
-                "within templates", &token->location);
+         error_at (token->location,
+                   "%<template%> (as a disambiguator) is only allowed "
+                   "within templates");
          /* If this part of the token stream is rescanned, the same
             error message would be generated.  So, we purge the token
             from the stream.  */
@@ -18918,14 +20743,10 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
   checks = check_value->checks;
   if (checks)
     {
-      for (i = 0 ;
-          VEC_iterate (deferred_access_check, checks, i, chk) ;
-          ++i)
-       {
-         perform_or_defer_access_check (chk->binfo,
-                                        chk->decl,
-                                        chk->diag_decl);
-       }
+      FOR_EACH_VEC_ELT (deferred_access_check, checks, i, chk)
+       perform_or_defer_access_check (chk->binfo,
+                                      chk->decl,
+                                      chk->diag_decl);
     }
   /* Set the scope from the stored value.  */
   parser->scope = check_value->value;
@@ -19148,8 +20969,9 @@ cp_parser_objc_expression (cp_parser* parser)
          break;
        }
     default:
-      error ("%Hmisplaced %<@%D%> Objective-C++ construct",
-            &kwd->location, kwd->u.value);
+      error_at (kwd->location,
+               "misplaced %<@%D%> Objective-C++ construct",
+               kwd->u.value);
       cp_parser_skip_to_end_of_block_or_statement (parser);
     }
 
@@ -19171,7 +20993,7 @@ cp_parser_objc_message_expression (cp_parser* parser)
   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, "%<]%>");
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
   return objc_build_message_expr (build_tree_list (receiver, messageargs));
 }
@@ -19243,7 +21065,7 @@ cp_parser_objc_message_args (cp_parser* parser)
        return build_tree_list (selector, NULL_TREE);
 
       maybe_unary_selector_p = false;
-      cp_parser_require (parser, CPP_COLON, "%<:%>");
+      cp_parser_require (parser, CPP_COLON, RT_COLON);
       arg = cp_parser_assignment_expression (parser, false, NULL);
 
       sel_args
@@ -19285,15 +21107,15 @@ cp_parser_objc_encode_expression (cp_parser* parser)
   cp_token *token;
 
   cp_lexer_consume_token (parser->lexer);  /* Eat '@encode'.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   token = cp_lexer_peek_token (parser->lexer);
   type = complete_type (cp_parser_type_id (parser));
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   if (!type)
     {
-      error ("%H%<@encode%> must specify a type as an argument",
-            &token->location);
+      error_at (token->location, 
+               "%<@encode%> must specify a type as an argument");
       return error_mark_node;
     }
 
@@ -19308,9 +21130,9 @@ 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, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   name = cp_parser_identifier (parser);
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   return objc_get_class_ivars (name);
 }
@@ -19328,9 +21150,9 @@ 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, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   proto = cp_parser_identifier (parser);
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   return objc_build_protocol_expr (proto);
 }
@@ -19356,9 +21178,10 @@ cp_parser_objc_selector_expression (cp_parser* parser)
   tree sel_seq = NULL_TREE;
   bool maybe_unary_selector_p = true;
   cp_token *token;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   cp_lexer_consume_token (parser->lexer);  /* Eat '@selector'.  */
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   token = cp_lexer_peek_token (parser->lexer);
 
   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
@@ -19405,9 +21228,9 @@ cp_parser_objc_selector_expression (cp_parser* parser)
     }
 
  finish_selector:
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
-  return objc_build_selector_expr (sel_seq);
+  return objc_build_selector_expr (loc, sel_seq);
 }
 
 /* Parse a list of identifiers.
@@ -19491,7 +21314,7 @@ cp_parser_objc_protocol_refs_opt (cp_parser* parser)
     {
       cp_lexer_consume_token (parser->lexer);  /* Eat '<'.  */
       protorefs = cp_parser_objc_identifier_list (parser);
-      cp_parser_require (parser, CPP_GREATER, "%<>%>");
+      cp_parser_require (parser, CPP_GREATER, RT_GREATER);
     }
 
   return protorefs;
@@ -19580,7 +21403,7 @@ cp_parser_objc_typename (cp_parser* parser)
       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, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       type_name = build_tree_list (proto_quals, cp_type);
     }
 
@@ -19608,7 +21431,7 @@ cp_parser_objc_selector (cp_parser* parser)
 
   if (!cp_parser_objc_selector_p (token->type))
     {
-      error ("%Hinvalid Objective-C++ selector name", &token->location);
+      error_at (token->location, "invalid Objective-C++ selector name");
       return error_mark_node;
     }
 
@@ -19633,7 +21456,7 @@ cp_parser_objc_selector (cp_parser* parser)
 /* Parse an Objective-C params list.  */
 
 static tree
-cp_parser_objc_method_keyword_params (cp_parser* parser)
+cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
 {
   tree params = NULL_TREE;
   bool maybe_unary_selector_p = true;
@@ -19642,6 +21465,10 @@ cp_parser_objc_method_keyword_params (cp_parser* parser)
   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
     {
       tree selector = NULL_TREE, type_name, identifier;
+      tree parm_attr = NULL_TREE;
+
+      if (token->keyword == RID_ATTRIBUTE)
+       break;
 
       if (token->type != CPP_COLON)
        selector = cp_parser_objc_selector (parser);
@@ -19649,29 +21476,55 @@ cp_parser_objc_method_keyword_params (cp_parser* 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;
+       {
+         params = selector; /* Might be followed by attributes.  */
+         break;
+       }
 
       maybe_unary_selector_p = false;
-      cp_parser_require (parser, CPP_COLON, "%<:%>");
+      cp_parser_require (parser, CPP_COLON, RT_COLON);
       type_name = cp_parser_objc_typename (parser);
+      /* New ObjC allows attributes on parameters too.  */
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+       parm_attr = cp_parser_attributes_opt (parser);
       identifier = cp_parser_identifier (parser);
 
       params
        = chainon (params,
                   objc_build_keyword_decl (selector,
                                            type_name,
-                                           identifier));
+                                           identifier,
+                                           parm_attr));
 
       token = cp_lexer_peek_token (parser->lexer);
     }
 
+  if (params == NULL_TREE)
+    {
+      cp_parser_error (parser, "objective-c++ method declaration is expected");
+      return error_mark_node;
+    }
+
+  /* We allow tail attributes for the method.  */
+  if (token->keyword == RID_ATTRIBUTE)
+    {
+      *attributes = cp_parser_attributes_opt (parser);
+      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+         || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+       return params;
+      cp_parser_error (parser, 
+                      "method attributes must be specified at the end");
+      return error_mark_node;
+    }
+
   return params;
 }
 
 /* Parse the non-keyword Objective-C params.  */
 
 static tree
-cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
+cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp, 
+                                      tree* attributes)
 {
   tree params = make_node (TREE_LIST);
   cp_token *token = cp_lexer_peek_token (parser->lexer);
@@ -19692,6 +21545,7 @@ cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
          break;
        }
 
+      /* TODO: parse attributes for tail parameters.  */
       parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
       parm = grokdeclarator (parmdecl->declarator,
                             &parmdecl->decl_specifiers,
@@ -19702,6 +21556,26 @@ cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
       token = cp_lexer_peek_token (parser->lexer);
     }
 
+  /* We allow tail attributes for the method.  */
+  if (token->keyword == RID_ATTRIBUTE)
+    {
+      if (*attributes == NULL_TREE)
+       {
+         *attributes = cp_parser_attributes_opt (parser);
+         if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+             || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+           return params;
+       }
+      else        
+       /* We have an error, but parse the attributes, so that we can 
+          carry on.  */
+       *attributes = cp_parser_attributes_opt (parser);
+
+      cp_parser_error (parser, 
+                      "method attributes must be specified at the end");
+      return error_mark_node;
+    }
+
   return params;
 }
 
@@ -19731,34 +21605,70 @@ cp_parser_objc_interstitial_code (cp_parser* parser)
 /* Parse a method signature.  */
 
 static tree
-cp_parser_objc_method_signature (cp_parser* parser)
+cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
 {
   tree rettype, kwdparms, optparms;
   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, &ellipsis);
+  *attributes = NULL_TREE;
+  kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
+  if (kwdparms == error_mark_node)
+    return error_mark_node;
+  optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes);
+  if (optparms == error_mark_node)
+    return error_mark_node;
 
   return objc_build_method_signature (rettype, kwdparms, optparms, ellipsis);
 }
 
-/* Pars an Objective-C method prototype list.  */
+static bool
+cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
+{
+  tree tattr;  
+  cp_lexer_save_tokens (parser->lexer);
+  tattr = cp_parser_attributes_opt (parser);
+  gcc_assert (tattr) ;
+  
+  /* If the attributes are followed by a method introducer, this is not allowed.
+     Dump the attributes and flag the situation.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
+      || cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
+    return true;
+
+  /* Otherwise, the attributes introduce some interstitial code, possibly so
+     rewind to allow that check.  */
+  cp_lexer_rollback_tokens (parser->lexer);
+  return false;  
+}
+
+/* Parse an Objective-C method prototype list.  */
 
 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)
+  while (token->keyword != RID_AT_END && token->type != CPP_EOF)
     {
       if (token->type == CPP_PLUS || token->type == CPP_MINUS)
        {
-         objc_add_method_declaration
-          (cp_parser_objc_method_signature (parser));
+         tree attributes, sig;
+         sig = cp_parser_objc_method_signature (parser, &attributes);
+         if (sig == error_mark_node)
+           {
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             continue;
+           }
+         objc_add_method_declaration (sig, attributes);
          cp_parser_consume_semicolon_at_end_of_statement (parser);
        }
+      else if (token->keyword == RID_ATTRIBUTE 
+              && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
+       warning_at (cp_lexer_peek_token (parser->lexer)->location, 
+                   OPT_Wattributes, 
+                   "prefix attributes are ignored for methods");
       else
        /* Allow for interspersed non-ObjC++ code.  */
        cp_parser_objc_interstitial_code (parser);
@@ -19777,27 +21687,43 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
 {
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
-  while (token->keyword != RID_AT_END)
+  while (token->keyword != RID_AT_END && token->type != CPP_EOF)
     {
       tree meth;
 
       if (token->type == CPP_PLUS || token->type == CPP_MINUS)
        {
+         cp_token *ptk;
+         tree sig, attribute;
          push_deferring_access_checks (dk_deferred);
-         objc_start_method_definition
-          (cp_parser_objc_method_signature (parser));
+         sig = cp_parser_objc_method_signature (parser, &attribute);
+         if (sig == error_mark_node)
+           {
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             continue;
+           }
+         objc_start_method_definition (sig, attribute);
 
          /* 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,
+         ptk = cp_lexer_peek_token (parser->lexer);
+         if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS 
+               || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
+           {
+             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);
+             pop_deferring_access_checks ();
+             objc_finish_method_definition (meth);
+           }
        }
+      else if (token->keyword == RID_ATTRIBUTE 
+              && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
+       warning_at (token->location, OPT_Wattributes,
+                   "prefix attributes are ignored for methods");
       else
        /* Allow for interspersed non-ObjC++ code.  */
        cp_parser_objc_interstitial_code (parser);
@@ -19930,7 +21856,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
 /* Parse an Objective-C protocol declaration.  */
 
 static void
-cp_parser_objc_protocol_declaration (cp_parser* parser)
+cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
 {
   tree proto, protorefs;
   cp_token *tok;
@@ -19939,7 +21865,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser)
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
     {
       tok = cp_lexer_peek_token (parser->lexer);
-      error ("%Hidentifier expected after %<@protocol%>", &tok->location);
+      error_at (tok->location, "identifier expected after %<@protocol%>");
       goto finish;
     }
 
@@ -19959,7 +21885,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser)
     {
       proto = cp_parser_identifier (parser);
       protorefs = cp_parser_objc_protocol_refs_opt (parser);
-      objc_start_protocol (proto, protorefs);
+      objc_start_protocol (proto, protorefs, attributes);
       cp_parser_objc_method_prototype_list (parser);
     }
 }
@@ -19982,14 +21908,14 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super,
     {
       cp_lexer_consume_token (parser->lexer);  /* Eat '('.  */
       *categ = cp_parser_identifier (parser);
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
     }
 }
 
 /* Parse an Objective-C class interface.  */
 
 static void
-cp_parser_objc_class_interface (cp_parser* parser)
+cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
 {
   tree name, super, categ, protos;
 
@@ -20000,10 +21926,10 @@ cp_parser_objc_class_interface (cp_parser* parser)
 
   /* We have either a class or a category on our hands.  */
   if (categ)
-    objc_start_category_interface (name, categ, protos);
+    objc_start_category_interface (name, categ, protos, attributes);
   else
     {
-      objc_start_class_interface (name, super, protos);
+      objc_start_class_interface (name, super, protos, attributes);
       /* Handle instance variable declarations, if any.  */
       cp_parser_objc_class_ivars (parser);
       objc_continue_interface ();
@@ -20049,11 +21975,31 @@ cp_parser_objc_end_implementation (cp_parser* parser)
 /* Parse an Objective-C declaration.  */
 
 static void
-cp_parser_objc_declaration (cp_parser* parser)
+cp_parser_objc_declaration (cp_parser* parser, tree attributes)
 {
   /* Try to figure out what kind of declaration is present.  */
   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
 
+  if (attributes)
+    switch (kwd->keyword)
+      {
+       case RID_AT_ALIAS:
+       case RID_AT_CLASS:
+       case RID_AT_END:
+         error_at (kwd->location, "attributes may not be specified before"
+                   " the %<@%D%> Objective-C++ keyword",
+                   kwd->u.value);
+         attributes = NULL;
+         break;
+       case RID_AT_IMPLEMENTATION:
+         warning_at (kwd->location, OPT_Wattributes,
+                     "prefix attributes are ignored before %<@%D%>",
+                     kwd->u.value);
+         attributes = NULL;
+       default:
+         break;
+      }
+
   switch (kwd->keyword)
     {
     case RID_AT_ALIAS:
@@ -20063,10 +22009,10 @@ cp_parser_objc_declaration (cp_parser* parser)
       cp_parser_objc_class_declaration (parser);
       break;
     case RID_AT_PROTOCOL:
-      cp_parser_objc_protocol_declaration (parser);
+      cp_parser_objc_protocol_declaration (parser, attributes);
       break;
     case RID_AT_INTERFACE:
-      cp_parser_objc_class_interface (parser);
+      cp_parser_objc_class_interface (parser, attributes);
       break;
     case RID_AT_IMPLEMENTATION:
       cp_parser_objc_class_implementation (parser);
@@ -20075,8 +22021,8 @@ cp_parser_objc_declaration (cp_parser* parser)
       cp_parser_objc_end_implementation (parser);
       break;
     default:
-      error ("%Hmisplaced %<@%D%> Objective-C++ construct",
-            &kwd->location, kwd->u.value);
+      error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
+               kwd->u.value);
       cp_parser_skip_to_end_of_block_or_statement (parser);
     }
 }
@@ -20103,7 +22049,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) {
   location_t location;
   tree stmt;
 
-  cp_parser_require_keyword (parser, RID_AT_TRY, "%<@try%>");
+  cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_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.  */
@@ -20117,13 +22063,13 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) {
       tree parm;
 
       cp_lexer_consume_token (parser->lexer);
-      cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+      cp_parser_require (parser, CPP_OPEN_PAREN, RT_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, "%<)%>");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       objc_begin_catch_clause (parm);
       cp_parser_compound_statement (parser, NULL, false);
       objc_finish_catch_clause ();
@@ -20155,12 +22101,12 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
   location_t location;
   tree lock, stmt;
 
-  cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, "%<@synchronized%>");
+  cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED);
 
   location = cp_lexer_peek_token (parser->lexer)->location;
-  cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   lock = cp_parser_expression (parser, false, NULL);
-  cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+  cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
   /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
      node, lest it get absorbed into the surrounding block.  */
@@ -20180,15 +22126,16 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
 static tree
 cp_parser_objc_throw_statement (cp_parser *parser) {
   tree expr = NULL_TREE;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
-  cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
+  cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW);
 
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     expr = cp_parser_assignment_expression (parser, false, NULL);
 
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 
-  return objc_build_throw_stmt (expr);
+  return objc_build_throw_stmt (loc, expr);
 }
 
 /* Parse an Objective-C statement.  */
@@ -20207,13 +22154,33 @@ cp_parser_objc_statement (cp_parser * parser) {
     case RID_AT_THROW:
       return cp_parser_objc_throw_statement (parser);
     default:
-      error ("%Hmisplaced %<@%D%> Objective-C++ construct",
-            &kwd->location, kwd->u.value);
+      error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
+              kwd->u.value);
       cp_parser_skip_to_end_of_block_or_statement (parser);
     }
 
   return error_mark_node;
 }
+
+/* If we are compiling ObjC++ and we see an __attribute__ we neeed to 
+   look ahead to see if an objc keyword follows the attributes.  This
+   is to detect the use of prefix attributes on ObjC @interface and 
+   @protocol.  */
+
+static bool
+cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
+{
+  cp_lexer_save_tokens (parser->lexer);
+  *attrib = cp_parser_attributes_opt (parser);
+  gcc_assert (*attrib);
+  if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
+    {
+      cp_lexer_commit_tokens (parser->lexer);
+      return true;
+    }
+  cp_lexer_rollback_tokens (parser->lexer);
+  return false;  
+}
 \f
 /* OpenMP 2.5 parsing routines.  */
 
@@ -20300,7 +22267,7 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
     if (OMP_CLAUSE_CODE (c) == code)
       {
-       error ("%Htoo many %qs clauses", &location, name);
+       error_at (location, "too many %qs clauses", name);
        break;
       }
 }
@@ -20339,10 +22306,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 
       decl = cp_parser_lookup_name_simple (parser, name, token->location);
       if (decl == error_mark_node)
-       cp_parser_name_lookup_error (parser, name, decl, NULL, token->location);
+       cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
+                                    token->location);
       else if (kind != 0)
        {
-         tree u = build_omp_clause (kind);
+         tree u = build_omp_clause (token->location, kind);
          OMP_CLAUSE_DECL (u) = decl;
          OMP_CLAUSE_CHAIN (u) = list;
          list = u;
@@ -20356,7 +22324,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
       cp_lexer_consume_token (parser->lexer);
     }
 
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     {
       int ending;
 
@@ -20380,7 +22348,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 static tree
 cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list)
 {
-  if (cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return cp_parser_omp_var_list_no_open (parser, kind, list);
   return list;
 }
@@ -20396,12 +22364,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location
   HOST_WIDE_INT n;
 
   loc = cp_lexer_peek_token (parser->lexer)->location;
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
   num = cp_parser_constant_expression (parser, false, NULL);
 
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
                                           /*consume_paren=*/true);
@@ -20414,13 +22382,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location
       || (n = tree_low_cst (num, 0)) <= 0
       || (int) n != n)
     {
-      error ("%Hcollapse argument needs positive constant integer expression",
-            &loc);
+      error_at (loc, "collapse argument needs positive constant integer expression");
       return list;
     }
 
   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
-  c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
+  c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
   OMP_CLAUSE_CHAIN (c) = list;
   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
 
@@ -20436,7 +22403,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
   tree c;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
@@ -20469,7 +22436,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
       cp_parser_error (parser, "expected %<none%> or %<shared%>");
     }
 
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
                                           /*consume_paren=*/true);
@@ -20478,7 +22445,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
     return list;
 
   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
-  c = build_omp_clause (OMP_CLAUSE_DEFAULT);
+  c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
   OMP_CLAUSE_CHAIN (c) = list;
   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
 
@@ -20493,20 +22460,20 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
 {
   tree t, c;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
   t = cp_parser_condition (parser);
 
   if (t == error_mark_node
-      || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+      || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
                                           /*consume_paren=*/true);
 
   check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
 
-  c = build_omp_clause (OMP_CLAUSE_IF);
+  c = build_omp_clause (location, OMP_CLAUSE_IF);
   OMP_CLAUSE_IF_EXPR (c) = t;
   OMP_CLAUSE_CHAIN (c) = list;
 
@@ -20524,7 +22491,7 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED,
 
   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
 
-  c = build_omp_clause (OMP_CLAUSE_NOWAIT);
+  c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -20538,13 +22505,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
 {
   tree t, c;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
   t = cp_parser_expression (parser, false, NULL);
 
   if (t == error_mark_node
-      || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+      || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
                                           /*consume_paren=*/true);
@@ -20552,7 +22519,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
   check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
                             "num_threads", location);
 
-  c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+  c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
   OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
   OMP_CLAUSE_CHAIN (c) = list;
 
@@ -20571,7 +22538,7 @@ cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED,
   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
                             "ordered", location);
 
-  c = build_omp_clause (OMP_CLAUSE_ORDERED);
+  c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -20588,7 +22555,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
   enum tree_code code;
   tree nlist, c;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
   switch (cp_lexer_peek_token (parser->lexer)->type)
@@ -20628,7 +22595,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
     }
   cp_lexer_consume_token (parser->lexer);
 
-  if (!cp_parser_require (parser, CPP_COLON, "%<:%>"))
+  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
     goto resync_fail;
 
   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list);
@@ -20650,10 +22617,10 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
 {
   tree c, t;
 
-  if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
-  c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+  c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
@@ -20703,18 +22670,18 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
       if (t == error_mark_node)
        goto resync_fail;
       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
-       error ("%Hschedule %<runtime%> does not take "
-              "a %<chunk_size%> parameter", &token->location);
+       error_at (token->location, "schedule %<runtime%> does not take "
+                 "a %<chunk_size%> parameter");
       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
-       error ("%Hschedule %<auto%> does not take "
-              "a %<chunk_size%> parameter", &token->location);
+       error_at (token->location, "schedule %<auto%> does not take "
+                 "a %<chunk_size%> parameter");
       else
        OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
 
-      if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+      if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
        goto resync_fail;
     }
-  else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>"))
+  else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
     goto resync_fail;
 
   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
@@ -20741,7 +22708,7 @@ cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED,
 
   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
 
-  c = build_omp_clause (OMP_CLAUSE_UNTIED);
+  c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -20854,7 +22821,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
          /* Remove the invalid clause(s) from the list to avoid
             confusing the rest of the compiler.  */
          clauses = prev;
-         error ("%H%qs is not valid for %qs", &token->location, c_name, where);
+         error_at (token->location, "%qs is not valid for %qs", c_name, where);
        }
     }
  saw_error:
@@ -20947,6 +22914,32 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
       rhs = integer_one_node;
       break;
 
+    case COMPOUND_EXPR:
+      if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
+        && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
+        && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
+        && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
+        && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
+                                            (TREE_OPERAND (lhs, 1), 0), 0)))
+           == BOOLEAN_TYPE)
+       /* Undo effects of boolean_increment for post {in,de}crement.  */
+       lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
+      /* FALLTHRU */
+    case MODIFY_EXPR:
+      if (TREE_CODE (lhs) == MODIFY_EXPR
+        && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
+       {
+        /* Undo effects of boolean_increment.  */
+        if (integer_onep (TREE_OPERAND (lhs, 1)))
+          {
+            /* This is pre or post increment.  */
+            rhs = TREE_OPERAND (lhs, 1);
+            lhs = TREE_OPERAND (lhs, 0);
+            code = NOP_EXPR;
+            break;
+          }
+       }
+      /* FALLTHRU */
     default:
       switch (cp_lexer_peek_token (parser->lexer)->type)
        {
@@ -21024,7 +23017,7 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
       name = cp_parser_identifier (parser);
 
       if (name == error_mark_node
-         || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+         || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                               /*or_comma=*/false,
                                               /*consume_paren=*/true);
@@ -21034,7 +23027,7 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
   stmt = cp_parser_omp_structured_block (parser);
-  return c_finish_omp_critical (stmt, name);
+  return c_finish_omp_critical (input_location, stmt, name);
 }
 
 /* OpenMP 2.5:
@@ -21190,11 +23183,12 @@ static tree
 cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
 {
   tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
-  tree for_block = NULL_TREE, real_decl, initv, condv, incrv, declv;
+  tree real_decl, initv, condv, incrv, declv;
   tree this_pre_body, cl;
   location_t loc_first;
   bool collapse_err = false;
   int i, collapse = 1, nbraces = 0;
+  VEC(tree,gc) *for_block = make_tree_vector ();
 
   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -21222,7 +23216,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
        }
       loc = cp_lexer_consume_token (parser->lexer)->location;
 
-      if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+      if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
        return NULL;
 
       init = decl = real_decl = NULL;
@@ -21243,7 +23237,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
             cp_parser_condition, from whence the bulk of this is copied.  */
 
          cp_parser_parse_tentatively (parser);
-         cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
+         cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
+                                       /*is_trailing_return=*/false,
                                        &type_specifiers);
          if (cp_parser_parse_definitely (parser))
            {
@@ -21281,7 +23276,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                               "OpenMP %<for%> loop");
                      else
                        /* Trigger an error.  */
-                       cp_parser_require (parser, CPP_EQ, "%<=%>");
+                       cp_parser_require (parser, CPP_EQ, RT_EQ);
 
                      init = error_mark_node;
                      cp_parser_skip_to_end_of_statement (parser);
@@ -21312,8 +23307,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                                      LOOKUP_ONLYCONVERTING);
                      if (CLASS_TYPE_P (TREE_TYPE (decl)))
                        {
-                         for_block
-                           = tree_cons (NULL, this_pre_body, for_block);
+                         VEC_safe_push (tree, gc, for_block, this_pre_body);
                          init = NULL_TREE;
                        }
                      else
@@ -21356,7 +23350,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                  tree rhs;
 
                  cp_parser_parse_definitely (parser);
-                 cp_parser_require (parser, CPP_EQ, "%<=%>");
+                 cp_parser_require (parser, CPP_EQ, RT_EQ);
                  rhs = cp_parser_assignment_expression (parser, false, NULL);
                  finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR,
                                                         rhs,
@@ -21377,7 +23371,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                }
            }
        }
-      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
       if (this_pre_body)
        {
          this_pre_body = pop_stmt_list (this_pre_body);
@@ -21402,8 +23396,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
            if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE
                && OMP_CLAUSE_DECL (*c) == real_decl)
              {
-               error ("%Hiteration variable %qD should not be firstprivate",
-                      &loc, real_decl);
+               error_at (loc, "iteration variable %qD"
+                         " should not be firstprivate", real_decl);
                *c = OMP_CLAUSE_CHAIN (*c);
              }
            else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
@@ -21411,7 +23405,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
              {
                /* Add lastprivate (decl) clause to OMP_FOR_CLAUSES,
                   change it to shared (decl) in OMP_PARALLEL_CLAUSES.  */
-               tree l = build_omp_clause (OMP_CLAUSE_LASTPRIVATE);
+               tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
                OMP_CLAUSE_DECL (l) = real_decl;
                OMP_CLAUSE_CHAIN (l) = clauses;
                CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
@@ -21440,16 +23434,17 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                break;
              else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
                       && OMP_CLAUSE_DECL (c) == decl)
-               error ("%Hiteration variable %qD should not be firstprivate",
-                      &loc, decl);
+               error_at (loc, "iteration variable %qD "
+                         "should not be firstprivate",
+                         decl);
              else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
                       && OMP_CLAUSE_DECL (c) == decl)
-               error ("%Hiteration variable %qD should not be reduction",
-                      &loc, decl);
+               error_at (loc, "iteration variable %qD should not be reduction",
+                         decl);
            }
          if (c == NULL)
            {
-             c = build_omp_clause (OMP_CLAUSE_PRIVATE);
+             c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
              OMP_CLAUSE_DECL (c) = decl;
              c = finish_omp_clauses (c);
              if (c)
@@ -21463,7 +23458,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
       cond = NULL;
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
        cond = cp_parser_omp_for_cond (parser, decl);
-      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 
       incr = NULL;
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
@@ -21478,7 +23473,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
            incr = cp_parser_expression (parser, false, NULL);
        }
 
-      if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+      if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                               /*or_comma=*/false,
                                               /*consume_paren=*/true);
@@ -21511,7 +23506,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
          else
            {
              loc = cp_lexer_peek_token (parser->lexer)->location;
-             error ("%Hnot enough collapsed for loops", &loc);
+             error_at (loc, "not enough collapsed for loops");
              collapse_err = true;
              cp_parser_abort_tentative_parse (parser);
              declv = NULL_TREE;
@@ -21556,20 +23551,19 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
        {
          if (!collapse_err)
            {
-             location_t loc = cp_lexer_peek_token (parser->lexer)->location;
-             error ("%Hcollapsed loops not perfectly nested", &loc);
+             error_at (cp_lexer_peek_token (parser->lexer)->location,
+                       "collapsed loops not perfectly nested");
            }
          collapse_err = true;
          cp_parser_statement_seq_opt (parser, NULL);
-         cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+         if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+           break;
        }
     }
 
-  while (for_block)
-    {
-      add_stmt (pop_stmt_list (TREE_VALUE (for_block)));
-      for_block = TREE_CHAIN (for_block);
-    }
+  while (!VEC_empty (tree, for_block))
+    add_stmt (pop_stmt_list (VEC_pop (tree, for_block)));
+  release_tree_vector (for_block);
 
   return ret;
 }
@@ -21616,7 +23610,8 @@ static tree
 cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
 {
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_master (cp_parser_omp_structured_block (parser));
+  return c_finish_omp_master (input_location,
+                             cp_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
@@ -21626,8 +23621,9 @@ cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
 static tree
 cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
 {
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_ordered (cp_parser_omp_structured_block (parser));
+  return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
@@ -21646,7 +23642,7 @@ cp_parser_omp_sections_scope (cp_parser *parser)
   bool error_suppress = false;
   cp_token *tok;
 
-  if (!cp_parser_require (parser, CPP_OPEN_BRACE, "%<{%>"))
+  if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
     return NULL_TREE;
 
   stmt = push_stmt_list ();
@@ -21701,7 +23697,7 @@ cp_parser_omp_sections_scope (cp_parser *parser)
       substmt = build1 (OMP_SECTION, void_type_node, substmt);
       add_stmt (substmt);
     }
-  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
   substmt = pop_stmt_list (stmt);
 
@@ -21762,6 +23758,7 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok)
   tree stmt, clauses, par_clause, ws_clause, block;
   unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
   unsigned int save;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
     {
@@ -21797,12 +23794,12 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok)
       break;
 
     case PRAGMA_OMP_PARALLEL_FOR:
-      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+      c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
       cp_parser_omp_for_loop (parser, ws_clause, &par_clause);
       break;
 
     case PRAGMA_OMP_PARALLEL_SECTIONS:
-      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+      c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
       stmt = cp_parser_omp_sections_scope (parser);
       if (stmt)
        OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
@@ -21968,11 +23965,11 @@ cp_parser_initial_pragma (cp_token *first_token)
 
       cp_lexer_get_preprocessor_token (NULL, first_token);
       if (first_token->type != CPP_PRAGMA_EOL)
-       error ("%Hjunk at end of %<#pragma GCC pch_preprocess%>",
-               &first_token->location);
+       error_at (first_token->location,
+                 "junk at end of %<#pragma GCC pch_preprocess%>");
     }
   else
-    error ("%Hexpected string literal", &first_token->location);
+    error_at (first_token->location, "expected string literal");
 
   /* Skip to the end of the pragma.  */
   while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
@@ -22005,8 +24002,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
   switch (id)
     {
     case PRAGMA_GCC_PCH_PREPROCESS:
-      error ("%H%<#pragma GCC pch_preprocess%> must be first",
-             &pragma_tok->location);
+      error_at (pragma_tok->location,
+               "%<#pragma GCC pch_preprocess%> must be first");
       break;
 
     case PRAGMA_OMP_BARRIER:
@@ -22016,8 +24013,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
          cp_parser_omp_barrier (parser, pragma_tok);
          return false;
        case pragma_stmt:
-         error ("%H%<#pragma omp barrier%> may only be "
-                "used in compound statements", &pragma_tok->location);
+         error_at (pragma_tok->location, "%<#pragma omp barrier%> may only be "
+                   "used in compound statements");
          break;
        default:
          goto bad_stmt;
@@ -22031,8 +24028,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
          cp_parser_omp_flush (parser, pragma_tok);
          return false;
        case pragma_stmt:
-         error ("%H%<#pragma omp flush%> may only be "
-                "used in compound statements", &pragma_tok->location);
+         error_at (pragma_tok->location, "%<#pragma omp flush%> may only be "
+                   "used in compound statements");
          break;
        default:
          goto bad_stmt;
@@ -22046,9 +24043,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
          cp_parser_omp_taskwait (parser, pragma_tok);
          return false;
        case pragma_stmt:
-         error ("%H%<#pragma omp taskwait%> may only be "
-                "used in compound statements",
-                &pragma_tok->location);
+         error_at (pragma_tok->location,
+                   "%<#pragma omp taskwait%> may only be "
+                   "used in compound statements");
          break;
        default:
          goto bad_stmt;
@@ -22074,8 +24071,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
       return true;
 
     case PRAGMA_OMP_SECTION:
-      error ("%H%<#pragma omp section%> may only be used in "
-            "%<#pragma omp sections%> construct", &pragma_tok->location);
+      error_at (pragma_tok->location, 
+               "%<#pragma omp section%> may only be used in "
+               "%<#pragma omp sections%> construct");
       break;
 
     default:
@@ -22127,7 +24125,6 @@ pragma_lex (tree *value)
 void
 c_parse_file (void)
 {
-  bool error_occurred;
   static bool already_called = false;
 
   if (already_called)
@@ -22140,7 +24137,7 @@ c_parse_file (void)
   the_parser = cp_parser_new ();
   push_deferring_access_checks (flag_access_control
                                ? dk_no_deferred : dk_no_check);
-  error_occurred = cp_parser_translation_unit (the_parser);
+  cp_parser_translation_unit (the_parser);
   the_parser = NULL;
 }