OSDN Git Service

2010-03-18 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 545d3dd..d27d122 100644 (file)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
+#include "intl.h"
 #include "c-pragma.h"
 #include "decl.h"
 #include "flags.h"
@@ -37,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "cgraph.h"
 #include "c-common.h"
+#include "plugin.h"
 
 \f
 /* The lexer.  */
@@ -47,8 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 /* A token's value and its associated deferred access checks and
    qualifying scope.  */
 
-struct tree_check GTY(())
-{
+struct GTY(()) tree_check {
   /* The value associated with the token.  */
   tree value;
   /* The checks that have been associated with value.  */
@@ -60,8 +61,7 @@ struct tree_check GTY(())
 
 /* A C++ token.  */
 
-typedef struct cp_token GTY (())
-{
+typedef struct GTY (()) cp_token {
   /* The kind of token.  */
   ENUM_BITFIELD (cpp_ttype) type : 8;
   /* If this token is a keyword, this value indicates which keyword.
@@ -77,6 +77,8 @@ typedef struct cp_token GTY (())
      KEYWORD is RID_MAX) iff this name was looked up and found to be
      ambiguous.  An error has already been reported.  */
   BOOL_BITFIELD ambiguous_p : 1;
+  /* The location at which this token was found.  */
+  location_t location;
   /* The value associated with this token, if any.  */
   union cp_token_value {
     /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID.  */
@@ -84,8 +86,6 @@ typedef struct cp_token GTY (())
     /* Use for all other tokens.  */
     tree GTY((tag ("0"))) value;
   } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
-  /* The location at which this token was found.  */
-  location_t location;
 } cp_token;
 
 /* We use a stack of token pointer for saving token sets.  */
@@ -95,8 +95,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap);
 
 static cp_token eof_token =
 {
-  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, { NULL },
-  0
+  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, 0, { NULL }
 };
 
 /* The cp_lexer structure represents the C++ lexer.  It is responsible
@@ -104,8 +103,7 @@ static cp_token eof_token =
    it to the parser.  Tokens are never added to the cp_lexer after
    it is created.  */
 
-typedef struct cp_lexer GTY (())
-{
+typedef struct GTY (()) cp_lexer {
   /* The memory allocated for the buffer.  NULL if this lexer does not
      own the token buffer.  */
   cp_token * GTY ((length ("%h.buffer_length"))) buffer;
@@ -144,8 +142,7 @@ typedef struct cp_lexer GTY (())
    a cp_token_cache, since everything in here is referenced through
    a lexer.  */
 
-typedef struct cp_token_cache GTY(())
-{
+typedef struct GTY(()) cp_token_cache {
   /* The beginning of the token range.  */
   cp_token * GTY((skip)) first;
 
@@ -251,6 +248,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.  */
 
@@ -310,8 +311,7 @@ cp_lexer_new_main (void)
 
   /* Subsequent preprocessor diagnostics should use compiler
      diagnostic functions to get the compiler source location.  */
-  cpp_get_options (parse_in)->client_diagnostic = true;
-  cpp_get_callbacks (parse_in)->error = cp_cpp_error;
+  done_lexing = true;
 
   gcc_assert (lexer->next_token->type != CPP_PURGED);
   return lexer;
@@ -403,7 +403,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;
 
@@ -423,11 +423,6 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
          token->type = CPP_KEYWORD;
          /* Record which keyword.  */
          token->keyword = C_RID_CODE (token->u.value);
-         /* Update the value.  Some keywords are mapped to particular
-            entities, rather than simply having the value of the
-            corresponding IDENTIFIER_NODE.  For example, `__const' is
-            mapped to `const'.  */
-         token->u.value = ridpointers[token->keyword];
        }
       else
        {
@@ -438,8 +433,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.  */
@@ -470,7 +465,8 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
   else if (token->type == CPP_PRAGMA)
     {
       /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
-      token->pragma_kind = TREE_INT_CST_LOW (token->u.value);
+      token->pragma_kind = ((enum pragma_kind)
+                           TREE_INT_CST_LOW (token->u.value));
       token->u.value = NULL_TREE;
     }
 }
@@ -797,6 +793,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;
 
@@ -1192,16 +1189,24 @@ function_declarator_p (const cp_declarator *declarator)
 /* Flags that are passed to some parsing functions.  These values can
    be bitwise-ored together.  */
 
-typedef 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
-} cp_parser_flags;
+  /* 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 above flags.  */
+typedef int cp_parser_flags;
 
 /* The different kinds of declarators we want to parse.  */
 
@@ -1273,7 +1278,7 @@ typedef struct cp_parser_expression_stack_entry
   /* Tree code for the binary operation we are parsing.  */
   enum tree_code tree_type;
   /* Precedence of the binary operation we are parsing.  */
-  int prec;
+  enum cp_parser_prec prec;
 } cp_parser_expression_stack_entry;
 
 /* The stack for storing partial expressions.  We only need NUM_PREC_VALUES
@@ -1283,8 +1288,7 @@ typedef struct cp_parser_expression_stack_entry
   cp_parser_expression_stack[NUM_PREC_VALUES];
 
 /* Context that is saved and restored when parsing tentatively.  */
-typedef struct cp_parser_context GTY (())
-{
+typedef struct GTY (()) cp_parser_context {
   /* If this is a tentative parsing context, the status of the
      tentative parse.  */
   enum cp_parser_status_kind status;
@@ -1390,8 +1394,7 @@ cp_parser_context_new (cp_parser_context* next)
 
 /* The cp_parser structure represents the C++ parser.  */
 
-typedef struct cp_parser GTY(())
-{
+typedef struct GTY(()) cp_parser {
   /* The lexer from which we are obtaining tokens.  */
   cp_lexer *lexer;
 
@@ -1586,22 +1589,22 @@ static tree cp_parser_nested_name_specifier
 static tree cp_parser_qualifying_entity
   (cp_parser *, bool, bool, bool, bool, bool);
 static tree cp_parser_postfix_expression
-  (cp_parser *, bool, bool, bool);
+  (cp_parser *, bool, bool, bool, cp_id_kind *);
 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
+static VEC(tree,gc) *cp_parser_parenthesized_expression_list
   (cp_parser *, bool, bool, bool, bool *);
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree *, tree *);
 static tree cp_parser_unary_expression
-  (cp_parser *, bool, bool);
+  (cp_parser *, bool, bool, cp_id_kind *);
 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 *);
@@ -1609,26 +1612,34 @@ 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 *);
 static tree cp_parser_cast_expression
-  (cp_parser *, bool, bool);
+  (cp_parser *, bool, bool, cp_id_kind *);
 static tree cp_parser_binary_expression
-  (cp_parser *, bool, enum cp_parser_prec);
+  (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
 static tree cp_parser_question_colon_clause
   (cp_parser *, tree);
 static tree cp_parser_assignment_expression
-  (cp_parser *, bool);
+  (cp_parser *, bool, cp_id_kind *);
 static enum tree_code cp_parser_assignment_operator_opt
   (cp_parser *);
 static tree cp_parser_expression
-  (cp_parser *, bool);
+  (cp_parser *, bool, cp_id_kind *);
 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]  */
 
@@ -1734,8 +1745,13 @@ static tree cp_parser_declarator_id
   (cp_parser *, bool);
 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, 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
@@ -1858,6 +1874,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
@@ -1911,7 +1929,7 @@ static tree cp_parser_maybe_treat_template_as_class
 static bool cp_parser_check_declarator_template_parameters
   (cp_parser *, cp_declarator *, location_t);
 static bool cp_parser_check_template_parameters
-  (cp_parser *, unsigned, location_t);
+  (cp_parser *, unsigned, location_t, cp_declarator *);
 static tree cp_parser_simple_cast_expression
   (cp_parser *);
 static tree cp_parser_global_scope_opt
@@ -2049,7 +2067,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.  */
@@ -2078,7 +2097,8 @@ 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;
        }
@@ -2088,7 +2108,7 @@ cp_parser_error (cp_parser* parser, const char* message)
                        CPP_KEYWORD, keywords are treated like
                        identifiers.  */
                     (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
-                    token->u.value);
+                    token->u.value, token->flags);
     }
 }
 
@@ -2109,26 +2129,26 @@ 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);
+    error_at (location, "%<%E::%E%> %s", parser->scope, name, desired);
   else if (parser->scope == global_namespace)
-    error ("%H%<::%E%> %s", &location, name, desired);
+    error_at (location, "%<::%E%> %s", name, desired);
   else
-    error ("%H%qE %s", &location, name, desired);
+    error_at (location, "%qE %s", name, desired);
 }
 
 /* If we are parsing tentatively, remember that an error has occurred
@@ -2152,22 +2172,21 @@ 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);
-         else if (pedantic && !in_system_header && warn_long_long
-                   && cxx_dialect == cxx98)
-           pedwarn (location, OPT_Wlong_long, 
-                    "ISO C++ 1998 does not support %<long long%>");
+           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%>");
        }
       else if (count > 1)
        {
@@ -2184,10 +2203,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]);
        }
     }
 }
@@ -2231,7 +2251,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);
@@ -2253,11 +2274,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);
@@ -2319,18 +2340,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:
 
@@ -2378,11 +2399,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 ();
     }
@@ -2405,6 +2441,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,
@@ -2412,12 +2456,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);
@@ -2429,9 +2470,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;
 }
 
@@ -2448,6 +2492,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))
@@ -2464,6 +2509,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)
@@ -2479,7 +2533,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;
 
@@ -2621,6 +2676,8 @@ cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
          /* Stop if this is an unnested '}', or closes the outermost
             nesting level.  */
          nesting_depth--;
+         if (nesting_depth < 0)
+           return;
          if (!nesting_depth)
            nesting_depth = -1;
          break;
@@ -2943,8 +3000,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));
@@ -2972,6 +3030,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,6 +3203,12 @@ cp_parser_primary_expression (cp_parser *parser,
     case CPP_WCHAR:
     case CPP_NUMBER:
       token = cp_lexer_consume_token (parser->lexer);
+      if (TREE_CODE (token->u.value) == FIXED_CST)
+       {
+         error_at (token->location,
+                   "fixed-point types not supported in C++");
+         return error_mark_node;
+       }
       /* Floating-point literals are only allowed in an integral
         constant expression if they are cast to an integral or
         enumeration type.  */
@@ -3195,6 +3260,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.  */
@@ -3232,9 +3298,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;
              }
@@ -3251,7 +3317,7 @@ cp_parser_primary_expression (cp_parser *parser,
        else
          {
            /* Parse the parenthesized expression.  */
-           expr = cp_parser_expression (parser, cast_p);
+           expr = cp_parser_expression (parser, cast_p, idk);
            /* Let the front end know that this expression was
               enclosed in parentheses. This matters in case, for
               example, the expression is of the form `A::B', since
@@ -3270,6 +3336,20 @@ cp_parser_primary_expression (cp_parser *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)
        {
@@ -3291,8 +3371,8 @@ cp_parser_primary_expression (cp_parser *parser,
          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.  */
@@ -3354,7 +3434,7 @@ cp_parser_primary_expression (cp_parser *parser,
            cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
            /* Now, parse the assignment-expression.  */
            expression = cp_parser_assignment_expression (parser,
-                                                         /*cast_p=*/false);
+                                                         /*cast_p=*/false, NULL);
            /* Look for the `,'.  */
            cp_parser_require (parser, CPP_COMMA, "%<,%>");
            /* Parse the type-id.  */
@@ -3388,6 +3468,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);
 
@@ -3447,6 +3529,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,
@@ -3500,8 +3592,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;
                  }
              }
@@ -3524,13 +3617,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;
     }
@@ -3800,8 +3886,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);
@@ -3814,7 +3901,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
-               == CPP_OPEN_PAREN)
+               != CPP_LESS)
            && constructor_name_p (token->u.value, scope))
          {
            cp_lexer_consume_token (parser->lexer);
@@ -3822,7 +3909,11 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
 
        /* 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)
@@ -3831,7 +3922,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);
@@ -3849,7 +3940,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);
@@ -3867,7 +3958,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);
@@ -3880,14 +3971,26 @@ cp_parser_unqualified_id (cp_parser* parser,
            parser->scope = NULL_TREE;
            parser->object_scope = NULL_TREE;
            parser->qualifying_scope = NULL_TREE;
+           if (processing_template_decl)
+             cp_parser_parse_tentatively (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);
+           if (processing_template_decl
+               && ! cp_parser_parse_definitely (parser))
+             {
+               /* We couldn't find a type with this name, so just accept
+                  it and check for a match at instantiation time.  */
+               type_decl = cp_parser_identifier (parser);
+               if (type_decl != error_mark_node)
+                 type_decl = build_nt (BIT_NOT_EXPR, type_decl);
+               return type_decl;
+             }
          }
        /* If an error occurred, assume that the name of the
           destructor is the same as the name of the qualifying
@@ -3902,8 +4005,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;
          }
@@ -3916,8 +4020,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));
       }
@@ -4130,12 +4235,14 @@ 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;
                        }
@@ -4399,7 +4506,8 @@ cp_parser_qualifying_entity (cp_parser *parser,
 
 static tree
 cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
-                              bool member_access_only_p)
+                              bool member_access_only_p,
+                             cp_id_kind * pidk_return)
 {
   cp_token *token;
   enum rid keyword;
@@ -4430,7 +4538,7 @@ 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, "%<<%>");
@@ -4443,7 +4551,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 
        /* And the expression which is being cast.  */
        cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
-       expression = cp_parser_expression (parser, /*cast_p=*/true);
+       expression = cp_parser_expression (parser, /*cast_p=*/true, & idk);
        cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
 
        /* Only type conversions to integral or enumeration types
@@ -4493,7 +4601,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* 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);
@@ -4515,7 +4623,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
            tree expression;
 
            /* Look for an expression.  */
-           expression = cp_parser_expression (parser, /*cast_p=*/false);
+           expression = cp_parser_expression (parser, /*cast_p=*/false, & idk);
            /* Compute its typeid.  */
            postfix_expression = build_typeid (expression);
            /* Look for the `)' token.  */
@@ -4668,7 +4776,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;
 
@@ -4696,7 +4804,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;
@@ -4709,19 +4817,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                                                               "a function call"))
              {
                postfix_expression = error_mark_node;
+               release_tree_vector (args);
                break;
              }
 
            koenig_p = false;
-           if (idk == CP_ID_KIND_UNQUALIFIED)
+           if (idk == CP_ID_KIND_UNQUALIFIED
+               || idk == CP_ID_KIND_TEMPLATE_ID)
              {
                if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  {
-                   if (args)
+                   if (!VEC_empty (tree, args))
                      {
                        koenig_p = true;
-                       postfix_expression
-                         = perform_koenig_lookup (postfix_expression, args);
+                       if (!any_type_dependent_arguments_p (args))
+                         postfix_expression
+                           = perform_koenig_lookup (postfix_expression, args);
                      }
                    else
                      postfix_expression
@@ -4730,21 +4841,22 @@ 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;
-                       postfix_expression
-                         = perform_koenig_lookup (postfix_expression, args);
+                       if (!any_type_dependent_arguments_p (args))
+                         postfix_expression
+                           = perform_koenig_lookup (postfix_expression, args);
                      }
                  }
              }
@@ -4762,21 +4874,24 @@ 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;
                  }
 
                if (BASELINK_P (fn))
+                 {
                  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,
                        tf_warning_or_error));
+                 }
                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);
@@ -4785,28 +4900,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);
 
-            if (warn_disallowed_functions)
-              warn_if_disallowed_function_p (postfix_expression);
-
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
+
+           release_tree_vector (args);
          }
          break;
 
@@ -4862,6 +4976,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
          break;
 
        default:
+         if (pidk_return != NULL)
+           * pidk_return = idk;
           if (member_access_only_p)
             return is_member_access? postfix_expression : error_mark_node;
           else
@@ -4903,7 +5019,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
   if (for_offsetof)
     index = cp_parser_constant_expression (parser, false, NULL);
   else
-    index = cp_parser_expression (parser, /*cast_p=*/false);
+    index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
   /* Look for the closing `]'.  */
   cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
@@ -4956,6 +5072,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   parser->qualifying_scope = NULL_TREE;
   parser->object_scope = NULL_TREE;
   *idk = CP_ID_KIND_NONE;
+
   /* Enter the scope corresponding to the type of the object
      given by the POSTFIX_EXPRESSION.  */
   if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
@@ -4971,7 +5088,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
@@ -5055,7 +5173,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,24 +5228,22 @@ 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.  */
+   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 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
+static VEC(tree,gc) *
 cp_parser_parenthesized_expression_list (cp_parser* parser,
                                         bool is_attribute_list,
                                         bool cast_p,
                                          bool allow_expansion_p,
                                         bool *non_constant_p)
 {
-  tree expression_list = NULL_TREE;
+  VEC(tree,gc) *expression_list;
   bool fold_expr_p = is_attribute_list;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
@@ -5137,7 +5253,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
     *non_constant_p = false;
 
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
-    return error_mark_node;
+    return NULL;
+
+  expression_list = make_tree_vector ();
 
   /* Within a parenthesized expression, a `>' token is always
      the greater-than operator.  */
@@ -5171,7 +5289,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;
@@ -5185,7 +5303,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
                  *non_constant_p = true;
              }
            else
-             expr = cp_parser_assignment_expression (parser, cast_p);
+             expr = cp_parser_assignment_expression (parser, cast_p, NULL);
 
            if (fold_expr_p)
              expr = fold_non_dependent_expr (expr);
@@ -5206,7 +5324,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;
@@ -5242,17 +5360,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;
 }
@@ -5369,7 +5485,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
    Returns a representation of the expression.  */
 
 static tree
-cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
+                           cp_id_kind * pidk)
 {
   cp_token *token;
   enum tree_code unary_operator;
@@ -5506,13 +5623,13 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
       cast_expression
        = cp_parser_cast_expression (parser,
                                     unary_operator == ADDR_EXPR,
-                                    /*cast_p=*/false);
+                                    /*cast_p=*/false, pidk);
       /* Now, build an appropriate representation.  */
       switch (unary_operator)
        {
        case INDIRECT_REF:
          non_constant_p = "%<*%>";
-         expression = build_x_indirect_ref (cast_expression, "unary *",
+         expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
                                              tf_warning_or_error);
          break;
 
@@ -5548,7 +5665,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
     }
 
   return cp_parser_postfix_expression (parser, address_p, cast_p,
-                                       /*member_access_only_p=*/false);
+                                       /*member_access_only_p=*/false,
+                                      pidk);
 }
 
 /* Returns ERROR_MARK if TOKEN is not a unary-operator.  If TOKEN is a
@@ -5594,10 +5712,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
@@ -5613,7 +5732,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.  */
@@ -5632,8 +5755,8 @@ cp_parser_new_expression (cp_parser* parser)
         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);
@@ -5649,16 +5772,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;
+    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.
@@ -5668,10 +5800,10 @@ 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
@@ -5706,9 +5838,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;
@@ -5748,7 +5881,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
        new_declarator = NULL;
     }
 
-  type = groktypename (&type_specifier_seq, new_declarator);
+  type = groktypename (&type_specifier_seq, new_declarator, false);
   return type;
 }
 
@@ -5813,7 +5946,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
       if (!declarator)
        {
          cp_token *token = cp_lexer_peek_token (parser->lexer);
-         expression = cp_parser_expression (parser, /*cast_p=*/false);
+         expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
          /* The standard requires that the expression have integral
             type.  DR 74 adds enumeration types.  We believe that the
             real intent is that these expressions be handled like the
@@ -5828,8 +5961,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;
                }
            }
@@ -5861,28 +5995,26 @@ 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,
                        /*non_constant_p=*/NULL));
-  if (!expression_list)
-    expression_list = void_zero_node;
 
   return expression_list;
 }
@@ -6001,7 +6133,8 @@ cp_parser_token_starts_cast_expression (cp_token *token)
    Returns a representation of the expression.  */
 
 static tree
-cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
+cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
+                          cp_id_kind * pidk)
 {
   /* If it's a `(', then we might be looking at a cast.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -6018,7 +6151,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
@@ -6076,7 +6209,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
          cp_parser_parse_definitely (parser);
          expr = cp_parser_cast_expression (parser,
                                            /*address_p=*/false,
-                                           /*cast_p=*/true);
+                                           /*cast_p=*/true, pidk);
 
          /* Warn about old-style casts, if so requested.  */
          if (warn_old_style_cast
@@ -6095,7 +6228,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
            return error_mark_node;
 
          /* Perform the cast.  */
-         expr = build_c_cast (type, expr);
+         expr = build_c_cast (input_location, type, expr);
          return expr;
        }
       else 
@@ -6104,7 +6237,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
 
   /* If we get here, then it's not a cast, so it must be a
      unary-expression.  */
-  return cp_parser_unary_expression (parser, address_p, cast_p);
+  return cp_parser_unary_expression (parser, address_p, cast_p, pidk);
 }
 
 /* Parse a binary expression of the general form:
@@ -6188,7 +6321,9 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
 
 static tree
 cp_parser_binary_expression (cp_parser* parser, bool cast_p,
-                            enum cp_parser_prec prec)
+                            bool no_toplevel_fold_p,
+                            enum cp_parser_prec prec,
+                            cp_id_kind * pidk)
 {
   cp_parser_expression_stack stack;
   cp_parser_expression_stack_entry *sp = &stack[0];
@@ -6199,7 +6334,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
   bool overloaded_p;
 
   /* Parse the first expression.  */
-  lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p);
+  lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
   lhs_type = ERROR_MARK;
 
   for (;;)
@@ -6211,11 +6346,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);
@@ -6241,6 +6376,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);
@@ -6269,6 +6411,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
          goto get_rhs;
 
         pop:
+         lookahead_prec = new_prec;
          /* If the stack is not empty, we have parsed into LHS the right side
             (`4' in the example above) of an expression we had suspended.
             We can use the information on the stack to recover the LHS (`3')
@@ -6285,6 +6428,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.
@@ -6293,8 +6442,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
         pass the correct tree_code unless the unary expression was
         surrounded by parentheses.
       */
-      lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
-                              &overloaded_p, tf_warning_or_error);
+      if (no_toplevel_fold_p
+         && lookahead_prec <= prec
+         && sp == stack
+         && TREE_CODE_CLASS (tree_type) == tcc_comparison)
+       lhs = build2 (tree_type, boolean_type_node, lhs, rhs);
+      else
+       lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
+                                &overloaded_p, tf_warning_or_error);
       lhs_type = tree_type;
 
       /* If the binary operator required the use of an overloaded operator,
@@ -6336,16 +6491,26 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
   cp_lexer_consume_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;
+    {
+      /* Implicit true clause.  */
+      expr = NULL_TREE;
+      c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
+    }
   else
-    /* Parse the expression.  */
-    expr = cp_parser_expression (parser, /*cast_p=*/false);
+    {
+      /* 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, "%<:%>");
   /* Parse the assignment-expression.  */
-  assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+  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,
@@ -6366,7 +6531,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
    Returns a representation for the expression.  */
 
 static tree
-cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
+                                cp_id_kind * pidk)
 {
   tree expr;
 
@@ -6379,7 +6545,8 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
   else
     {
       /* Parse the binary expressions (logical-or-expression).  */
-      expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR);
+      expr = cp_parser_binary_expression (parser, cast_p, false,
+                                         PREC_NOT_OPERATOR, pidk);
       /* If the next token is a `?' then we're actually looking at a
         conditional-expression.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
@@ -6400,7 +6567,7 @@ 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.  */
@@ -6514,7 +6681,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
    Returns a representation of the expression.  */
 
 static tree
-cp_parser_expression (cp_parser* parser, bool cast_p)
+cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
 {
   tree expression = NULL_TREE;
 
@@ -6524,7 +6691,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p)
 
       /* Parse the next assignment-expression.  */
       assignment_expression
-       = cp_parser_assignment_expression (parser, cast_p);
+       = cp_parser_assignment_expression (parser, cast_p, pidk);
       /* If this is the first assignment-expression, we can just
         save it away.  */
       if (!expression)
@@ -6603,7 +6770,7 @@ cp_parser_constant_expression (cp_parser* parser,
      For example, cp_parser_initializer_clauses uses this function to
      determine whether a particular assignment-expression is in fact
      constant.  */
-  expression = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+  expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
   /* Restore the old settings.  */
   parser->integral_constant_expression_p
     = saved_integral_constant_expression_p;
@@ -6627,7 +6794,8 @@ cp_parser_constant_expression (cp_parser* parser,
    offsetof-member-designator:
      id-expression
      | offsetof-member-designator "." id-expression
-     | offsetof-member-designator "[" expression "]"  */
+     | offsetof-member-designator "[" expression "]"
+     | offsetof-member-designator "->" id-expression  */
 
 static tree
 cp_parser_builtin_offsetof (cp_parser *parser)
@@ -6670,11 +6838,16 @@ cp_parser_builtin_offsetof (cp_parser *parser)
          expr = cp_parser_postfix_open_square_expression (parser, expr, true);
          break;
 
+       case CPP_DEREF:
+         /* offsetof-member-designator "->" identifier */
+         expr = grok_array_decl (expr, integer_zero_node);
+         /* FALLTHRU */
+
        case CPP_DOT:
          /* offsetof-member-designator "." identifier */
          cp_lexer_consume_token (parser->lexer);
-         expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr,
-                                                        true, &dummy,
+         expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
+                                                        expr, true, &dummy,
                                                         token->location);
          break;
 
@@ -6770,6 +6943,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;
@@ -6820,6 +6999,528 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
   return finish_trait_expr (kind, type1, type2);
 }
 
+/* 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;
+
+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
+record_lambda_scope (tree lambda)
+{
+  LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
+  LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
+}
+
+static void
+finish_lambda_scope (void)
+{
+  tree_int *p = VEC_last (tree_int, lambda_scope_stack);
+  if (lambda_scope != p->t)
+    {
+      lambda_scope = p->t;
+      lambda_count = p->i;
+    }
+  VEC_pop (tree_int, lambda_scope_stack);
+}
+
+/* Parse a lambda expression.
+
+   lambda-expression:
+     lambda-introducer lambda-declarator [opt] compound-statement
+
+   Returns a representation of the expression.  */
+
+static tree
+cp_parser_lambda_expression (cp_parser* parser)
+{
+  tree lambda_expr = build_lambda_expr ();
+  tree type;
+
+  LAMBDA_EXPR_LOCATION (lambda_expr)
+    = cp_lexer_peek_token (parser->lexer)->location;
+
+  /* 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, "%<[%>");
+
+  /* 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, "%<,%>");
+
+      /* 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, "%<]%>");
+}
+
+/* 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, "%<)%>");
+
+      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 = TREE_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 = TYPE_UNQUALIFIED;
+    if (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) == NULL_TREE
+       && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
+      {
+       /* A lambda with no captures has a static op() and a conversion op
+          to function type.  */
+       if (LAMBDA_EXPR_MUTABLE_P (lambda_expr))
+         error ("lambda expression with no captures declared mutable");
+       return_type_specs.storage_class = sc_static;
+      }
+    else if (!LAMBDA_EXPR_MUTABLE_P (lambda_expr))
+      quals = TYPE_QUAL_CONST;
+    declarator = make_call_declarator (declarator, param_list, quals,
+                                      exception_spec,
+                                       /*late_return_type=*/NULL_TREE);
+
+    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, "%<{%>");
+       cp_parser_require_keyword (parser, RID_RETURN, "%<return%>");
+
+       expr = cp_parser_expression (parser, /*cast_p=*/false, &idk);
+
+       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
+       cp_parser_require (parser, CPP_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.
@@ -6995,6 +7696,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);
@@ -7035,10 +7737,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;
 
@@ -7047,19 +7750,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, "%<:%>");
+
+  /* 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.
@@ -7076,11 +7801,31 @@ 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);
+    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);
@@ -7167,7 +7912,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%>");
            }
        }
 
@@ -7246,7 +7991,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 "
@@ -7269,10 +8014,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
@@ -7295,10 +8042,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.  */
@@ -7362,9 +8108,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;
@@ -7425,7 +8172,7 @@ cp_parser_condition (cp_parser* parser)
              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);
@@ -7448,7 +8195,7 @@ cp_parser_condition (cp_parser* parser)
     cp_parser_abort_tentative_parse (parser);
 
   /* Otherwise, we are looking at an expression.  */
-  return cp_parser_expression (parser, /*cast_p=*/false);
+  return cp_parser_expression (parser, /*cast_p=*/false, NULL);
 }
 
 /* Parse an iteration-statement.
@@ -7520,7 +8267,7 @@ cp_parser_iteration_statement (cp_parser* parser)
        /* Look for the `('.  */
        cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
        /* Parse the expression.  */
-       expression = cp_parser_expression (parser, /*cast_p=*/false);
+       expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
        /* We're done with the do-statement.  */
        finish_do_stmt (expression, statement);
        /* Look for the `)'.  */
@@ -7552,7 +8299,7 @@ cp_parser_iteration_statement (cp_parser* 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);
+         expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
        finish_for_expr (expression, statement);
        /* Look for the `)'.  */
        cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
@@ -7605,7 +8352,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.
@@ -7646,7 +8393,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)
@@ -7654,10 +8401,10 @@ 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, "%<;%>");
@@ -7667,14 +8414,14 @@ cp_parser_jump_statement (cp_parser* parser)
       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 ();
@@ -7689,11 +8436,11 @@ 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))
-         expr = cp_parser_expression (parser, /*cast_p=*/false);
+         expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
        else
          /* If the next token is a `;', then there is no
             expression.  */
@@ -7714,7 +8461,7 @@ cp_parser_jump_statement (cp_parser* parser)
          /* Consume the '*' token.  */
          cp_lexer_consume_token (parser->lexer);
          /* Parse the dependent expression.  */
-         finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false));
+         finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false, NULL));
        }
       else
        finish_goto_stmt (cp_parser_identifier (parser));
@@ -7780,8 +8527,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))
@@ -7817,6 +8565,10 @@ 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, "%<{%>");
+      /* 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, "%<}%>");
     }
@@ -8071,7 +8823,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))
@@ -8144,7 +8896,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
@@ -8208,8 +8960,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
@@ -8344,11 +9097,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
@@ -8359,6 +9113,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
@@ -8402,10 +9161,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,
@@ -8504,6 +9261,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;
            }
        }
 
@@ -8523,8 +9282,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.
@@ -8593,7 +9352,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;
@@ -8759,7 +9518,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.  */
@@ -8770,7 +9529,10 @@ 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, "%<(%>"))
@@ -8851,7 +9613,7 @@ cp_parser_decltype (cp_parser *parser)
       /* Parse a class member access.  */
       expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
                                            /*cast_p=*/false,
-                                           /*member_access_only_p=*/true);
+                                           /*member_access_only_p=*/true, NULL);
 
       if (expr 
           && expr != error_mark_node
@@ -8865,16 +9627,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);
+      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.  */
@@ -8978,7 +9754,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)
@@ -9080,8 +9857,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 base initializers");
 
   /* Loop through the list.  */
   while (true)
@@ -9102,8 +9879,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;
             }
 
@@ -9161,7 +9939,11 @@ cp_parser_mem_initializer (cp_parser* parser)
       mem_initializer_id = NULL_TREE;
     }
   else
-    mem_initializer_id = cp_parser_mem_initializer_id (parser);
+    {
+      mem_initializer_id = cp_parser_mem_initializer_id (parser);
+      if (mem_initializer_id == error_mark_node)
+       return mem_initializer_id;
+    }
   member = expand_member_init (mem_initializer_id);
   if (member && !DECL_P (member))
     in_base_initializer = 1;
@@ -9169,17 +9951,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, false,
+                                                    /*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)
@@ -9213,9 +10002,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.  */
@@ -9250,7 +10039,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);
@@ -9585,14 +10374,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);
@@ -9741,11 +10533,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);
@@ -9753,7 +10546,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;
@@ -9839,11 +10632,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 ();
@@ -9859,14 +10654,13 @@ 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, "%<<%>");
        /* 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, "%<>%>");
        /* Look for the `class' keyword.  */
@@ -9945,13 +10739,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 ();
@@ -10000,7 +10794,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
@@ -10048,7 +10842,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,
@@ -10173,8 +10966,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 ();
@@ -10280,7 +11072,7 @@ cp_parser_template_name (cp_parser* parser,
          && !template_keyword_p
          && parser->scope && TYPE_P (parser->scope)
          && check_dependency_p
-         && dependent_type_p (parser->scope)
+         && dependent_scope_p (parser->scope)
          /* Do not do this for dtors (or ctors), since they never
             need the template keyword before their name.  */
          && !constructor_name_p (identifier, parser->scope))
@@ -10288,9 +11080,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))
@@ -10330,12 +11122,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)
@@ -10420,6 +11211,12 @@ cp_parser_template_argument_list (cp_parser* parser)
          argument pack. */
       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
         {
+         if (argument == error_mark_node)
+           {
+             cp_token *token = cp_lexer_peek_token (parser->lexer);
+             error_at (token->location,
+                       "expected parameter pack before %<...%>");
+           }
           /* Consume the `...' token. */
           cp_lexer_consume_token (parser->lexer);
 
@@ -10454,6 +11251,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;
 }
 
@@ -10494,7 +11294,7 @@ cp_parser_template_argument (cp_parser* parser)
 
      Therefore, we try a type-id first.  */
   cp_parser_parse_tentatively (parser);
-  argument = cp_parser_type_id (parser);
+  argument = cp_parser_template_type_arg (parser);
   /* If there was no error parsing the type-id but the next token is a
      '>>', our behavior depends on which dialect of C++ we're
      parsing. In C++98, we probably found a typo for '> >'. But there
@@ -10616,18 +11416,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))
@@ -10682,7 +11490,7 @@ cp_parser_template_argument (cp_parser* parser)
      was the only alternative that matched (albeit with a '>' after
      it). We can assume it's just a typo from the user, and a
      diagnostic will then be issued.  */
-  return cp_parser_type_id (parser);
+  return cp_parser_template_type_arg (parser);
 }
 
 /* Parse an explicit-instantiation.
@@ -10713,7 +11521,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.  */
@@ -10736,7 +11543,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,
@@ -10827,7 +11633,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);
@@ -10839,7 +11645,6 @@ cp_parser_explicit_specialization (cp_parser* parser)
   if (!begin_specialization ())
     {
       end_specialization ();
-      cp_parser_skip_to_end_of_block_or_statement (parser);
       return;
     }
 
@@ -10932,6 +11737,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.  */
@@ -10954,11 +11762,15 @@ 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);
       /* Look for the class-specifier.  */
       type_spec = cp_parser_class_specifier (parser);
+      invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec);
       /* If that worked, we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
@@ -11149,7 +11961,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;
 
@@ -11187,8 +11999,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
@@ -11203,7 +12013,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
@@ -11440,6 +12250,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.  */
@@ -11455,7 +12266,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);
@@ -11471,9 +12282,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
@@ -11486,10 +12294,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,
@@ -11537,7 +12345,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
        type = make_typename_type (parser->scope, decl,
                                   typename_type,
                                   /*complain=*/tf_error);
-      else
+      /* If the `typename' keyword is in effect and DECL is not a type
+        decl. Then type is non existant.   */
+      else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
+        type = NULL_TREE; 
+      else 
        type = TREE_TYPE (decl);
     }
 
@@ -11708,7 +12520,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
             there were no qualifying templates.  */
          if (!cp_parser_check_template_parameters (parser,
                                                    /*num_templates=*/0,
-                                                   token->location))
+                                                   token->location,
+                                                   /*declarator=*/NULL))
            return error_mark_node;
          type = xref_tag (tag_type, identifier, ts, template_p);
        }
@@ -11790,7 +12603,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);
@@ -11805,27 +12618,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)
         {
@@ -11877,6 +12692,7 @@ cp_parser_enum_specifier (cp_parser* parser)
   if (cp_parser_allow_gnu_extensions_p (parser))
     {
       tree trailing_attr = cp_parser_attributes_opt (parser);
+      trailing_attr = chainon (trailing_attr, attributes);
       cplus_decl_attributes (&type,
                             trailing_attr,
                             (int) ATTR_FLAG_TYPE_IN_PLACE);
@@ -11953,6 +12769,11 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
   else
     value = NULL_TREE;
 
+  /* If we are processing a template, make sure the initializer of the
+     enumerator doesn't contain any bare template parameter pack.  */
+  if (check_for_bare_parameter_packs (value))
+    value = error_mark_node;
+
   /* Create the enumerator.  */
   build_enumerator (identifier, value, type);
 }
@@ -12008,7 +12829,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;
     }
@@ -12092,7 +12913,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
 #ifdef HANDLE_PRAGMA_VISIBILITY
   if (has_visibility)
-    pop_visibility ();
+    pop_visibility (1);
 #endif
 
   /* Finish the namespace.  */
@@ -12135,7 +12956,7 @@ 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))
@@ -12275,8 +13096,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 ())
@@ -12362,7 +13183,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)
@@ -12371,11 +13195,14 @@ 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;
+  const char *missing = NULL;
 
   /* Look for the `asm' keyword.  */
   cp_parser_require_keyword (parser, RID_ASM, "%<asm%>");
@@ -12388,6 +13215,15 @@ 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, "%<(%>"))
     return;
@@ -12412,6 +13248,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;
@@ -12427,7 +13264,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)
@@ -12449,6 +13287,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);
 
@@ -12463,16 +13303,41 @@ 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 ? "%<:%>" : "%<:%> or %<::%>";
     }
+  else if (goto_p)
+    missing = "%<:%> or %<::%>";
+
   /* 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 : "%<)%>"))
     cp_parser_skip_to_closing_parenthesis (parser, true, false,
                                           /*consume_paren=*/true);
   cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
@@ -12483,7 +13348,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)
            {
@@ -12612,6 +13477,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))
@@ -12652,12 +13522,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;
 
@@ -12809,8 +13679,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,
@@ -12818,9 +13688,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
@@ -12924,7 +13806,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;
@@ -12939,9 +13820,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.  */
@@ -13229,10 +14107,16 @@ cp_parser_direct_declarator (cp_parser* parser,
                 in function scopes.  */
              else if (!parser->in_function_body)
                {
-                 error ("%Harray bound is not an integer constant",
-                        &token->location);
+                 error_at (token->location,
+                           "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;
@@ -13247,181 +14131,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");
+           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;
+                 }
+             }
 
-         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)
+             return NULL;
+           if (unqualified_name == error_mark_node)
+             {
+               declarator = cp_error_declarator;
+               pack_expansion_p = false;
+               declarator->parameter_pack_p = false;
+               break;
+             }
 
-         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 (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;
+             }
 
-             /* 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;
-           }
+           sfk = sfk_none;
 
-         sfk = sfk_none;
+           if (unqualified_name)
+             {
+               tree class_type;
 
-         if (unqualified_name)
-           {
-             tree class_type;
+               if (qualifying_scope
+                   && CLASS_TYPE_P (qualifying_scope))
+                 class_type = qualifying_scope;
+               else
+                 class_type = current_class_type;
 
-             if (qualifying_scope
-                 && CLASS_TYPE_P (qualifying_scope))
-               class_type = qualifying_scope;
-             else
-               class_type = current_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_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 (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
+               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);
-                   }
-                 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 (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 (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 ();
+                   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);
@@ -13543,7 +14441,7 @@ cp_parser_ptr_operator (cp_parser* parser,
          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
@@ -13618,7 +14516,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
@@ -13634,7 +14532,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.  */
 
@@ -13652,7 +14550,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.
@@ -13705,13 +14603,15 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p)
    Returns the TYPE specified.  */
 
 static tree
-cp_parser_type_id (cp_parser* parser)
+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;
@@ -13730,11 +14630,36 @@ cp_parser_type_id (cp_parser* parser)
   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);
+  return groktypename (&type_specifier_seq, abstract_declarator,
+                      is_template_arg);
+}
+
+static tree cp_parser_type_id (cp_parser *parser)
+{
+  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, 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.
@@ -13747,14 +14672,18 @@ cp_parser_type_id (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;
@@ -13764,6 +14693,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)
     {
@@ -13823,7 +14758,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;
     }
 
@@ -13934,6 +14869,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;
@@ -13985,6 +14921,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);
@@ -14072,7 +15014,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;
@@ -14087,18 +15028,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))
@@ -14202,7 +15147,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;
@@ -14304,7 +15250,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;
 
@@ -14353,9 +15299,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;
            }
        }
@@ -14363,20 +15309,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;
        }
@@ -14408,21 +15357,13 @@ 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);
   default_argument
-    = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+    = 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;
 
@@ -14500,13 +15441,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, false,
+                                                    /*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;
     }
@@ -14791,14 +15739,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;
            }
        }
@@ -14866,13 +15808,12 @@ cp_parser_class_name (cp_parser *parser,
 static tree
 cp_parser_class_specifier (cp_parser* parser)
 {
-  cp_token *token;
   tree type;
   tree attributes = NULL_TREE;
-  int has_trailing_semicolon;
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
   bool saved_in_function_body;
+  bool saved_in_unbraced_linkage_specification_p;
   tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
   tree bases;
@@ -14924,6 +15865,10 @@ cp_parser_class_specifier (cp_parser* parser)
   /* We are not in a function body.  */
   saved_in_function_body = parser->in_function_body;
   parser->in_function_body = false;
+  /* We are not immediately inside an extern "lang" block.  */
+  saved_in_unbraced_linkage_specification_p
+    = parser->in_unbraced_linkage_specification_p;
+  parser->in_unbraced_linkage_specification_p = false;
 
   /* Start the class.  */
   if (nested_name_specifier_p)
@@ -14942,10 +15887,6 @@ cp_parser_class_specifier (cp_parser* parser)
 
   /* Look for the trailing `}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
-  /* We get better error messages by noticing a common problem: a
-     missing trailing `;'.  */
-  token = cp_lexer_peek_token (parser->lexer);
-  has_trailing_semicolon = (token->type == CPP_SEMICOLON);
   /* Look for trailing attributes to apply to this class.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
@@ -15036,6 +15977,8 @@ cp_parser_class_specifier (cp_parser* parser)
   parser->in_function_body = saved_in_function_body;
   parser->num_template_parameter_lists
     = saved_num_template_parameter_lists;
+  parser->in_unbraced_linkage_specification_p
+    = saved_in_unbraced_linkage_specification_p;
 
   return type;
 }
@@ -15256,8 +16199,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;
        }
@@ -15269,14 +16213,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;
        }
@@ -15288,8 +16232,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;
        }
@@ -15300,8 +16244,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.  */
@@ -15314,7 +16258,8 @@ cp_parser_class_head (cp_parser* parser,
   /* Make sure that the right number of template parameters were
      present.  */
   if (!cp_parser_check_template_parameters (parser, num_templates,
-                                           type_start_token->location))
+                                           type_start_token->location,
+                                           /*declarator=*/NULL))
     {
       /* If something went wrong, there is no point in even trying to
         process the class-definition.  */
@@ -15329,8 +16274,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
@@ -15411,10 +16356,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;
     }
@@ -15643,7 +16588,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
@@ -15681,8 +16626,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 {
@@ -15696,8 +16641,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);
@@ -15715,7 +16661,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);
            }
@@ -15876,8 +16823,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,
@@ -15959,13 +16906,19 @@ cp_parser_pure_specifier (cp_parser* parser)
   if (!cp_parser_require (parser, CPP_EQ, "%<=%>"))
     return error_mark_node;
   /* Look for the `0' token.  */
-  token = cp_lexer_consume_token (parser->lexer);
+  token = cp_lexer_peek_token (parser->lexer);
+
+  if (token->type == CPP_EOF
+      || token->type == CPP_PRAGMA_EOL)
+    return error_mark_node;
+
+  cp_lexer_consume_token (parser->lexer);
 
   /* Accept = default or = delete in c++0x mode.  */
   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;
     }
 
@@ -15979,7 +16932,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;
     }
 
@@ -16183,12 +17136,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);
     }
 
@@ -16269,7 +17222,7 @@ cp_parser_exception_specification_opt (cp_parser* parser)
       /* 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.  */
@@ -16450,10 +17403,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))
@@ -16499,7 +17453,7 @@ cp_parser_throw_expression (cp_parser* parser)
     expression = NULL_TREE;
   else
     expression = cp_parser_assignment_expression (parser,
-                                                 /*cast_p=*/false);
+                                                 /*cast_p=*/false, NULL);
 
   return build_throw (expression);
 }
@@ -16591,7 +17545,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
       /* Look for the `('.  */
       cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
       /* Parse the expression.  */
-      expression = cp_parser_expression (parser, /*cast_p=*/false);
+      expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
       /* Look for the `)'.  */
       cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
 
@@ -16648,6 +17602,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:
@@ -16744,7 +17741,12 @@ cp_parser_attribute_list (cp_parser* parser)
 
          /* Save away the identifier that indicates which attribute
             this is.  */
-         identifier = token->u.value;
+         identifier = (token->type == CPP_KEYWORD) 
+           /* For keywords, use the canonical spelling, not the
+              parsed identifier.  */
+           ? ridpointers[(int) token->keyword]
+           : token->u.value;
+         
          attribute = build_tree_list (identifier, NULL_TREE);
 
          /* Peek at the next token.  */
@@ -16752,10 +17754,18 @@ 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;
+             vec = cp_parser_parenthesized_expression_list
+                   (parser, true, /*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;
            }
@@ -16966,35 +17976,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
         cannot look up the name if the scope is not a class type; it
         might, for example, be a template type parameter.  */
       dependent_p = (TYPE_P (parser->scope)
-                    && !(parser->in_declarator_p
-                         && currently_open_class (parser->scope))
-                    && dependent_type_p (parser->scope));
+                    && dependent_scope_p (parser->scope));
       if ((check_dependency || !CLASS_TYPE_P (parser->scope))
-          && dependent_p)
-       {
-         if (tag_type)
-           {
-             tree type;
-
-             /* The resolution to Core Issue 180 says that `struct
-                A::B' should be considered a type-name, even if `A'
-                is dependent.  */
-             type = make_typename_type (parser->scope, name, tag_type,
-                                        /*complain=*/tf_error);
-             decl = TYPE_NAME (type);
-           }
-         else if (is_template
-                  && (cp_parser_next_token_ends_template_argument_p (parser)
-                      || cp_lexer_next_token_is (parser->lexer,
-                                                 CPP_CLOSE_PAREN)))
-           decl = make_unbound_class_template (parser->scope,
-                                               name, NULL_TREE,
-                                               /*complain=*/tf_error);
-         else
-           decl = build_qualified_name (/*type=*/NULL_TREE,
-                                        parser->scope, name,
-                                        is_template);
-       }
+         && dependent_p)
+       /* Defer lookup.  */
+       decl = error_mark_node;
       else
        {
          tree pushed_scope = NULL_TREE;
@@ -17006,6 +17992,26 @@ 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);
+
+         /* 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
+             && CLASS_TYPE_P (parser->scope)
+             && constructor_name_p (name, parser->scope))
+           name = ctor_identifier;
+
          /* 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
@@ -17015,14 +18021,42 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
                                        /*complain=*/true);
 
          /* If we have a single function from a using decl, pull it out.  */
-         if (decl
-             && TREE_CODE (decl) == OVERLOAD
+         if (TREE_CODE (decl) == OVERLOAD
              && !really_overloaded_fn (decl))
            decl = OVL_FUNCTION (decl);
 
          if (pushed_scope)
            pop_scope (pushed_scope);
        }
+
+      /* If the scope is a dependent type and either we deferred lookup or
+        we did lookup but didn't find the name, rememeber the name.  */
+      if (decl == error_mark_node && TYPE_P (parser->scope)
+         && dependent_type_p (parser->scope))
+       {
+         if (tag_type)
+           {
+             tree type;
+
+             /* The resolution to Core Issue 180 says that `struct
+                A::B' should be considered a type-name, even if `A'
+                is dependent.  */
+             type = make_typename_type (parser->scope, name, tag_type,
+                                        /*complain=*/tf_error);
+             decl = TYPE_NAME (type);
+           }
+         else if (is_template
+                  && (cp_parser_next_token_ends_template_argument_p (parser)
+                      || cp_lexer_next_token_is (parser->lexer,
+                                                 CPP_CLOSE_PAREN)))
+           decl = make_unbound_class_template (parser->scope,
+                                               name, NULL_TREE,
+                                               /*complain=*/tf_error);
+         else
+           decl = build_qualified_name (/*type=*/NULL_TREE,
+                                        parser->scope, name,
+                                        is_template);
+       }
       parser->qualifying_scope = parser->scope;
       parser->object_scope = NULL_TREE;
     }
@@ -17062,6 +18096,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)
     {
@@ -17071,8 +18109,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;
@@ -17177,10 +18215,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))
            {
@@ -17213,9 +18249,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
           additional level of template parameters.  */
        ++num_templates;
 
-      return cp_parser_check_template_parameters (parser,
-                                                 num_templates,
-                                                 declarator_location);
+      return cp_parser_check_template_parameters 
+       (parser, num_templates, declarator_location, declarator);
+
 
     case cdk_function:
     case cdk_array:
@@ -17236,35 +18272,47 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
 
 /* NUM_TEMPLATES were used in the current declaration.  If that is
    invalid, return FALSE and issue an error messages.  Otherwise,
-   return TRUE.  */
+   return TRUE.  If DECLARATOR is non-NULL, then we are checking a
+   declarator and we can print more accurate diagnostics.  */
 
 static bool
 cp_parser_check_template_parameters (cp_parser* parser,
                                     unsigned num_templates,
-                                    location_t location)
+                                    location_t location,
+                                    cp_declarator *declarator)
 {
+  /* If there are the same number of template classes and parameter
+     lists, that's OK.  */
+  if (parser->num_template_parameter_lists == num_templates)
+    return true;
+  /* If there are more, but only one more, then we are referring to a
+     member template.  That's OK too.  */
+  if (parser->num_template_parameter_lists == num_templates + 1)
+    return true;
   /* If there are more template classes than parameter lists, we have
      something like:
 
        template <class T> void S<T>::R<T>::f ();  */
   if (parser->num_template_parameter_lists < num_templates)
     {
-      error ("%Htoo few template-parameter-lists", &location);
+      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;
     }
-  /* If there are the same number of template classes and parameter
-     lists, that's OK.  */
-  if (parser->num_template_parameter_lists == num_templates)
-    return true;
-  /* If there are more, but only one more, then we are referring to a
-     member template.  That's OK too.  */
-  if (parser->num_template_parameter_lists == num_templates + 1)
-      return true;
   /* Otherwise, there are too many template parameter lists.  We have
      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;
 }
 
@@ -17313,8 +18361,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
@@ -17340,34 +18387,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 ();
-
-        we must recognize that the nested `S' names a class.
-        Similarly, for:
+          template <typename T> struct S {
+            S();
+          };
 
-          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,
@@ -17377,22 +18438,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, "%<(%>"))
+       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
@@ -17447,8 +18509,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);
 
@@ -17509,7 +18570,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.  */
 
@@ -17538,8 +18599,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)
        {
@@ -17561,6 +18622,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))
@@ -17571,6 +18635,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));
@@ -17613,8 +18679,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
       /* 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;
     }
@@ -17623,7 +18689,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);
@@ -17770,8 +18836,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;
     }
 
@@ -17809,6 +18875,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
@@ -17834,8 +18905,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;
       }
     }
@@ -17862,7 +18933,7 @@ static tree
 cp_parser_simple_cast_expression (cp_parser *parser)
 {
   return cp_parser_cast_expression (parser, /*address_p=*/false,
-                                   /*cast_p=*/false);
+                                   /*cast_p=*/false, NULL);
 }
 
 /* Parse a functional cast to TYPE.  Returns an expression
@@ -17871,13 +18942,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)
@@ -17885,11 +18957,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, false,
+                                                /*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);
@@ -17921,8 +19000,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)
     {
@@ -17970,9 +19049,6 @@ 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,
@@ -17993,7 +19069,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]
 
@@ -18010,8 +19087,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))
@@ -18052,9 +19131,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;
        }
@@ -18065,8 +19143,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
@@ -18078,7 +19157,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;
 }
@@ -18189,7 +19269,7 @@ 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
@@ -18203,9 +19283,11 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
   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 = TREE_CHAIN (parmdecl))
     {
       cp_token_cache *tokens;
       tree default_arg = TREE_PURPOSE (parm);
@@ -18227,8 +19309,15 @@ 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);
+      parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+      if (parsed_arg == error_mark_node)
+       {
+         cp_parser_pop_lexer (parser);
+         continue;
+       }
 
       if (!processing_template_decl)
        parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
@@ -18240,6 +19329,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.  */
@@ -18307,7 +19398,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))
@@ -18349,14 +19441,15 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
      looking at the unary-expression production.  */
   if (!expr)
     expr = cp_parser_unary_expression (parser, /*address_p=*/false,
-                                      /*cast_p=*/false);
+                                      /*cast_p=*/false, NULL);
 
   if (pack_expansion_p)
     /* Build a pack expansion. */
     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);
@@ -18394,8 +19487,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)
@@ -18407,7 +19500,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;
     }
 
@@ -18749,7 +19842,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.
@@ -18767,8 +19860,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.  */
@@ -19033,8 +20127,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);
     }
 
@@ -19077,7 +20172,7 @@ cp_parser_objc_message_receiver (cp_parser* parser)
   /* An Objective-C message receiver may be either (1) a type
      or (2) an expression.  */
   cp_parser_parse_tentatively (parser);
-  rcv = cp_parser_expression (parser, false);
+  rcv = cp_parser_expression (parser, false, NULL);
 
   if (cp_parser_parse_definitely (parser))
     return rcv;
@@ -19129,7 +20224,7 @@ cp_parser_objc_message_args (cp_parser* parser)
 
       maybe_unary_selector_p = false;
       cp_parser_require (parser, CPP_COLON, "%<:%>");
-      arg = cp_parser_assignment_expression (parser, false);
+      arg = cp_parser_assignment_expression (parser, false, NULL);
 
       sel_args
        = chainon (sel_args,
@@ -19144,7 +20239,7 @@ cp_parser_objc_message_args (cp_parser* parser)
       tree arg;
 
       cp_lexer_consume_token (parser->lexer);
-      arg = cp_parser_assignment_expression (parser, false);
+      arg = cp_parser_assignment_expression (parser, false, NULL);
 
       addl_args
        = chainon (addl_args,
@@ -19177,8 +20272,8 @@ cp_parser_objc_encode_expression (cp_parser* parser)
 
   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;
     }
 
@@ -19241,6 +20336,7 @@ 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, "%<(%>");
@@ -19292,7 +20388,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
  finish_selector:
   cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
 
-  return objc_build_selector_expr (sel_seq);
+  return objc_build_selector_expr (loc, sel_seq);
 }
 
 /* Parse a list of identifiers.
@@ -19493,7 +20589,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;
     }
 
@@ -19824,7 +20920,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;
     }
 
@@ -19960,8 +21056,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);
     }
 }
@@ -20044,7 +21140,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
 
   location = cp_lexer_peek_token (parser->lexer)->location;
   cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
-  lock = cp_parser_expression (parser, false);
+  lock = cp_parser_expression (parser, false, NULL);
   cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
 
   /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
@@ -20065,15 +21161,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%>");
 
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-    expr = cp_parser_assignment_expression (parser, false);
+    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.  */
@@ -20092,8 +21189,8 @@ 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);
     }
 
@@ -20185,7 +21282,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;
       }
 }
@@ -20227,7 +21324,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
        cp_parser_name_lookup_error (parser, name, decl, 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;
@@ -20299,13 +21396,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;
 
@@ -20363,7 +21459,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;
 
@@ -20391,7 +21487,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
 
   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;
 
@@ -20409,7 +21505,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;
 }
@@ -20426,7 +21522,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
     return list;
 
-  t = cp_parser_expression (parser, false);
+  t = cp_parser_expression (parser, false, NULL);
 
   if (t == error_mark_node
       || !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
@@ -20437,7 +21533,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;
 
@@ -20456,7 +21552,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;
 }
@@ -20538,7 +21634,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
   if (!cp_parser_require (parser, CPP_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))
     {
@@ -20583,16 +21679,16 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
       cp_lexer_consume_token (parser->lexer);
 
       token = cp_lexer_peek_token (parser->lexer);
-      t = cp_parser_assignment_expression (parser, false);
+      t = cp_parser_assignment_expression (parser, false, NULL);
 
       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;
 
@@ -20626,7 +21722,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;
 }
@@ -20739,7 +21835,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:
@@ -20812,7 +21908,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
   lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
-                                   /*cast_p=*/false);
+                                   /*cast_p=*/false, NULL);
   switch (TREE_CODE (lhs))
     {
     case ERROR_MARK:
@@ -20869,7 +21965,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
        }
       cp_lexer_consume_token (parser->lexer);
 
-      rhs = cp_parser_expression (parser, false);
+      rhs = cp_parser_expression (parser, false, NULL);
       if (rhs == error_mark_node)
        goto saw_error;
       break;
@@ -20919,7 +22015,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:
@@ -20932,7 +22028,7 @@ static void
 cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
 {
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
-    (void) cp_parser_omp_var_list (parser, 0, NULL);
+    (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
   finish_omp_flush ();
@@ -20943,41 +22039,39 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
 static tree
 cp_parser_omp_for_cond (cp_parser *parser, tree decl)
 {
-  tree lhs = cp_parser_cast_expression (parser, false, false), rhs;
-  enum tree_code op;
-  cp_token *token;
+  tree cond = cp_parser_binary_expression (parser, false, true,
+                                          PREC_NOT_OPERATOR, NULL);
+  bool overloaded_p;
 
-  if (lhs != decl)
+  if (cond == error_mark_node
+      || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     {
       cp_parser_skip_to_end_of_statement (parser);
       return error_mark_node;
     }
 
-  token = cp_lexer_peek_token (parser->lexer);
-  op = binops_by_token [token->type].tree_type;
-  switch (op)
+  switch (TREE_CODE (cond))
     {
-    case LT_EXPR:
-    case LE_EXPR:
     case GT_EXPR:
     case GE_EXPR:
+    case LT_EXPR:
+    case LE_EXPR:
       break;
     default:
-      cp_parser_skip_to_end_of_statement (parser);
       return error_mark_node;
     }
 
-  cp_lexer_consume_token (parser->lexer);
-  rhs = cp_parser_binary_expression (parser, false,
-                                    PREC_RELATIONAL_EXPRESSION);
-  if (rhs == error_mark_node
-      || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-    {
-      cp_parser_skip_to_end_of_statement (parser);
-      return error_mark_node;
-    }
+  /* If decl is an iterator, preserve LHS and RHS of the relational
+     expr until finish_omp_for.  */
+  if (decl
+      && (type_dependent_expression_p (decl)
+         || CLASS_TYPE_P (TREE_TYPE (decl))))
+    return cond;
 
-  return build2 (op, boolean_type_node, lhs, rhs);
+  return build_x_binary_op (TREE_CODE (cond),
+                           TREE_OPERAND (cond, 0), ERROR_MARK,
+                           TREE_OPERAND (cond, 1), ERROR_MARK,
+                           &overloaded_p, tf_warning_or_error);
 }
 
 /* Helper function, to parse omp for increment expression.  */
@@ -20996,7 +22090,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
       op = (token->type == CPP_PLUS_PLUS
            ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
       cp_lexer_consume_token (parser->lexer);
-      lhs = cp_parser_cast_expression (parser, false, false);
+      lhs = cp_parser_cast_expression (parser, false, false, NULL);
       if (lhs != decl)
        return error_mark_node;
       return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
@@ -21021,13 +22115,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
 
   if (op != NOP_EXPR)
     {
-      rhs = cp_parser_assignment_expression (parser, false);
+      rhs = cp_parser_assignment_expression (parser, false, NULL);
       rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
       return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
     }
 
-  lhs = cp_parser_binary_expression (parser, false,
-                                    PREC_ADDITIVE_EXPRESSION);
+  lhs = cp_parser_binary_expression (parser, false, false,
+                                    PREC_ADDITIVE_EXPRESSION, NULL);
   token = cp_lexer_peek_token (parser->lexer);
   decl_first = lhs == decl;
   if (decl_first)
@@ -21040,8 +22134,8 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
     {
       op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
       cp_lexer_consume_token (parser->lexer);
-      rhs = cp_parser_binary_expression (parser, false,
-                                        PREC_ADDITIVE_EXPRESSION);
+      rhs = cp_parser_binary_expression (parser, false, false,
+                                        PREC_ADDITIVE_EXPRESSION, NULL);
       token = cp_lexer_peek_token (parser->lexer);
       if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
        {
@@ -21130,7 +22224,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))
            {
@@ -21211,7 +22306,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                    {
                      /* Consume '='.  */
                      cp_lexer_consume_token (parser->lexer);
-                     init = cp_parser_assignment_expression (parser, false);
+                     init = cp_parser_assignment_expression (parser, false, NULL);
 
                    non_class:
                      if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
@@ -21244,7 +22339,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
 
                  cp_parser_parse_definitely (parser);
                  cp_parser_require (parser, CPP_EQ, "%<=%>");
-                 rhs = cp_parser_assignment_expression (parser, false);
+                 rhs = cp_parser_assignment_expression (parser, false, NULL);
                  finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR,
                                                         rhs,
                                                         tf_warning_or_error));
@@ -21254,7 +22349,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                {
                  decl = NULL;
                  cp_parser_abort_tentative_parse (parser);
-                 init = cp_parser_expression (parser, false);
+                 init = cp_parser_expression (parser, false, NULL);
                  if (init)
                    {
                      if (TREE_CODE (init) == MODIFY_EXPR
@@ -21289,8 +22384,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
@@ -21298,7 +22393,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);
@@ -21327,16 +22422,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)
@@ -21349,16 +22445,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))
-       {
-         /* If decl is an iterator, preserve LHS and RHS of the relational
-            expr until finish_omp_for.  */
-         if (decl
-             && (type_dependent_expression_p (decl)
-                 || CLASS_TYPE_P (TREE_TYPE (decl))))
-           cond = cp_parser_omp_for_cond (parser, decl);
-         else
-           cond = cp_parser_condition (parser);
-       }
+       cond = cp_parser_omp_for_cond (parser, decl);
       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
 
       incr = NULL;
@@ -21371,7 +22458,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                  || CLASS_TYPE_P (TREE_TYPE (decl))))
            incr = cp_parser_omp_for_incr (parser, decl);
          else
-           incr = cp_parser_expression (parser, false);
+           incr = cp_parser_expression (parser, false, NULL);
        }
 
       if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
@@ -21407,7 +22494,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;
@@ -21452,12 +22539,13 @@ 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;
        }
     }
 
@@ -21512,7 +22600,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:
@@ -21522,8 +22611,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:
@@ -21658,6 +22748,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))
     {
@@ -21693,12 +22784,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;
@@ -21784,7 +22875,7 @@ cp_parser_omp_threadprivate (cp_parser *parser, cp_token *pragma_tok)
 {
   tree vars;
 
-  vars = cp_parser_omp_var_list (parser, 0, NULL);
+  vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
   finish_omp_threadprivate (vars);
@@ -21864,11 +22955,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)
@@ -21901,8 +22992,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:
@@ -21912,8 +23003,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;
@@ -21927,8 +23018,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;
@@ -21942,9 +23033,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;
@@ -21970,8 +23061,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:
@@ -22023,7 +23115,6 @@ pragma_lex (tree *value)
 void
 c_parse_file (void)
 {
-  bool error_occurred;
   static bool already_called = false;
 
   if (already_called)
@@ -22036,7 +23127,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;
 }