OSDN Git Service

PR c++/51027 - accepts alias-declaration without ';'
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index c63d5b3..1376a3a 100644 (file)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "timevar.h"
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
@@ -37,6 +38,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-common.h"
 #include "c-family/c-objc.h"
 #include "plugin.h"
+#include "tree-pretty-print.h"
+#include "parser.h"
 
 \f
 /* The lexer.  */
@@ -44,110 +47,11 @@ along with GCC; see the file COPYING3.  If not see
 /* The cp_lexer_* routines mediate between the lexer proper (in libcpp
    and c-lex.c) and the C++ parser.  */
 
-/* A token's value and its associated deferred access checks and
-   qualifying scope.  */
-
-struct GTY(()) tree_check {
-  /* The value associated with the token.  */
-  tree value;
-  /* The checks that have been associated with value.  */
-  VEC (deferred_access_check, gc)* checks;
-  /* The token's qualifying scope (used when it is a
-     CPP_NESTED_NAME_SPECIFIER).  */
-  tree qualifying_scope;
-};
-
-/* A C++ token.  */
-
-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.
-     Otherwise, this value is RID_MAX.  */
-  ENUM_BITFIELD (rid) keyword : 8;
-  /* Token flags.  */
-  unsigned char flags;
-  /* Identifier for the pragma.  */
-  ENUM_BITFIELD (pragma_kind) pragma_kind : 6;
-  /* True if this token is from a context where it is implicitly extern "C" */
-  BOOL_BITFIELD implicit_extern_c : 1;
-  /* True for a CPP_NAME token that is not a keyword (i.e., for which
-     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.  */
-    struct tree_check* GTY((tag ("1"))) tree_check_value;
-    /* Use for all other tokens.  */
-    tree GTY((tag ("0"))) value;
-  } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
-} cp_token;
-
-/* We use a stack of token pointer for saving token sets.  */
-typedef struct cp_token *cp_token_position;
-DEF_VEC_P (cp_token_position);
-DEF_VEC_ALLOC_P (cp_token_position,heap);
-
 static cp_token eof_token =
 {
-  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, 0, { NULL }
+  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, false, false, 0, { NULL }
 };
 
-/* The cp_lexer structure represents the C++ lexer.  It is responsible
-   for managing the token stream from the preprocessor and supplying
-   it to the parser.  Tokens are never added to the cp_lexer after
-   it is created.  */
-
-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;
-  /* If the lexer owns the buffer, this is the number of tokens in the
-     buffer.  */
-  size_t buffer_length;
-
-  /* A pointer just past the last available token.  The tokens
-     in this lexer are [buffer, last_token).  */
-  cp_token_position GTY ((skip)) last_token;
-
-  /* The next available token.  If NEXT_TOKEN is &eof_token, then there are
-     no more available tokens.  */
-  cp_token_position GTY ((skip)) next_token;
-
-  /* A stack indicating positions at which cp_lexer_save_tokens was
-     called.  The top entry is the most recent position at which we
-     began saving tokens.  If the stack is non-empty, we are saving
-     tokens.  */
-  VEC(cp_token_position,heap) *GTY ((skip)) saved_tokens;
-
-  /* The next lexer in a linked list of lexers.  */
-  struct cp_lexer *next;
-
-  /* True if we should output debugging information.  */
-  bool debugging_p;
-
-  /* True if we're in the context of parsing a pragma, and should not
-     increment past the end-of-line marker.  */
-  bool in_pragma;
-} cp_lexer;
-
-/* cp_token_cache is a range of tokens.  There is no need to represent
-   allocate heap memory for it, since tokens are never removed from the
-   lexer's array.  There is also no need for the GC to walk through
-   a cp_token_cache, since everything in here is referenced through
-   a lexer.  */
-
-typedef struct GTY(()) cp_token_cache {
-  /* The beginning of the token range.  */
-  cp_token * GTY((skip)) first;
-
-  /* Points immediately after the last token in the range.  */
-  cp_token * GTY ((skip)) last;
-} cp_token_cache;
-
 /* The various kinds of non integral constant we encounter. */
 typedef enum non_integral_constant {
   NIC_NONE,
@@ -202,7 +106,9 @@ typedef enum non_integral_constant {
   /* a comma operator */
   NIC_COMMA,
   /* a call to a constructor */
-  NIC_CONSTRUCTOR
+  NIC_CONSTRUCTOR,
+  /* a transaction expression */
+  NIC_TRANSACTION
 } non_integral_constant;
 
 /* The various kinds of errors about name-lookup failing. */
@@ -267,7 +173,10 @@ typedef enum required_token {
   RT_INTERATION, /* iteration-statement */
   RT_JUMP, /* jump-statement */
   RT_CLASS_KEY, /* class-key */
-  RT_CLASS_TYPENAME_TEMPLATE /* class, typename, or template */
+  RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */
+  RT_TRANSACTION_ATOMIC, /* __transaction_atomic */
+  RT_TRANSACTION_RELAXED, /* __transaction_relaxed */
+  RT_TRANSACTION_CANCEL /* __transaction_cancel */
 } required_token;
 
 /* Prototypes.  */
@@ -280,8 +189,6 @@ static void cp_lexer_destroy
   (cp_lexer *);
 static int cp_lexer_saving_tokens
   (const cp_lexer *);
-static cp_token_position cp_lexer_token_position
-  (cp_lexer *, bool);
 static cp_token *cp_lexer_token_at
   (cp_lexer *, cp_token_position);
 static void cp_lexer_get_preprocessor_token
@@ -308,7 +215,6 @@ static void cp_lexer_commit_tokens
   (cp_lexer *);
 static void cp_lexer_rollback_tokens
   (cp_lexer *);
-#ifdef ENABLE_CHECKING
 static void cp_lexer_print_token
   (FILE *, cp_token *);
 static inline bool cp_lexer_debugging_p
@@ -317,15 +223,6 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-#else
-/* If we define cp_lexer_debug_stream to NULL it will provoke warnings
-   about passing NULL to functions that require non-NULL arguments
-   (fputs, fprintf).  It will never be used, so all we need is a value
-   of the right type that's guaranteed not to be NULL.  */
-#define cp_lexer_debug_stream stdout
-#define cp_lexer_print_token(str, tok) (void) 0
-#define cp_lexer_debugging_p(lexer) 0
-#endif /* ENABLE_CHECKING */
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
@@ -333,107 +230,389 @@ static cp_token_cache *cp_token_cache_new
 static void cp_parser_initial_pragma
   (cp_token *);
 
+static tree cp_literal_operator_id
+  (const char *);
+
 /* Manifest constants.  */
 #define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
 #define CP_SAVED_TOKEN_STACK 5
 
-/* A token type for keywords, as opposed to ordinary identifiers.  */
-#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
-
-/* A token type for template-ids.  If a template-id is processed while
-   parsing tentatively, it is replaced with a CPP_TEMPLATE_ID token;
-   the value of the CPP_TEMPLATE_ID is whatever was returned by
-   cp_parser_template_id.  */
-#define CPP_TEMPLATE_ID ((enum cpp_ttype) (CPP_KEYWORD + 1))
-
-/* A token type for nested-name-specifiers.  If a
-   nested-name-specifier is processed while parsing tentatively, it is
-   replaced with a CPP_NESTED_NAME_SPECIFIER token; the value of the
-   CPP_NESTED_NAME_SPECIFIER is whatever was returned by
-   cp_parser_nested_name_specifier_opt.  */
-#define CPP_NESTED_NAME_SPECIFIER ((enum cpp_ttype) (CPP_TEMPLATE_ID + 1))
-
-/* A token type for tokens that are not tokens at all; these are used
-   to represent slots in the array where there used to be a token
-   that has now been deleted.  */
-#define CPP_PURGED ((enum cpp_ttype) (CPP_NESTED_NAME_SPECIFIER + 1))
-
-/* The number of token types, including C++-specific ones.  */
-#define N_CP_TTYPES ((int) (CPP_PURGED + 1))
-
 /* Variables.  */
 
-#ifdef ENABLE_CHECKING
 /* The stream to which debugging output should be written.  */
 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.  */
+/* Dump up to NUM tokens in BUFFER to FILE starting with token
+   START_TOKEN.  If START_TOKEN is NULL, the dump starts with the
+   first token in BUFFER.  If NUM is 0, dump all the tokens.  If
+   CURR_TOKEN is set and it is one of the tokens in BUFFER, it will be
+   highlighted by surrounding it in [[ ]].  */
+
+static void
+cp_lexer_dump_tokens (FILE *file, VEC(cp_token,gc) *buffer,
+                     cp_token *start_token, unsigned num,
+                     cp_token *curr_token)
+{
+  unsigned i, nprinted;
+  cp_token *token;
+  bool do_print;
+
+  fprintf (file, "%u tokens\n", VEC_length (cp_token, buffer));
+
+  if (buffer == NULL)
+    return;
+
+  if (num == 0)
+    num = VEC_length (cp_token, buffer);
+
+  if (start_token == NULL)
+    start_token = VEC_address (cp_token, buffer);
+
+  if (start_token > VEC_address (cp_token, buffer))
+    {
+      cp_lexer_print_token (file, VEC_index (cp_token, buffer, 0));
+      fprintf (file, " ... ");
+    }
+
+  do_print = false;
+  nprinted = 0;
+  for (i = 0; VEC_iterate (cp_token, buffer, i, token) && nprinted < num; i++)
+    {
+      if (token == start_token)
+       do_print = true;
+
+      if (!do_print)
+       continue;
+
+      nprinted++;
+      if (token == curr_token)
+       fprintf (file, "[[");
+
+      cp_lexer_print_token (file, token);
+
+      if (token == curr_token)
+       fprintf (file, "]]");
+
+      switch (token->type)
+       {
+         case CPP_SEMICOLON:
+         case CPP_OPEN_BRACE:
+         case CPP_CLOSE_BRACE:
+         case CPP_EOF:
+           fputc ('\n', file);
+           break;
+
+         default:
+           fputc (' ', file);
+       }
+    }
+
+  if (i == num && i < VEC_length (cp_token, buffer))
+    {
+      fprintf (file, " ... ");
+      cp_lexer_print_token (file, VEC_index (cp_token, buffer,
+                           VEC_length (cp_token, buffer) - 1));
+    }
+
+  fprintf (file, "\n");
+}
+
+
+/* Dump all tokens in BUFFER to stderr.  */
+
+void
+cp_lexer_debug_tokens (VEC(cp_token,gc) *buffer)
+{
+  cp_lexer_dump_tokens (stderr, buffer, NULL, 0, NULL);
+}
+
+
+/* Dump the cp_parser tree field T to FILE if T is non-NULL.  DESC is the
+   description for T.  */
+
+static void
+cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t)
+{
+  if (t)
+    {
+      fprintf (file, "%s: ", desc);
+      print_node_brief (file, "", t, 0);
+    }
+}
+
+
+/* Dump parser context C to FILE.  */
+
+static void
+cp_debug_print_context (FILE *file, cp_parser_context *c)
+{
+  const char *status_s[] = { "OK", "ERROR", "COMMITTED" };
+  fprintf (file, "{ status = %s, scope = ", status_s[c->status]);
+  print_node_brief (file, "", c->object_type, 0);
+  fprintf (file, "}\n");
+}
+
+
+/* Print the stack of parsing contexts to FILE starting with FIRST.  */
+
+static void
+cp_debug_print_context_stack (FILE *file, cp_parser_context *first)
+{
+  unsigned i;
+  cp_parser_context *c;
+
+  fprintf (file, "Parsing context stack:\n");
+  for (i = 0, c = first; c; c = c->next, i++)
+    {
+      fprintf (file, "\t#%u: ", i);
+      cp_debug_print_context (file, c);
+    }
+}
+
+
+/* Print the value of FLAG to FILE.  DESC is a string describing the flag.  */
+
+static void
+cp_debug_print_flag (FILE *file, const char *desc, bool flag)
+{
+  if (flag)
+    fprintf (file, "%s: true\n", desc);
+}
+
+
+/* Print an unparsed function entry UF to FILE.  */
+
+static void
+cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf)
+{
+  unsigned i;
+  cp_default_arg_entry *default_arg_fn;
+  tree fn;
+
+  fprintf (file, "\tFunctions with default args:\n");
+  for (i = 0;
+       VEC_iterate (cp_default_arg_entry, uf->funs_with_default_args, i,
+                   default_arg_fn);
+       i++)
+    {
+      fprintf (file, "\t\tClass type: ");
+      print_node_brief (file, "", default_arg_fn->class_type, 0);
+      fprintf (file, "\t\tDeclaration: ");
+      print_node_brief (file, "", default_arg_fn->decl, 0);
+      fprintf (file, "\n");
+    }
+
+  fprintf (file, "\n\tFunctions with definitions that require "
+          "post-processing\n\t\t");
+  for (i = 0; VEC_iterate (tree, uf->funs_with_definitions, i, fn); i++)
+    {
+      print_node_brief (file, "", fn, 0);
+      fprintf (file, " ");
+    }
+  fprintf (file, "\n");
+
+  fprintf (file, "\n\tNon-static data members with initializers that require "
+           "post-processing\n\t\t");
+  for (i = 0; VEC_iterate (tree, uf->nsdmis, i, fn); i++)
+    {
+      print_node_brief (file, "", fn, 0);
+      fprintf (file, " ");
+    }
+  fprintf (file, "\n");
+}
+
+
+/* Print the stack of unparsed member functions S to FILE.  */
+
+static void
+cp_debug_print_unparsed_queues (FILE *file,
+                               VEC(cp_unparsed_functions_entry, gc) *s)
+{
+  unsigned i;
+  cp_unparsed_functions_entry *uf;
+
+  fprintf (file, "Unparsed functions\n");
+  for (i = 0; VEC_iterate (cp_unparsed_functions_entry, s, i, uf); i++)
+    {
+      fprintf (file, "#%u:\n", i);
+      cp_debug_print_unparsed_function (file, uf);
+    }
+}
+
+
+/* Dump the tokens in a window of size WINDOW_SIZE around the next_token for
+   the given PARSER.  If FILE is NULL, the output is printed on stderr. */
+
+static void
+cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size)
+{
+  cp_token *next_token, *first_token, *start_token;
+
+  if (file == NULL)
+    file = stderr;
+
+  next_token = parser->lexer->next_token;
+  first_token = VEC_address (cp_token, parser->lexer->buffer);
+  start_token = (next_token > first_token + window_size / 2)
+               ? next_token - window_size / 2
+               : first_token;
+  cp_lexer_dump_tokens (file, parser->lexer->buffer, start_token, window_size,
+                       next_token);
+}
+
+
+/* Dump debugging information for the given PARSER.  If FILE is NULL,
+   the output is printed on stderr.  */
+
+void
+cp_debug_parser (FILE *file, cp_parser *parser)
+{
+  const size_t window_size = 20;
+  cp_token *token;
+  expanded_location eloc;
+
+  if (file == NULL)
+    file = stderr;
+
+  fprintf (file, "Parser state\n\n");
+  fprintf (file, "Number of tokens: %u\n",
+          VEC_length (cp_token, parser->lexer->buffer));
+  cp_debug_print_tree_if_set (file, "Lookup scope", parser->scope);
+  cp_debug_print_tree_if_set (file, "Object scope",
+                                    parser->object_scope);
+  cp_debug_print_tree_if_set (file, "Qualifying scope",
+                                    parser->qualifying_scope);
+  cp_debug_print_context_stack (file, parser->context);
+  cp_debug_print_flag (file, "Allow GNU extensions",
+                             parser->allow_gnu_extensions_p);
+  cp_debug_print_flag (file, "'>' token is greater-than",
+                             parser->greater_than_is_operator_p);
+  cp_debug_print_flag (file, "Default args allowed in current "
+                             "parameter list", parser->default_arg_ok_p);
+  cp_debug_print_flag (file, "Parsing integral constant-expression",
+                             parser->integral_constant_expression_p);
+  cp_debug_print_flag (file, "Allow non-constant expression in current "
+                             "constant-expression",
+                             parser->allow_non_integral_constant_expression_p);
+  cp_debug_print_flag (file, "Seen non-constant expression",
+                             parser->non_integral_constant_expression_p);
+  cp_debug_print_flag (file, "Local names and 'this' forbidden in "
+                             "current context",
+                             parser->local_variables_forbidden_p);
+  cp_debug_print_flag (file, "In unbraced linkage specification",
+                             parser->in_unbraced_linkage_specification_p);
+  cp_debug_print_flag (file, "Parsing a declarator",
+                             parser->in_declarator_p);
+  cp_debug_print_flag (file, "In template argument list",
+                             parser->in_template_argument_list_p);
+  cp_debug_print_flag (file, "Parsing an iteration statement",
+                             parser->in_statement & IN_ITERATION_STMT);
+  cp_debug_print_flag (file, "Parsing a switch statement",
+                             parser->in_statement & IN_SWITCH_STMT);
+  cp_debug_print_flag (file, "Parsing a structured OpenMP block",
+                             parser->in_statement & IN_OMP_BLOCK);
+  cp_debug_print_flag (file, "Parsing a an OpenMP loop",
+                             parser->in_statement & IN_OMP_FOR);
+  cp_debug_print_flag (file, "Parsing an if statement",
+                             parser->in_statement & IN_IF_STMT);
+  cp_debug_print_flag (file, "Parsing a type-id in an expression "
+                             "context", parser->in_type_id_in_expr_p);
+  cp_debug_print_flag (file, "Declarations are implicitly extern \"C\"",
+                             parser->implicit_extern_c);
+  cp_debug_print_flag (file, "String expressions should be translated "
+                             "to execution character set",
+                             parser->translate_strings_p);
+  cp_debug_print_flag (file, "Parsing function body outside of a "
+                             "local class", parser->in_function_body);
+  cp_debug_print_flag (file, "Auto correct a colon to a scope operator",
+                             parser->colon_corrects_to_scope_p);
+  if (parser->type_definition_forbidden_message)
+    fprintf (file, "Error message for forbidden type definitions: %s\n",
+            parser->type_definition_forbidden_message);
+  cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
+  fprintf (file, "Number of class definitions in progress: %u\n",
+          parser->num_classes_being_defined);
+  fprintf (file, "Number of template parameter lists for the current "
+          "declaration: %u\n", parser->num_template_parameter_lists);
+  cp_debug_parser_tokens (file, parser, window_size);
+  token = parser->lexer->next_token;
+  fprintf (file, "Next token to parse:\n");
+  fprintf (file, "\tToken:  ");
+  cp_lexer_print_token (file, token);
+  eloc = expand_location (token->location);
+  fprintf (file, "\n\tFile:   %s\n", eloc.file);
+  fprintf (file, "\tLine:   %d\n", eloc.line);
+  fprintf (file, "\tColumn: %d\n", eloc.column);
+}
+
+
+/* Allocate memory for a new lexer object and return it.  */
 
 static cp_lexer *
-cp_lexer_new_main (void)
+cp_lexer_alloc (void)
 {
-  cp_token first_token;
   cp_lexer *lexer;
-  cp_token *pos;
-  size_t alloc;
-  size_t space;
-  cp_token *buffer;
-
-  /* It's possible that parsing the first pragma will load a PCH file,
-     which is a GC collection point.  So we have to do that before
-     allocating any memory.  */
-  cp_parser_initial_pragma (&first_token);
 
   c_common_no_more_pch ();
 
   /* Allocate the memory.  */
   lexer = ggc_alloc_cleared_cp_lexer ();
 
-#ifdef ENABLE_CHECKING
   /* Initially we are not debugging.  */
   lexer->debugging_p = false;
-#endif /* ENABLE_CHECKING */
+
   lexer->saved_tokens = VEC_alloc (cp_token_position, heap,
                                   CP_SAVED_TOKEN_STACK);
 
   /* Create the buffer.  */
-  alloc = CP_LEXER_BUFFER_SIZE;
-  buffer = ggc_alloc_vec_cp_token (alloc);
+  lexer->buffer = VEC_alloc (cp_token, gc, CP_LEXER_BUFFER_SIZE);
+
+  return lexer;
+}
+
+
+/* Create a new main C++ lexer, the lexer that gets tokens from the
+   preprocessor.  */
+
+static cp_lexer *
+cp_lexer_new_main (void)
+{
+  cp_lexer *lexer;
+  cp_token token;
+
+  /* It's possible that parsing the first pragma will load a PCH file,
+     which is a GC collection point.  So we have to do that before
+     allocating any memory.  */
+  cp_parser_initial_pragma (&token);
+
+  lexer = cp_lexer_alloc ();
 
   /* Put the first token in the buffer.  */
-  space = alloc;
-  pos = buffer;
-  *pos = first_token;
+  VEC_quick_push (cp_token, lexer->buffer, &token);
 
   /* Get the remaining tokens from the preprocessor.  */
-  while (pos->type != CPP_EOF)
+  while (token.type != CPP_EOF)
     {
-      pos++;
-      if (!--space)
-       {
-         space = alloc;
-         alloc *= 2;
-         buffer = GGC_RESIZEVEC (cp_token, buffer, alloc);
-         pos = buffer + space;
-       }
-      cp_lexer_get_preprocessor_token (lexer, pos);
+      cp_lexer_get_preprocessor_token (lexer, &token);
+      VEC_safe_push (cp_token, gc, lexer->buffer, &token);
     }
-  lexer->buffer = buffer;
-  lexer->buffer_length = alloc - space;
-  lexer->last_token = pos;
-  lexer->next_token = lexer->buffer_length ? buffer : &eof_token;
+
+  lexer->last_token = VEC_address (cp_token, lexer->buffer)
+                      + VEC_length (cp_token, lexer->buffer)
+                     - 1;
+  lexer->next_token = VEC_length (cp_token, lexer->buffer)
+                     ? VEC_address (cp_token, lexer->buffer)
+                     : &eof_token;
 
   /* Subsequent preprocessor diagnostics should use compiler
      diagnostic functions to get the compiler source location.  */
   done_lexing = true;
 
-  gcc_assert (lexer->next_token->type != CPP_PURGED);
+  gcc_assert (!lexer->next_token->purged_p);
   return lexer;
 }
 
@@ -449,19 +628,16 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
 
   /* We do not own the buffer.  */
   lexer->buffer = NULL;
-  lexer->buffer_length = 0;
   lexer->next_token = first == last ? &eof_token : first;
   lexer->last_token = last;
 
   lexer->saved_tokens = VEC_alloc (cp_token_position, heap,
                                   CP_SAVED_TOKEN_STACK);
 
-#ifdef ENABLE_CHECKING
   /* Initially we are not debugging.  */
   lexer->debugging_p = false;
-#endif
 
-  gcc_assert (lexer->next_token->type != CPP_PURGED);
+  gcc_assert (!lexer->next_token->purged_p);
   return lexer;
 }
 
@@ -470,23 +646,19 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
 static void
 cp_lexer_destroy (cp_lexer *lexer)
 {
-  if (lexer->buffer)
-    ggc_free (lexer->buffer);
+  VEC_free (cp_token, gc, lexer->buffer);
   VEC_free (cp_token_position, heap, lexer->saved_tokens);
   ggc_free (lexer);
 }
 
 /* Returns nonzero if debugging information should be output.  */
 
-#ifdef ENABLE_CHECKING
-
 static inline bool
 cp_lexer_debugging_p (cp_lexer *lexer)
 {
   return lexer->debugging_p;
 }
 
-#endif /* ENABLE_CHECKING */
 
 static inline cp_token_position
 cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
@@ -549,6 +721,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
                        lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN);
   token->keyword = RID_MAX;
   token->pragma_kind = PRAGMA_NONE;
+  token->purged_p = false;
 
   /* On some systems, some header files are surrounded by an
      implicit extern "C" block.  Set a flag in the token if it
@@ -576,7 +749,7 @@ 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 %qE will become a keyword in C++0x",
+                       "identifier %qE is a keyword in C++11",
                        token->u.value);
 
               /* Clear out the C_RID_CODE so we don't warn about this
@@ -723,6 +896,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
     case RID_TYPEOF:
       /* C++0x extensions.  */
     case RID_DECLTYPE:
+    case RID_UNDERLYING_TYPE:
       return true;
 
     default:
@@ -730,6 +904,24 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
     }
 }
 
+/* Returns TRUE iff the token T begins a decltype type.  */
+
+static bool
+token_is_decltype (cp_token *t)
+{
+  return (t->keyword == RID_DECLTYPE
+         || t->type == CPP_DECLTYPE);
+}
+
+/* Returns TRUE iff the next token begins a decltype type.  */
+
+static bool
+cp_lexer_next_token_is_decltype (cp_lexer *lexer)
+{
+  cp_token *t = cp_lexer_peek_token (lexer);
+  return token_is_decltype (t);
+}
+
 /* Return a pointer to the Nth token in the token stream.  If N is 1,
    then this is precisely equivalent to cp_lexer_peek_token (except
    that it is not inline).  One would like to disallow that case, but
@@ -760,7 +952,7 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
          break;
        }
 
-      if (token->type != CPP_PURGED)
+      if (!token->purged_p)
        --n;
     }
 
@@ -794,7 +986,7 @@ cp_lexer_consume_token (cp_lexer* lexer)
        }
 
     }
-  while (lexer->next_token->type == CPP_PURGED);
+  while (lexer->next_token->purged_p);
 
   cp_lexer_set_source_position_from_token (token);
 
@@ -819,7 +1011,7 @@ cp_lexer_purge_token (cp_lexer *lexer)
   cp_token *tok = lexer->next_token;
 
   gcc_assert (tok != &eof_token);
-  tok->type = CPP_PURGED;
+  tok->purged_p = true;
   tok->location = UNKNOWN_LOCATION;
   tok->u.value = NULL_TREE;
   tok->keyword = RID_MAX;
@@ -833,7 +1025,7 @@ cp_lexer_purge_token (cp_lexer *lexer)
          break;
        }
     }
-  while (tok->type == CPP_PURGED);
+  while (tok->purged_p);
   lexer->next_token = tok;
 }
 
@@ -853,7 +1045,7 @@ cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
 
   for ( tok += 1; tok != peek; tok += 1)
     {
-      tok->type = CPP_PURGED;
+      tok->purged_p = true;
       tok->location = UNKNOWN_LOCATION;
       tok->u.value = NULL_TREE;
       tok->keyword = RID_MAX;
@@ -901,8 +1093,6 @@ cp_lexer_rollback_tokens (cp_lexer* lexer)
 
 /* Print a representation of the TOKEN on the STREAM.  */
 
-#ifdef ENABLE_CHECKING
-
 static void
 cp_lexer_print_token (FILE * stream, cp_token *token)
 {
@@ -919,14 +1109,8 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
     "KEYWORD",
     "TEMPLATE_ID",
     "NESTED_NAME_SPECIFIER",
-    "PURGED"
   };
 
-  /* If we have a name for the token, print it out.  Otherwise, we
-     simply give the numeric code.  */
-  gcc_assert (token->type < ARRAY_SIZE(token_names));
-  fputs (token_names[token->type], stream);
-
   /* For some tokens, print the associated data.  */
   switch (token->type)
     {
@@ -948,7 +1132,17 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
       fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
       break;
 
+    case CPP_NUMBER:
+      print_generic_expr (stream, token->u.value, 0);
+      break;
+
     default:
+      /* If we have a name for the token, print it out.  Otherwise, we
+        simply give the numeric code.  */
+      if (token->type < ARRAY_SIZE(token_names))
+       fputs (token_names[token->type], stream);
+      else
+       fprintf (stream, "[%d]", token->type);
       break;
     }
 }
@@ -959,6 +1153,7 @@ static void
 cp_lexer_start_debugging (cp_lexer* lexer)
 {
   lexer->debugging_p = true;
+  cp_lexer_debug_stream = stderr;
 }
 
 /* Stop emitting debugging information.  */
@@ -967,10 +1162,9 @@ static void
 cp_lexer_stop_debugging (cp_lexer* lexer)
 {
   lexer->debugging_p = false;
+  cp_lexer_debug_stream = NULL;
 }
 
-#endif /* ENABLE_CHECKING */
-
 /* Create a new cp_token_cache, representing a range of tokens.  */
 
 static cp_token_cache *
@@ -1001,7 +1195,7 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
    VAR_DECLs or FUNCTION_DECLs) should do that directly.  */
 
 static cp_declarator *make_call_declarator
-  (cp_declarator *, tree, cp_cv_quals, tree, tree);
+  (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, tree, tree);
 static cp_declarator *make_array_declarator
   (cp_declarator *, tree);
 static cp_declarator *make_pointer_declarator
@@ -1166,6 +1360,7 @@ cp_declarator *
 make_call_declarator (cp_declarator *target,
                      tree parms,
                      cp_cv_quals cv_qualifiers,
+                     cp_virt_specifiers virt_specifiers,
                      tree exception_specification,
                      tree late_return_type)
 {
@@ -1175,6 +1370,7 @@ make_call_declarator (cp_declarator *target,
   declarator->declarator = target;
   declarator->u.function.parameters = parms;
   declarator->u.function.qualifiers = cv_qualifiers;
+  declarator->u.function.virt_specifiers = virt_specifiers;
   declarator->u.function.exception_specification = exception_specification;
   declarator->u.function.late_return_type = late_return_type;
   if (target)
@@ -1413,19 +1609,6 @@ typedef struct cp_parser_binary_operations_map_node
   enum cp_parser_prec prec;
 } cp_parser_binary_operations_map_node;
 
-/* The status of a tentative parse.  */
-
-typedef enum cp_parser_status_kind
-{
-  /* No errors have occurred.  */
-  CP_PARSER_STATUS_KIND_NO_ERROR,
-  /* An error has occurred.  */
-  CP_PARSER_STATUS_KIND_ERROR,
-  /* We are committed to this tentative parse, whether or not an error
-     has occurred.  */
-  CP_PARSER_STATUS_KIND_COMMITTED
-} cp_parser_status_kind;
-
 typedef struct cp_parser_expression_stack_entry
 {
   /* Left hand side of the binary operation we are currently
@@ -1446,21 +1629,6 @@ typedef struct cp_parser_expression_stack_entry
 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 GTY (()) cp_parser_context {
-  /* If this is a tentative parsing context, the status of the
-     tentative parse.  */
-  enum cp_parser_status_kind status;
-  /* If non-NULL, we have just seen a `x->' or `x.' expression.  Names
-     that are looked up in this context must be looked up both in the
-     scope given by OBJECT_TYPE (the type of `x' or `*x') and also in
-     the context of the containing expression.  */
-  tree object_type;
-
-  /* The next parsing context in the stack.  */
-  struct cp_parser_context *next;
-} cp_parser_context;
-
 /* Prototypes.  */
 
 /* Constructors and destructors.  */
@@ -1551,183 +1719,14 @@ cp_parser_context_new (cp_parser_context* next)
   return context;
 }
 
-/* An entry in a queue of function arguments that require post-processing.  */
-
-typedef struct GTY(()) cp_default_arg_entry_d {
-  /* The current_class_type when we parsed this arg.  */
-  tree class_type;
-
-  /* The function decl itself.  */
-  tree decl;
-} cp_default_arg_entry;
-
-DEF_VEC_O(cp_default_arg_entry);
-DEF_VEC_ALLOC_O(cp_default_arg_entry,gc);
-
-/* An entry in a stack for member functions of local classes.  */
-
-typedef struct GTY(()) cp_unparsed_functions_entry_d {
-  /* Functions with default arguments that require post-processing.
-     Functions appear in this list in declaration order.  */
-  VEC(cp_default_arg_entry,gc) *funs_with_default_args;
-
-  /* Functions with defintions that require post-processing.  Functions
-     appear in this list in declaration order.  */
-  VEC(tree,gc) *funs_with_definitions;
-} cp_unparsed_functions_entry;
-
-DEF_VEC_O(cp_unparsed_functions_entry);
-DEF_VEC_ALLOC_O(cp_unparsed_functions_entry,gc);
-
-/* The cp_parser structure represents the C++ parser.  */
-
-typedef struct GTY(()) cp_parser {
-  /* The lexer from which we are obtaining tokens.  */
-  cp_lexer *lexer;
-
-  /* The scope in which names should be looked up.  If NULL_TREE, then
-     we look up names in the scope that is currently open in the
-     source program.  If non-NULL, this is either a TYPE or
-     NAMESPACE_DECL for the scope in which we should look.  It can
-     also be ERROR_MARK, when we've parsed a bogus scope.
-
-     This value is not cleared automatically after a name is looked
-     up, so we must be careful to clear it before starting a new look
-     up sequence.  (If it is not cleared, then `X::Y' followed by `Z'
-     will look up `Z' in the scope of `X', rather than the current
-     scope.)  Unfortunately, it is difficult to tell when name lookup
-     is complete, because we sometimes peek at a token, look it up,
-     and then decide not to consume it.   */
-  tree scope;
-
-  /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the
-     last lookup took place.  OBJECT_SCOPE is used if an expression
-     like "x->y" or "x.y" was used; it gives the type of "*x" or "x",
-     respectively.  QUALIFYING_SCOPE is used for an expression of the
-     form "X::Y"; it refers to X.  */
-  tree object_scope;
-  tree qualifying_scope;
-
-  /* A stack of parsing contexts.  All but the bottom entry on the
-     stack will be tentative contexts.
-
-     We parse tentatively in order to determine which construct is in
-     use in some situations.  For example, in order to determine
-     whether a statement is an expression-statement or a
-     declaration-statement we parse it tentatively as a
-     declaration-statement.  If that fails, we then reparse the same
-     token stream as an expression-statement.  */
-  cp_parser_context *context;
-
-  /* True if we are parsing GNU C++.  If this flag is not set, then
-     GNU extensions are not recognized.  */
-  bool allow_gnu_extensions_p;
-
-  /* TRUE if the `>' token should be interpreted as the greater-than
-     operator.  FALSE if it is the end of a template-id or
-     template-parameter-list. In C++0x mode, this flag also applies to
-     `>>' tokens, which are viewed as two consecutive `>' tokens when
-     this flag is FALSE.  */
-  bool greater_than_is_operator_p;
-
-  /* TRUE if default arguments are allowed within a parameter list
-     that starts at this point. FALSE if only a gnu extension makes
-     them permissible.  */
-  bool default_arg_ok_p;
-
-  /* TRUE if we are parsing an integral constant-expression.  See
-     [expr.const] for a precise definition.  */
-  bool integral_constant_expression_p;
-
-  /* TRUE if we are parsing an integral constant-expression -- but a
-     non-constant expression should be permitted as well.  This flag
-     is used when parsing an array bound so that GNU variable-length
-     arrays are tolerated.  */
-  bool allow_non_integral_constant_expression_p;
-
-  /* TRUE if ALLOW_NON_CONSTANT_EXPRESSION_P is TRUE and something has
-     been seen that makes the expression non-constant.  */
-  bool non_integral_constant_expression_p;
-
-  /* TRUE if local variable names and `this' are forbidden in the
-     current context.  */
-  bool local_variables_forbidden_p;
-
-  /* TRUE if the declaration we are parsing is part of a
-     linkage-specification of the form `extern string-literal
-     declaration'.  */
-  bool in_unbraced_linkage_specification_p;
-
-  /* TRUE if we are presently parsing a declarator, after the
-     direct-declarator.  */
-  bool in_declarator_p;
-
-  /* TRUE if we are presently parsing a template-argument-list.  */
-  bool in_template_argument_list_p;
-
-  /* Set to IN_ITERATION_STMT if parsing an iteration-statement,
-     to IN_OMP_BLOCK if parsing OpenMP structured block and
-     IN_OMP_FOR if parsing OpenMP loop.  If parsing a switch statement,
-     this is bitwise ORed with IN_SWITCH_STMT, unless parsing an
-     iteration-statement, OpenMP block or loop within that switch.  */
-#define IN_SWITCH_STMT         1
-#define IN_ITERATION_STMT      2
-#define IN_OMP_BLOCK           4
-#define IN_OMP_FOR             8
-#define IN_IF_STMT             16
-  unsigned char in_statement;
-
-  /* TRUE if we are presently parsing the body of a switch statement.
-     Note that this doesn't quite overlap with in_statement above.
-     The difference relates to giving the right sets of error messages:
-     "case not in switch" vs "break statement used with OpenMP...".  */
-  bool in_switch_statement_p;
-
-  /* TRUE if we are parsing a type-id in an expression context.  In
-     such a situation, both "type (expr)" and "type (type)" are valid
-     alternatives.  */
-  bool in_type_id_in_expr_p;
-
-  /* TRUE if we are currently in a header file where declarations are
-     implicitly extern "C".  */
-  bool implicit_extern_c;
-
-  /* TRUE if strings in expressions should be translated to the execution
-     character set.  */
-  bool translate_strings_p;
-
-  /* TRUE if we are presently parsing the body of a function, but not
-     a local class.  */
-  bool in_function_body;
-
-  /* TRUE if we can auto-correct a colon to a scope operator.  */
-  bool colon_corrects_to_scope_p;
-
-  /* If non-NULL, then we are parsing a construct where new type
-     definitions are not permitted.  The string stored here will be
-     issued as an error message if a type is defined.  */
-  const char *type_definition_forbidden_message;
-
-  /* A stack used for member functions of local classes.  The lists
-     contained in an individual entry can only be processed once the
-     outermost class being defined is complete.  */
-  VEC(cp_unparsed_functions_entry,gc) *unparsed_queues;
-
-  /* The number of classes whose definitions are currently in
-     progress.  */
-  unsigned num_classes_being_defined;
-
-  /* The number of template parameter lists that apply directly to the
-     current declaration.  */
-  unsigned num_template_parameter_lists;
-} cp_parser;
-
 /* Managing the unparsed function queues.  */
 
 #define unparsed_funs_with_default_args \
   VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args
 #define unparsed_funs_with_definitions \
   VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_definitions
+#define unparsed_nsdmis \
+  VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->nsdmis
 
 static void
 push_unparsed_function_queues (cp_parser *parser)
@@ -1736,6 +1735,7 @@ push_unparsed_function_queues (cp_parser *parser)
                 parser->unparsed_queues, NULL);
   unparsed_funs_with_default_args = NULL;
   unparsed_funs_with_definitions = make_tree_vector ();
+  unparsed_nsdmis = NULL;
 }
 
 static void
@@ -1770,6 +1770,12 @@ static tree cp_parser_identifier
   (cp_parser *);
 static tree cp_parser_string_literal
   (cp_parser *, bool, bool);
+static tree cp_parser_userdef_char_literal
+  (cp_parser *);
+static tree cp_parser_userdef_string_literal
+  (cp_token *);
+static tree cp_parser_userdef_numeric_literal
+  (cp_parser *);
 
 /* Basic concepts [gram.basic]  */
 
@@ -1840,7 +1846,7 @@ static tree cp_parser_lambda_expression
   (cp_parser *);
 static void cp_parser_lambda_introducer
   (cp_parser *, tree);
-static void cp_parser_lambda_declarator_opt
+static bool cp_parser_lambda_declarator_opt
   (cp_parser *, tree);
 static void cp_parser_lambda_body
   (cp_parser *, tree);
@@ -1854,7 +1860,7 @@ static void cp_parser_label_for_labeled_statement
 static tree cp_parser_expression_statement
   (cp_parser *, tree);
 static tree cp_parser_compound_statement
-  (cp_parser *, tree, bool);
+  (cp_parser *, tree, bool, bool);
 static void cp_parser_statement_seq_opt
   (cp_parser *, tree);
 static tree cp_parser_selection_statement
@@ -1871,6 +1877,12 @@ static tree cp_parser_c_for
   (cp_parser *, tree, tree);
 static tree cp_parser_range_for
   (cp_parser *, tree, tree, tree);
+static void do_range_for_auto_deduction
+  (tree, tree);
+static tree cp_parser_perform_range_for_lookup
+  (tree, tree *, tree *);
+static tree cp_parser_range_for_member_function
+  (tree, tree);
 static tree cp_parser_jump_statement
   (cp_parser *);
 static void cp_parser_declaration_statement
@@ -1928,6 +1940,8 @@ static bool cp_parser_using_declaration
   (cp_parser *, bool);
 static void cp_parser_using_directive
   (cp_parser *);
+static tree cp_parser_alias_declaration
+  (cp_parser *);
 static void cp_parser_asm_definition
   (cp_parser *);
 static void cp_parser_linkage_specification
@@ -1949,8 +1963,10 @@ static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, cp_cv_quals *);
 static cp_cv_quals cp_parser_cv_qualifier_seq_opt
   (cp_parser *);
-static tree cp_parser_late_return_type_opt
+static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
   (cp_parser *);
+static tree cp_parser_late_return_type_opt
+  (cp_parser *, cp_cv_quals);
 static tree cp_parser_declarator_id
   (cp_parser *, bool);
 static tree cp_parser_type_id
@@ -2095,6 +2111,17 @@ static bool cp_parser_extension_opt
 static void cp_parser_label_declaration
   (cp_parser *);
 
+/* Transactional Memory Extensions */
+
+static tree cp_parser_transaction
+  (cp_parser *, enum rid);
+static tree cp_parser_transaction_expression
+  (cp_parser *, enum rid);
+static bool cp_parser_function_transaction
+  (cp_parser *, enum rid);
+static tree cp_parser_transaction_cancel
+  (cp_parser *);
+
 enum pragma_context { pragma_external, pragma_stmt, pragma_compound };
 static bool cp_parser_pragma
   (cp_parser *, enum pragma_context);
@@ -2170,12 +2197,18 @@ static tree cp_parser_functional_cast
   (cp_parser *, tree);
 static tree cp_parser_save_member_function_body
   (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
+static tree cp_parser_save_nsdmi
+  (cp_parser *);
 static tree cp_parser_enclosed_template_argument_list
   (cp_parser *);
 static void cp_parser_save_default_args
   (cp_parser *, tree);
 static void cp_parser_late_parsing_for_member
   (cp_parser *, tree);
+static tree cp_parser_late_parse_one_default_arg
+  (cp_parser *, tree, tree, tree);
+static void cp_parser_late_parsing_nsdmi
+  (cp_parser *, tree);
 static void cp_parser_late_parsing_default_args
   (cp_parser *, tree);
 static tree cp_parser_sizeof_operand
@@ -2264,6 +2297,8 @@ static bool cp_parser_error_occurred
   (cp_parser *);
 static bool cp_parser_allow_gnu_extensions_p
   (cp_parser *);
+static bool cp_parser_is_pure_string_literal
+  (cp_token *);
 static bool cp_parser_is_string_literal
   (cp_token *);
 static bool cp_parser_is_keyword
@@ -2284,7 +2319,7 @@ cp_parser_parsing_tentatively (cp_parser* parser)
 /* Returns nonzero if TOKEN is a string literal.  */
 
 static bool
-cp_parser_is_string_literal (cp_token* token)
+cp_parser_is_pure_string_literal (cp_token* token)
 {
   return (token->type == CPP_STRING ||
          token->type == CPP_STRING16 ||
@@ -2293,6 +2328,20 @@ cp_parser_is_string_literal (cp_token* token)
          token->type == CPP_UTF8STRING);
 }
 
+/* Returns nonzero if TOKEN is a string literal
+   of a user-defined string literal.  */
+
+static bool
+cp_parser_is_string_literal (cp_token* token)
+{
+  return (cp_parser_is_pure_string_literal (token) ||
+         token->type == CPP_STRING_USERDEF ||
+         token->type == CPP_STRING16_USERDEF ||
+         token->type == CPP_STRING32_USERDEF ||
+         token->type == CPP_WSTRING_USERDEF ||
+         token->type == CPP_UTF8STRING_USERDEF);
+}
+
 /* Returns nonzero if TOKEN is the indicated KEYWORD.  */
 
 static bool
@@ -2478,6 +2527,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
            "explicit",
            "friend",
            "typedef",
+           "using",
             "constexpr",
            "__complex",
            "__thread"
@@ -2637,6 +2687,10 @@ cp_parser_non_integral_constant_expression (cp_parser  *parser,
                error ("a call to a constructor "
                       "cannot appear in a constant-expression");
                return true;
+             case NIC_TRANSACTION:
+               error ("a transaction expression "
+                      "cannot appear in a constant-expression");
+               return true;
              case NIC_THIS:
                msg = "this";
                break;
@@ -2699,6 +2753,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
                                      location_t location)
 {
   tree decl, old_scope;
+  cp_parser_commit_to_tentative_parse (parser);
   /* Try to lookup the identifier.  */
   old_scope = parser->scope;
   parser->scope = scope;
@@ -2727,8 +2782,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
 
         The user should have said "typename A<T>::X".  */
       if (cxx_dialect < cxx0x && id == ridpointers[(int)RID_CONSTEXPR])
-       inform (location, "C++0x %<constexpr%> only available with "
-               "-std=c++0x or -std=gnu++0x");
+       inform (location, "C++11 %<constexpr%> only available with "
+               "-std=c++11 or -std=gnu++11");
       else if (processing_template_decl && current_class_type
               && TYPE_BINFO (current_class_type))
        {
@@ -2787,12 +2842,11 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
                  "%qT is a dependent scope",
                  parser->scope, id, parser->scope);
       else if (TYPE_P (parser->scope))
-       error_at (location, "%qE in class %qT does not name a type",
+       error_at (location, "%qE in %q#T does not name a type",
                  id, parser->scope);
       else
        gcc_unreachable ();
     }
-  cp_parser_commit_to_tentative_parse (parser);
 }
 
 /* Check for a common situation where a type-name should be present,
@@ -3332,7 +3386,11 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
   struct obstack str_ob;
   cpp_string str, istr, *strs;
   cp_token *tok;
-  enum cpp_ttype type;
+  enum cpp_ttype type, curr_type;
+  int have_suffix_p = 0;
+  tree string_tree;
+  tree suffix_id = NULL_TREE;
+  bool curr_tok_is_userdef_p = false;
 
   tok = cp_lexer_peek_token (parser->lexer);
   if (!cp_parser_is_string_literal (tok))
@@ -3341,7 +3399,18 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
       return error_mark_node;
     }
 
-  type = tok->type;
+  if (cpp_userdef_string_p (tok->type))
+    {
+      string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
+      curr_type = cpp_userdef_string_remove_type (tok->type);
+      curr_tok_is_userdef_p = true;
+    }
+  else
+    {
+      string_tree = tok->u.value;
+      curr_type = tok->type;
+    }
+  type = curr_type;
 
   /* Try to avoid the overhead of creating and destroying an obstack
      for the common case of just one string.  */
@@ -3350,10 +3419,19 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
     {
       cp_lexer_consume_token (parser->lexer);
 
-      str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value);
-      str.len = TREE_STRING_LENGTH (tok->u.value);
+      str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
+      str.len = TREE_STRING_LENGTH (string_tree);
       count = 1;
 
+      if (curr_tok_is_userdef_p)
+       {
+         suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
+         have_suffix_p = 1;
+         curr_type = cpp_userdef_string_remove_type (tok->type);
+       }
+      else
+       curr_type = tok->type;
+
       strs = &str;
     }
   else
@@ -3365,15 +3443,36 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
        {
          cp_lexer_consume_token (parser->lexer);
          count++;
-         str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value);
-         str.len = TREE_STRING_LENGTH (tok->u.value);
+         str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
+         str.len = TREE_STRING_LENGTH (string_tree);
 
-         if (type != tok->type)
+         if (curr_tok_is_userdef_p)
            {
-             if (type == CPP_STRING)
-               type = tok->type;
-             else if (tok->type != CPP_STRING)
-               error_at (tok->location,
+             tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
+             if (have_suffix_p == 0)
+               {
+                 suffix_id = curr_suffix_id;
+                 have_suffix_p = 1;
+               }
+             else if (have_suffix_p == 1
+                      && curr_suffix_id != suffix_id)
+               {
+                 error ("inconsistent user-defined literal suffixes"
+                        " %qD and %qD in string literal",
+                        suffix_id, curr_suffix_id);
+                 have_suffix_p = -1;
+               }
+             curr_type = cpp_userdef_string_remove_type (tok->type);
+           }
+         else
+           curr_type = tok->type;
+
+         if (type != curr_type)
+           {
+             if (type == CPP_STRING)
+               type = curr_type;
+             else if (curr_type != CPP_STRING)
+               error_at (tok->location,
                          "unsupported non-standard concatenation "
                          "of string literals");
            }
@@ -3381,6 +3480,18 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
          obstack_grow (&str_ob, &str, sizeof (cpp_string));
 
          tok = cp_lexer_peek_token (parser->lexer);
+         if (cpp_userdef_string_p (tok->type))
+           {
+             string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
+             curr_type = cpp_userdef_string_remove_type (tok->type);
+             curr_tok_is_userdef_p = true;
+           }
+         else
+           {
+             string_tree = tok->u.value;
+             curr_type = tok->type;
+             curr_tok_is_userdef_p = false;
+           }
        }
       while (cp_parser_is_string_literal (tok));
 
@@ -3418,6 +3529,13 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
        }
 
       value = fix_string_type (value);
+
+      if (have_suffix_p)
+       {
+         tree literal = build_userdef_literal (suffix_id, value, NULL_TREE);
+         tok->u.value = literal;
+         return cp_parser_userdef_string_literal (tok);
+       }
     }
   else
     /* cpp_interpret_string has issued an error.  */
@@ -3429,6 +3547,187 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
   return value;
 }
 
+/* Parse a user-defined char constant.  Returns a call to a user-defined
+   literal operator taking the character as an argument.  */
+
+static tree
+cp_parser_userdef_char_literal (cp_parser *parser)
+{
+  cp_token *token = NULL;
+  tree literal, suffix_id, value;
+  tree name, decl;
+  tree result;
+  VEC(tree,gc) *vec;
+
+  token = cp_lexer_consume_token (parser->lexer);
+  literal = token->u.value;
+  suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  value = USERDEF_LITERAL_VALUE (literal);
+  name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+
+  /* Build up a call to the user-defined operator  */
+  /* Lookup the name we got back from the id-expression.  */
+  vec = make_tree_vector ();
+  VEC_safe_push (tree, gc, vec, value);
+  decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+  if (!decl || decl == error_mark_node)
+    {
+      error ("unable to find user-defined character literal operator %qD",
+            name);
+      release_tree_vector (vec);
+      return error_mark_node;
+    }
+  result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
+  release_tree_vector (vec);
+
+  return result;
+}
+
+/* A subroutine of cp_parser_userdef_numeric_literal to
+   create a char... template parameter pack from a string node.  */
+
+static tree
+make_char_string_pack (tree value)
+{
+  tree charvec;
+  tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
+  const char *str = TREE_STRING_POINTER (value);
+  int i, len = TREE_STRING_LENGTH (value) - 1;
+  tree argvec = make_tree_vec (1);
+
+  /* Fill in CHARVEC with all of the parameters.  */
+  charvec = make_tree_vec (len);
+  for (i = 0; i < len; ++i)
+    TREE_VEC_ELT (charvec, i) = build_int_cst (char_type_node, str[i]);
+
+  /* Build the argument packs.  */
+  SET_ARGUMENT_PACK_ARGS (argpack, charvec);
+  TREE_TYPE (argpack) = char_type_node;
+
+  TREE_VEC_ELT (argvec, 0) = argpack;
+
+  return argvec;
+}
+
+/* Parse a user-defined numeric constant.  returns a call to a user-defined
+   literal operator.  */
+
+static tree
+cp_parser_userdef_numeric_literal (cp_parser *parser)
+{
+  cp_token *token = NULL;
+  tree literal, suffix_id, value, num_string;
+  tree name, decl;
+  tree result = error_mark_node;
+  VEC(tree,gc) *args;
+
+  token = cp_lexer_consume_token (parser->lexer);
+  literal = token->u.value;
+  suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  value = USERDEF_LITERAL_VALUE (literal);
+  num_string = USERDEF_LITERAL_NUM_STRING (literal);
+  name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+
+  /* Build up a call to the user-defined operator  */
+  /* Lookup the name we got back from the id-expression.  */
+  /* Try to find the literal operator by finishing the call expression
+     with the numeric argument.  */
+  args = make_tree_vector ();
+  VEC_safe_push (tree, gc, args, value);
+  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+  if (decl && decl != error_mark_node)
+    {
+      result = finish_call_expr (decl, &args, false, true, tf_none);
+      if (result != error_mark_node)
+       {
+         release_tree_vector (args);
+         return result;
+       }
+    }
+  release_tree_vector (args);
+
+  /* If the numeric argument didn't work, look for a raw literal
+     operator taking a const char* argument consisting of the number
+     in string format.  */
+  args = make_tree_vector ();
+  VEC_safe_push (tree, gc, args, num_string);
+  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+  if (decl && decl != error_mark_node)
+    {
+      result = finish_call_expr (decl, &args, false, true, tf_none);
+      if (result != error_mark_node)
+       {
+         release_tree_vector (args);
+         return result;
+       }
+    }
+  release_tree_vector (args);
+
+  /* If the raw literal didn't work, look for a non-type template
+     function with parameter pack char....  Call the function with
+     template parameter characters representing the number.  */
+  args = make_tree_vector ();
+  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+  if (decl && decl != error_mark_node)
+    {
+      tree tmpl_args = make_char_string_pack (num_string);
+      decl = lookup_template_function (decl, tmpl_args);
+      result = finish_call_expr (decl, &args, false, true, tf_none);
+      if (result != error_mark_node)
+       {
+         release_tree_vector (args);
+         return result;
+       }
+    }
+  release_tree_vector (args);
+
+  if (result == error_mark_node)
+    error ("unable to find user-defined numeric literal operator %qD", name);
+
+  return result;
+}
+
+/* Parse a user-defined string constant.  Returns a call to a user-defined
+   literal operator taking a character pointer and the length of the string
+   as arguments.  */
+
+static tree
+cp_parser_userdef_string_literal (cp_token *token)
+{
+  tree literal, suffix_id, value;
+  tree name, decl;
+  tree result;
+  VEC(tree,gc) *vec;
+  int len;
+
+  literal = token->u.value;
+  suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+  value = USERDEF_LITERAL_VALUE (literal);
+  len = TREE_STRING_LENGTH (value)
+       / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
+  /* Build up a call to the user-defined operator  */
+  /* Lookup the name we got back from the id-expression.  */
+  vec = make_tree_vector ();
+  VEC_safe_push (tree, gc, vec, value);
+  VEC_safe_push (tree, gc, vec, build_int_cst (size_type_node, len));
+  decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+  if (!decl || decl == error_mark_node)
+    {
+      error ("unable to find user-defined string literal operator %qD", name);
+      release_tree_vector (vec);
+      return error_mark_node;
+    }
+  result = finish_call_expr (decl, &vec, false, true, tf_none);
+  if (result == error_mark_node)
+    error ("unable to find valid user-defined string literal operator %qD."
+          "  Possible missing length argument in string literal operator.",
+          name);
+  release_tree_vector (vec);
+
+  return result;
+}
+
 
 /* Basic concepts [gram.basic]  */
 
@@ -3528,8 +3827,11 @@ cp_parser_translation_unit (cp_parser* parser)
      __is_convertible_to ( type-id , type-id )     
      __is_empty ( type-id )
      __is_enum ( type-id )
+     __is_literal_type ( type-id )
      __is_pod ( type-id )
      __is_polymorphic ( type-id )
+     __is_std_layout ( type-id )
+     __is_trivial ( type-id )
      __is_union ( type-id )
 
    Objective-C++ Extension:
@@ -3569,12 +3871,16 @@ cp_parser_primary_expression (cp_parser *parser,
           character-literal
           floating-literal
           string-literal
-          boolean-literal  */
+          boolean-literal
+          pointer-literal
+          user-defined-literal  */
     case CPP_CHAR:
     case CPP_CHAR16:
     case CPP_CHAR32:
     case CPP_WCHAR:
     case CPP_NUMBER:
+      if (TREE_CODE (token->u.value) == USERDEF_LITERAL)
+       return cp_parser_userdef_numeric_literal (parser);
       token = cp_lexer_consume_token (parser->lexer);
       if (TREE_CODE (token->u.value) == FIXED_CST)
        {
@@ -3628,11 +3934,22 @@ cp_parser_primary_expression (cp_parser *parser,
        }
       return token->u.value;
 
+    case CPP_CHAR_USERDEF:
+    case CPP_CHAR16_USERDEF:
+    case CPP_CHAR32_USERDEF:
+    case CPP_WCHAR_USERDEF:
+      return cp_parser_userdef_char_literal (parser);
+
     case CPP_STRING:
     case CPP_STRING16:
     case CPP_STRING32:
     case CPP_WSTRING:
     case CPP_UTF8STRING:
+    case CPP_STRING_USERDEF:
+    case CPP_STRING16_USERDEF:
+    case CPP_STRING32_USERDEF:
+    case CPP_WSTRING_USERDEF:
+    case CPP_UTF8STRING_USERDEF:
       /* ??? 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.  */
@@ -3681,7 +3998,7 @@ cp_parser_primary_expression (cp_parser *parser,
                /* Start the statement-expression.  */
                expr = begin_stmt_expr ();
                /* Parse the compound-statement.  */
-               cp_parser_compound_statement (parser, expr, false);
+               cp_parser_compound_statement (parser, expr, false, false);
                /* Finish up.  */
                expr = finish_stmt_expr (expr, false);
              }
@@ -3696,6 +4013,12 @@ cp_parser_primary_expression (cp_parser *parser,
               `&A::B' might be a pointer-to-member, but `&(A::B)' is
               not.  */
            finish_parenthesized_expr (expr);
+           /* DR 705: Wrapping an unqualified name in parentheses
+              suppresses arg-dependent lookup.  We want to pass back
+              CP_ID_KIND_QUALIFIED for suppressing vtable lookup
+              (c++/37862), but none of the others.  */
+           if (*idk != CP_ID_KIND_QUALIFIED)
+             *idk = CP_ID_KIND_NONE;
          }
        /* The `>' token might be the end of a template-id or
           template-parameter-list now.  */
@@ -3849,12 +4172,12 @@ cp_parser_primary_expression (cp_parser *parser,
        case RID_IS_CONVERTIBLE_TO:
        case RID_IS_EMPTY:
        case RID_IS_ENUM:
+       case RID_IS_LITERAL_TYPE:
        case RID_IS_POD:
        case RID_IS_POLYMORPHIC:
        case RID_IS_STD_LAYOUT:
        case RID_IS_TRIVIAL:
        case RID_IS_UNION:
-       case RID_IS_LITERAL_TYPE:
          return cp_parser_trait_expr (parser, token->keyword);
 
        /* Objective-C++ expressions.  */
@@ -4314,7 +4637,8 @@ cp_parser_unqualified_id (cp_parser* parser,
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
                != CPP_LESS)
            && (token->u.value == TYPE_IDENTIFIER (scope)
-               || constructor_name_p (token->u.value, scope)))
+               || (CLASS_TYPE_P (scope)
+                   && constructor_name_p (token->u.value, scope))))
          {
            cp_lexer_consume_token (parser->lexer);
            return build_nt (BIT_NOT_EXPR, scope);
@@ -4461,6 +4785,14 @@ cp_parser_unqualified_id (cp_parser* parser,
          /* If that didn't work, try a conversion-function-id.  */
          if (!cp_parser_parse_definitely (parser))
            id = cp_parser_conversion_function_id (parser);
+         else if (UDLIT_OPER_P (id))
+           {
+             /* 17.6.3.3.5  */
+             const char *name = UDLIT_OP_SUFFIX (id);
+             if (name[0] != '_' && !in_system_header)
+               warning (0, "literal operator suffixes not preceded by %<_%>"
+                           " are reserved for future standardization");
+           }
 
          return id;
        }
@@ -4557,6 +4889,9 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
       /* A template-id can start a nested-name-specifier.  */
       else if (token->type == CPP_TEMPLATE_ID)
        ;
+      /* DR 743: decltype can be used in a nested-name-specifier.  */
+      else if (token_is_decltype (token))
+       ;
       else
        {
          /* If the next token is not an identifier, then it is
@@ -4630,6 +4965,28 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
             class-or-namespace-name.  */
          parser->scope = old_scope;
          parser->qualifying_scope = saved_qualifying_scope;
+
+         /* If the next token is a decltype, and the one after that is a
+            `::', then the decltype has failed to resolve to a class or
+            enumeration type.  Give this error even when parsing
+            tentatively since it can't possibly be valid--and we're going
+            to replace it with a CPP_NESTED_NAME_SPECIFIER below, so we
+            won't get another chance.*/
+         if (cp_lexer_next_token_is (parser->lexer, CPP_DECLTYPE)
+             && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+                 == CPP_SCOPE))
+           {
+             token = cp_lexer_consume_token (parser->lexer);
+             error_at (token->location, "decltype evaluates to %qT, "
+                       "which is not a class or enumeration type",
+                       token->u.value);
+             parser->scope = error_mark_node;
+             error_p = true;
+             /* As below.  */
+             success = true;
+             cp_lexer_consume_token (parser->lexer);
+           }
+
          if (cp_parser_uncommitted_to_tentative_parse_p (parser))
            break;
          /* If the next token is an identifier, and the one after
@@ -4711,8 +5068,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
               && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
                   == TEMPLATE_ID_EXPR)))
        permerror (input_location, TYPE_P (new_scope)
-                  ? "%qT is not a template"
-                  : "%qD is not a template",
+                  ? G_("%qT is not a template")
+                  : G_("%qD is not a template"),
                   new_scope);
       /* If it is a class scope, try to complete it; we are about to
         be looking up names inside the class.  */
@@ -4801,7 +5158,7 @@ cp_parser_nested_name_specifier (cp_parser *parser,
    this is either a class-name or a namespace-name (which corresponds
    to the class-or-namespace-name production in the grammar). For
    C++0x, it can also be a type-name that refers to an enumeration
-   type.
+   type or a simple-template-id.
 
    TYPENAME_KEYWORD_P is TRUE iff the `typename' keyword is in effect.
    TEMPLATE_KEYWORD_P is TRUE iff the `template' keyword is in effect.
@@ -4829,6 +5186,21 @@ cp_parser_qualifying_entity (cp_parser *parser,
   bool only_class_p;
   bool successful_parse_p;
 
+  /* DR 743: decltype can appear in a nested-name-specifier.  */
+  if (cp_lexer_next_token_is_decltype (parser->lexer))
+    {
+      scope = cp_parser_decltype (parser);
+      if (TREE_CODE (scope) != ENUMERAL_TYPE
+         && !MAYBE_CLASS_TYPE_P (scope))
+       {
+         cp_parser_simulate_error (parser);
+         return error_mark_node;
+       }
+      if (TYPE_NAME (scope))
+       scope = TYPE_NAME (scope);
+      return scope;
+    }
+
   /* Before we try to parse the class-name, we must save away the
      current PARSER->SCOPE since cp_parser_class_name will destroy
      it.  */
@@ -4862,8 +5234,8 @@ cp_parser_qualifying_entity (cp_parser *parser,
       /* Parse tentatively.  */
       cp_parser_parse_tentatively (parser);
      
-      /* Parse a typedef-name or enum-name.  */
-      scope = cp_parser_nonclass_name (parser);
+      /* Parse a type-name  */
+      scope = cp_parser_type_name (parser);
 
       /* "If the name found does not designate a namespace or a class,
         enumeration, or dependent type, the program is ill-formed."
@@ -5063,7 +5435,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* Restore the saved message.  */
        parser->type_definition_forbidden_message = saved_message;
        /* `typeid' may not appear in an integral constant expression.  */
-       if (cp_parser_non_integral_constant_expression(parser, NIC_TYPEID))
+       if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
          return error_mark_node;
       }
       break;
@@ -5161,7 +5533,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                postfix_expression
                  = (finish_compound_literal
                     (type, build_constructor (init_list_type_node,
-                                              initializer_list)));
+                                              initializer_list),
+                     tf_warning_or_error));
                break;
              }
          }
@@ -5263,7 +5636,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                        if (!any_type_dependent_arguments_p (args))
                          postfix_expression
                            = perform_koenig_lookup (postfix_expression, args,
-                                                    /*include_std=*/false);
+                                                    /*include_std=*/false,
+                                                    tf_warning_or_error);
                      }
                    else
                      postfix_expression
@@ -5288,7 +5662,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                        if (!any_type_dependent_arguments_p (args))
                          postfix_expression
                            = perform_koenig_lookup (postfix_expression, args,
-                                                    /*include_std=*/false);
+                                                    /*include_std=*/false,
+                                                    tf_warning_or_error);
                      }
                  }
              }
@@ -5317,7 +5692,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                    = (build_new_method_call
                       (instance, fn, &args, NULL_TREE,
                        (idk == CP_ID_KIND_QUALIFIED
-                        ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
+                        ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
+                        : LOOKUP_NORMAL),
                        /*fn_p=*/NULL,
                        tf_warning_or_error));
                  }
@@ -5521,7 +5897,11 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
                    postfix_expression);
          scope = NULL_TREE;
        }
-      else
+      /* Unlike the object expression in other contexts, *this is not
+        required to be of complete type for purposes of class member
+        access (5.2.5) outside the member function body.  */
+      else if (scope != current_class_ref
+              && !(processing_template_decl && scope == current_class_type))
        scope = complete_type_or_else (scope, NULL_TREE);
       /* Let the name lookup machinery know that we are processing a
         class member access expression.  */
@@ -5609,10 +5989,17 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
        {
          if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
            {
-             name = build_qualified_name (/*type=*/NULL_TREE,
-                                          parser->scope,
-                                          name,
-                                          template_p);
+             if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
+               {
+                 error_at (token->location, "%<%D::%D%> is not a class member",
+                           parser->scope, name);
+                 postfix_expression = error_mark_node;
+               }
+             else
+               name = build_qualified_name (/*type=*/NULL_TREE,
+                                            parser->scope,
+                                            name,
+                                            template_p);
              parser->scope = NULL_TREE;
              parser->qualifying_scope = NULL_TREE;
              parser->object_scope = NULL_TREE;
@@ -5882,6 +6269,11 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
 
   /* Look for the `~'.  */
   cp_parser_require (parser, CPP_COMPL, RT_COMPL);
+
+  /* Once we see the ~, this has to be a pseudo-destructor.  */
+  if (!processing_template_decl && !cp_parser_error_occurred (parser))
+    cp_parser_commit_to_tentative_parse (parser);
+
   /* Look for the type-name again.  We are not responsible for
      checking that it matches the first type-name.  */
   *type = cp_parser_nonclass_name (parser);
@@ -6000,6 +6392,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
          }
          break;
 
+       case RID_TRANSACTION_ATOMIC:
+       case RID_TRANSACTION_RELAXED:
+         return cp_parser_transaction_expression (parser, keyword);
+
        case RID_NOEXCEPT:
          {
            tree expr;
@@ -6552,7 +6948,8 @@ cp_parser_delete_expression (cp_parser* parser)
   if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
     return error_mark_node;
 
-  return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
+  return delete_sanity (expression, NULL_TREE, array_p, global_scope_p,
+                       tf_warning_or_error);
 }
 
 /* Returns true if TOKEN may start a cast-expression and false
@@ -6819,7 +7216,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
   cp_token *token;
   enum tree_code tree_type, lhs_type, rhs_type;
   enum cp_parser_prec new_prec, lookahead_prec;
-  bool overloaded_p;
+  tree overload;
 
   /* Parse the first expression.  */
   lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
@@ -6835,8 +7232,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
           && !parser->greater_than_is_operator_p)
         {
           if (warning_at (token->location, OPT_Wc__0x_compat, 
-                         "%<>>%> operator will be treated as"
-                         " two right angle brackets in C++0x"))
+                         "%<>>%> operator is treated as"
+                         " two right angle brackets in C++11"))
            inform (token->location,
                    "suggest parentheses around %<>>%> expression");
         }
@@ -6922,7 +7319,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
       else if (tree_type == TRUTH_ORIF_EXPR)
        c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node;
 
-      overloaded_p = false;
+      overload = NULL;
       /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
         ERROR_MARK for everything that is not a binary expression.
         This makes warn_about_parentheses miss some warnings that
@@ -6937,7 +7334,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
        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);
+                                &overload, tf_warning_or_error);
       lhs_type = tree_type;
 
       /* If the binary operator required the use of an overloaded operator,
@@ -6946,7 +7343,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
         otherwise permissible in an integral constant-expression if at
         least one of the operands is of enumeration type.  */
 
-      if (overloaded_p
+      if (overload
          && cp_parser_non_integral_constant_expression (parser,
                                                         NIC_OVERLOADED))
        return error_mark_node;
@@ -7284,8 +7681,6 @@ cp_parser_constant_expression (cp_parser* parser,
     }
   if (allow_non_constant_p)
     *non_constant_p = parser->non_integral_constant_expression_p;
-  else if (parser->non_integral_constant_expression_p)
-    expression = error_mark_node;
   parser->non_integral_constant_expression_p
     = saved_non_integral_constant_expression_p;
 
@@ -7387,7 +7782,10 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   return expr;
 }
 
-/* Parse a trait expression.  */
+/* Parse a trait expression.
+
+   Returns a representation of the expression, the underlying type
+   of the type at issue when KEYWORD is RID_UNDERLYING_TYPE.  */
 
 static tree
 cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
@@ -7443,6 +7841,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     case RID_IS_ENUM:
       kind = CPTK_IS_ENUM;
       break;
+    case RID_IS_LITERAL_TYPE:
+      kind = CPTK_IS_LITERAL_TYPE;
+      break;
     case RID_IS_POD:
       kind = CPTK_IS_POD;
       break;
@@ -7458,8 +7859,14 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     case RID_IS_UNION:
       kind = CPTK_IS_UNION;
       break;
-    case RID_IS_LITERAL_TYPE:
-      kind = CPTK_IS_LITERAL_TYPE;
+    case RID_UNDERLYING_TYPE:
+      kind = CPTK_UNDERLYING_TYPE;
+      break;
+    case RID_BASES:
+      kind = CPTK_BASES;
+      break;
+    case RID_DIRECT_BASES:
+      kind = CPTK_DIRECT_BASES;
       break;
     default:
       gcc_unreachable ();
@@ -7505,7 +7912,17 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
 
   /* Complete the trait expression, which may mean either processing
      the trait expr now or saving it for template instantiation.  */
-  return finish_trait_expr (kind, type1, type2);
+  switch(kind)
+    {
+    case CPTK_UNDERLYING_TYPE:
+      return finish_underlying_type (type1);
+    case CPTK_BASES:
+      return finish_bases (type1, false);
+    case CPTK_DIRECT_BASES:
+      return finish_bases (type1, true);
+    default:
+      return finish_trait_expr (kind, type1, type2);
+    }
 }
 
 /* Lambdas that appear in variable initializer or default argument scope
@@ -7573,6 +7990,7 @@ cp_parser_lambda_expression (cp_parser* parser)
 {
   tree lambda_expr = build_lambda_expr ();
   tree type;
+  bool ok;
 
   LAMBDA_EXPR_LOCATION (lambda_expr)
     = cp_lexer_peek_token (parser->lexer)->location;
@@ -7602,15 +8020,22 @@ cp_parser_lambda_expression (cp_parser* parser)
     /* Inside the class, surrounding template-parameter-lists do not apply.  */
     unsigned int saved_num_template_parameter_lists
         = parser->num_template_parameter_lists;
+    unsigned char in_statement = parser->in_statement;
+    bool in_switch_statement_p = parser->in_switch_statement_p;
 
     parser->num_template_parameter_lists = 0;
+    parser->in_statement = 0;
+    parser->in_switch_statement_p = false;
 
     /* 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);
+    ok = cp_parser_lambda_declarator_opt (parser, lambda_expr);
 
-    cp_parser_lambda_body (parser, lambda_expr);
+    if (ok)
+      cp_parser_lambda_body (parser, lambda_expr);
+    else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+      cp_parser_skip_to_end_of_block_or_statement (parser);
 
     /* The capture list was built up in reverse order; fix that now.  */
     {
@@ -7620,40 +8045,37 @@ cp_parser_lambda_expression (cp_parser* parser)
       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);
+    if (ok)
+      maybe_add_lambda_conv_op (type);
 
     type = finish_struct (type, /*attributes=*/NULL_TREE);
 
     parser->num_template_parameter_lists = saved_num_template_parameter_lists;
+    parser->in_statement = in_statement;
+    parser->in_switch_statement_p = in_switch_statement_p;
   }
 
   pop_deferring_access_checks ();
 
-  return build_lambda_object (lambda_expr);
+  /* This field is only used during parsing of the lambda.  */
+  LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE;
+
+  /* This lambda shouldn't have any proxies left at this point.  */
+  gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL);
+  /* And now that we're done, push proxies for an enclosing lambda.  */
+  insert_pending_capture_proxies ();
+
+  if (ok)
+    return build_lambda_object (lambda_expr);
+  else
+    return error_mark_node;
 }
 
 /* Parse the beginning of a lambda expression.
@@ -7714,9 +8136,13 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
       /* Possibly capture `this'.  */
       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS))
        {
+         location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
+           pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant "
+                    "with by-copy capture default");
          cp_lexer_consume_token (parser->lexer);
          add_capture (lambda_expr,
-                      /*id=*/get_identifier ("__this"),
+                      /*id=*/this_identifier,
                       /*initializer=*/finish_this_expr(),
                       /*by_reference_p=*/false,
                       explicit_init_p);
@@ -7776,6 +8202,31 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
                  /*ambiguous_decls=*/NULL,
                  capture_token->location);
 
+         if (capture_init_expr == error_mark_node)
+           {
+             unqualified_name_lookup_error (capture_id);
+             continue;
+           }
+         else if (DECL_P (capture_init_expr)
+                  && (TREE_CODE (capture_init_expr) != VAR_DECL
+                      && TREE_CODE (capture_init_expr) != PARM_DECL))
+           {
+             error_at (capture_token->location,
+                       "capture of non-variable %qD ",
+                       capture_init_expr);
+             inform (0, "%q+#D declared here", capture_init_expr);
+             continue;
+           }
+         if (TREE_CODE (capture_init_expr) == VAR_DECL
+             && decl_storage_duration (capture_init_expr) != dk_auto)
+           {
+             pedwarn (capture_token->location, 0, "capture of variable "
+                      "%qD with non-automatic storage duration",
+                      capture_init_expr);
+             inform (0, "%q+#D declared here", capture_init_expr);
+             continue;
+           }
+
          capture_init_expr
             = finish_id_expression
                 (capture_id,
@@ -7793,9 +8244,20 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
                  capture_token->location);
        }
 
-      if (TREE_CODE (capture_init_expr) == IDENTIFIER_NODE)
-       capture_init_expr
-         = unqualified_name_lookup_error (capture_init_expr);
+      if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
+         && !explicit_init_p)
+       {
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY
+             && capture_kind == BY_COPY)
+           pedwarn (capture_token->location, 0, "explicit by-copy capture "
+                    "of %qD redundant with by-copy capture default",
+                    capture_id);
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE
+             && capture_kind == BY_REFERENCE)
+           pedwarn (capture_token->location, 0, "explicit by-reference "
+                    "capture of %qD redundant with by-reference capture "
+                    "default", capture_id);
+       }
 
       add_capture (lambda_expr,
                   capture_id,
@@ -7818,7 +8280,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 
    LAMBDA_EXPR is the current representation of the lambda expression.  */
 
-static void
+static bool
 cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
 {
   /* 5.1.1.4 of the standard says:
@@ -7906,6 +8368,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
             ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
     declarator = make_call_declarator (declarator, param_list, quals,
+                                      VIRT_SPEC_UNSPECIFIED,
                                       exception_spec,
                                        /*late_return_type=*/NULL_TREE);
     declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
@@ -7913,12 +8376,19 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     fco = grokmethod (&return_type_specs,
                      declarator,
                      attributes);
-    DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
-    DECL_ARTIFICIAL (fco) = 1;
+    if (fco != error_mark_node)
+      {
+       DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
+       DECL_ARTIFICIAL (fco) = 1;
+       /* Give the object parameter a different name.  */
+       DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure");
+      }
 
     finish_member_declaration (fco);
 
     obstack_free (&declarator_obstack, p);
+
+    return (fco != error_mark_node);
   }
 }
 
@@ -7933,8 +8403,15 @@ static void
 cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
 {
   bool nested = (current_function_decl != NULL_TREE);
+  bool local_variables_forbidden_p = parser->local_variables_forbidden_p;
   if (nested)
     push_function_context ();
+  else
+    /* Still increment function_depth so that we don't GC in the
+       middle of an expression.  */
+    ++function_depth;
+  /* Clear this in case we're in the middle of a default argument.  */
+  parser->local_variables_forbidden_p = false;
 
   /* Finish the function call operator
      - class_specifier
@@ -7945,6 +8422,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     tree fco = lambda_function (lambda_expr);
     tree body;
     bool done = false;
+    tree compound_stmt;
+    tree cap;
 
     /* Let the front end know that we are going to be defining this
        function.  */
@@ -7955,6 +8434,16 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     start_lambda_scope (fco);
     body = begin_function_body ();
 
+    if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+      goto out;
+
+    /* Push the proxies for any explicit captures.  */
+    for (cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap;
+        cap = TREE_CHAIN (cap))
+      build_capture_proxy (TREE_PURPOSE (cap));
+
+    compound_stmt = begin_compound_stmt (0);
+
     /* 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:
@@ -7971,11 +8460,9 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
        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)
+        && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN
+        && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON)
       {
-       tree compound_stmt;
        tree expr = NULL_TREE;
        cp_id_kind idk = CP_ID_KIND_NONE;
 
@@ -7983,7 +8470,6 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
           statement.  */
        cp_parser_parse_tentatively (parser);
 
-       cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
        cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN);
 
        expr = cp_parser_expression (parser, /*cast_p=*/false, &idk);
@@ -7995,10 +8481,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
          {
            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;
          }
@@ -8008,12 +8492,16 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
       {
        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);
+       while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+         cp_parser_label_declaration (parser);
+       cp_parser_statement_seq_opt (parser, NULL_TREE);
+       cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
        LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false;
       }
 
+    finish_compound_stmt (compound_stmt);
+
+  out:
     finish_function_body (body);
     finish_lambda_scope ();
 
@@ -8021,8 +8509,11 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     expand_or_defer_fn (finish_function (/*inline*/2));
   }
 
+  parser->local_variables_forbidden_p = local_variables_forbidden_p;
   if (nested)
     pop_function_context();
+  else
+    --function_depth;
 }
 
 /* Statements [gram.stmt.stmt]  */
@@ -8039,6 +8530,11 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
      declaration-statement
      try-block
 
+  TM Extension:
+
+   statement:
+     atomic-statement
+
   IN_COMPOUND is true when the statement is nested inside a
   cp_parser_compound_statement; this matters for certain pragmas.
 
@@ -8115,6 +8611,14 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
          cp_parser_declaration_statement (parser);
          return;
          
+       case RID_TRANSACTION_ATOMIC:
+       case RID_TRANSACTION_RELAXED:
+         statement = cp_parser_transaction (parser, keyword);
+         break;
+       case RID_TRANSACTION_CANCEL:
+         statement = cp_parser_transaction_cancel (parser);
+         break;
+
        default:
          /* It might be a keyword like `int' that can start a
             declaration-statement.  */
@@ -8137,7 +8641,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
     }
   /* Anything that starts with a `{' must be a compound-statement.  */
   else if (token->type == CPP_OPEN_BRACE)
-    statement = cp_parser_compound_statement (parser, NULL, false);
+    statement = cp_parser_compound_statement (parser, NULL, false, false);
   /* CPP_PRAGMA is a #pragma inside a function body, which constitutes
      a statement all its own.  */
   else if (token->type == CPP_PRAGMA)
@@ -8369,13 +8873,17 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
 
 static tree
 cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
-                             bool in_try)
+                             bool in_try, bool function_body)
 {
   tree compound_stmt;
 
   /* Consume the `{'.  */
   if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
     return error_mark_node;
+  if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && !function_body)
+    pedwarn (input_location, OPT_pedantic,
+            "compound-statement in constexpr function");
   /* Begin the compound-statement.  */
   compound_stmt = begin_compound_stmt (in_try ? BCS_TRY_BLOCK : 0);
   /* If the next keyword is `__label__' we have a label declaration.  */
@@ -8687,9 +9195,6 @@ cp_parser_condition (cp_parser* parser)
          if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
            maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
-         if (!non_constant_p)
-           initializer = fold_non_dependent_expr (initializer);
-
          /* Process the initializer.  */
          cp_finish_decl (decl,
                          initializer, !non_constant_p,
@@ -8789,6 +9294,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
     {
       stmt = begin_range_for_stmt (scope, init);
       finish_range_for_decl (stmt, range_decl, range_expr);
+      if (!type_dependent_expression_p (range_expr)
+         /* do_auto_deduction doesn't mess with template init-lists.  */
+         && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
+       do_range_for_auto_deduction (range_decl, range_expr);
     }
   else
     {
@@ -8798,6 +9307,52 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
   return stmt;
 }
 
+/* Subroutine of cp_convert_range_for: given the initializer expression,
+   builds up the range temporary.  */
+
+static tree
+build_range_temp (tree range_expr)
+{
+  tree range_type, range_temp;
+
+  /* Find out the type deduced by the declaration
+     `auto &&__range = range_expr'.  */
+  range_type = cp_build_reference_type (make_auto (), true);
+  range_type = do_auto_deduction (range_type, range_expr,
+                                 type_uses_auto (range_type));
+
+  /* Create the __range variable.  */
+  range_temp = build_decl (input_location, VAR_DECL,
+                          get_identifier ("__for_range"), range_type);
+  TREE_USED (range_temp) = 1;
+  DECL_ARTIFICIAL (range_temp) = 1;
+
+  return range_temp;
+}
+
+/* Used by cp_parser_range_for in template context: we aren't going to
+   do a full conversion yet, but we still need to resolve auto in the
+   type of the for-range-declaration if present.  This is basically
+   a shortcut version of cp_convert_range_for.  */
+
+static void
+do_range_for_auto_deduction (tree decl, tree range_expr)
+{
+  tree auto_node = type_uses_auto (TREE_TYPE (decl));
+  if (auto_node)
+    {
+      tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
+      range_temp = convert_from_reference (build_range_temp (range_expr));
+      iter_type = (cp_parser_perform_range_for_lookup
+                  (range_temp, &begin_dummy, &end_dummy));
+      iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
+      iter_decl = build_x_indirect_ref (iter_decl, RO_NULL,
+                                       tf_warning_or_error);
+      TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
+                                           iter_decl, auto_node);
+    }
+}
+
 /* Converts a range-based for-statement into a normal
    for-statement, as per the definition.
 
@@ -8818,19 +9373,24 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
       }
 
    If RANGE_EXPR is an array:
-       BEGIN_EXPR = __range
-       END_EXPR = __range + ARRAY_SIZE(__range)
+       BEGIN_EXPR = __range
+       END_EXPR = __range + ARRAY_SIZE(__range)
+   Else if RANGE_EXPR has a member 'begin' or 'end':
+       BEGIN_EXPR = __range.begin()
+       END_EXPR = __range.end()
    Else:
        BEGIN_EXPR = begin(__range)
        END_EXPR = end(__range);
 
-   When calling begin()/end() we must use argument dependent
-   lookup, but always considering 'std' as an associated namespace.  */
+   If __range has a member 'begin' but not 'end', or vice versa, we must
+   still use the second alternative (it will surely fail, however).
+   When calling begin()/end() in the third alternative we must use
+   argument dependent lookup, but always considering 'std' as an associated
+   namespace.  */
 
 tree
 cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
 {
-  tree range_type, range_temp;
   tree begin, end;
   tree iter_type, begin_expr, end_expr;
   tree condition, expression;
@@ -8841,68 +9401,18 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
     begin_expr = end_expr = iter_type = error_mark_node;
   else
     {
-      /* Find out the type deduced by the declaration
-       * `auto &&__range = range_expr' */
-      range_type = cp_build_reference_type (make_auto (), true);
-      range_type = do_auto_deduction (range_type, range_expr,
-                                     type_uses_auto (range_type));
-
-      /* Create the __range variable */
-      range_temp = build_decl (input_location, VAR_DECL,
-                              get_identifier ("__for_range"), range_type);
-      TREE_USED (range_temp) = 1;
-      DECL_ARTIFICIAL (range_temp) = 1;
+      tree range_temp = build_range_temp (range_expr);
       pushdecl (range_temp);
       cp_finish_decl (range_temp, range_expr,
                      /*is_constant_init*/false, NULL_TREE,
                      LOOKUP_ONLYCONVERTING);
 
       range_temp = convert_from_reference (range_temp);
-
-      if (TREE_CODE (TREE_TYPE (range_temp)) == ARRAY_TYPE)
-       {
-         /* If RANGE_TEMP is an array we will use pointer arithmetic */
-         iter_type = build_pointer_type (TREE_TYPE (TREE_TYPE (range_temp)));
-         begin_expr = range_temp;
-         end_expr
-             = build_binary_op (input_location, PLUS_EXPR,
-                                range_temp,
-                                array_type_nelts_top (TREE_TYPE (range_temp)),
-                                0);
-       }
-      else
-       {
-         /* If it is not an array, we must call begin(__range)/end__range() */
-         VEC(tree,gc) *vec;
-
-         begin_expr = get_identifier ("begin");
-         vec = make_tree_vector ();
-         VEC_safe_push (tree, gc, vec, range_temp);
-         begin_expr = perform_koenig_lookup (begin_expr, vec,
-                                             /*include_std=*/true);
-         begin_expr = finish_call_expr (begin_expr, &vec, false, true,
-                                        tf_warning_or_error);
-         release_tree_vector (vec);
-
-         end_expr = get_identifier ("end");
-         vec = make_tree_vector ();
-         VEC_safe_push (tree, gc, vec, range_temp);
-         end_expr = perform_koenig_lookup (end_expr, vec,
-                                           /*include_std=*/true);
-         end_expr = finish_call_expr (end_expr, &vec, false, true,
-                                      tf_warning_or_error);
-         release_tree_vector (vec);
-
-         /* The unqualified type of the __begin and __end temporaries should
-          * be the same as required by the multiple auto declaration */
-         iter_type = cv_unqualified (TREE_TYPE (begin_expr));
-         if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (end_expr))))
-           error ("inconsistent begin/end types in range-based for: %qT and %qT",
-                  TREE_TYPE (begin_expr), TREE_TYPE (end_expr));
-       }
+      iter_type = cp_parser_perform_range_for_lookup (range_temp,
+                                                     &begin_expr, &end_expr);
     }
 
-  /* The new for initialization statement */
+  /* The new for initialization statement */
   begin = build_decl (input_location, VAR_DECL,
                      get_identifier ("__for_begin"), iter_type);
   TREE_USED (begin) = 1;
@@ -8923,18 +9433,18 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
 
   finish_for_init_stmt (statement);
 
-/* The new for condition */
+  /* The new for condition.  */
   condition = build_x_binary_op (NE_EXPR,
                                 begin, ERROR_MARK,
                                 end, ERROR_MARK,
                                 NULL, tf_warning_or_error);
   finish_for_cond (condition, statement);
 
-  /* The new increment expression */
+  /* The new increment expression */
   expression = finish_unary_op_expr (PREINCREMENT_EXPR, begin);
   finish_for_expr (expression, statement);
 
-  /* The declaration is initialized with *__begin inside the loop body */
+  /* The declaration is initialized with *__begin inside the loop body */
   cp_finish_decl (range_decl,
                  build_x_indirect_ref (begin, RO_NULL, tf_warning_or_error),
                  /*is_constant_init*/false, NULL_TREE,
@@ -8943,6 +9453,132 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
   return statement;
 }
 
+/* Solves BEGIN_EXPR and END_EXPR as described in cp_convert_range_for.
+   We need to solve both at the same time because the method used
+   depends on the existence of members begin or end.
+   Returns the type deduced for the iterator expression.  */
+
+static tree
+cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
+{
+  if (error_operand_p (range))
+    {
+      *begin = *end = error_mark_node;
+      return error_mark_node;
+    }
+
+  if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (range))))
+    {
+      error ("range-based %<for%> expression of type %qT "
+            "has incomplete type", TREE_TYPE (range));
+      *begin = *end = error_mark_node;
+      return error_mark_node;
+    }
+  if (TREE_CODE (TREE_TYPE (range)) == ARRAY_TYPE)
+    {
+      /* If RANGE is an array, we will use pointer arithmetic.  */
+      *begin = range;
+      *end = build_binary_op (input_location, PLUS_EXPR,
+                             range,
+                             array_type_nelts_top (TREE_TYPE (range)),
+                             0);
+      return build_pointer_type (TREE_TYPE (TREE_TYPE (range)));
+    }
+  else
+    {
+      /* If it is not an array, we must do a bit of magic.  */
+      tree id_begin, id_end;
+      tree member_begin, member_end;
+
+      *begin = *end = error_mark_node;
+
+      id_begin = get_identifier ("begin");
+      id_end = get_identifier ("end");
+      member_begin = lookup_member (TREE_TYPE (range), id_begin,
+                                   /*protect=*/2, /*want_type=*/false);
+      member_end = lookup_member (TREE_TYPE (range), id_end,
+                                 /*protect=*/2, /*want_type=*/false);
+
+      if (member_begin != NULL_TREE || member_end != NULL_TREE)
+       {
+         /* Use the member functions.  */
+         if (member_begin != NULL_TREE)
+           *begin = cp_parser_range_for_member_function (range, id_begin);
+         else
+           error ("range-based %<for%> expression of type %qT has an "
+                  "%<end%> member but not a %<begin%>", TREE_TYPE (range));
+
+         if (member_end != NULL_TREE)
+           *end = cp_parser_range_for_member_function (range, id_end);
+         else
+           error ("range-based %<for%> expression of type %qT has a "
+                  "%<begin%> member but not an %<end%>", TREE_TYPE (range));
+       }
+      else
+       {
+         /* Use global functions with ADL.  */
+         VEC(tree,gc) *vec;
+         vec = make_tree_vector ();
+
+         VEC_safe_push (tree, gc, vec, range);
+
+         member_begin = perform_koenig_lookup (id_begin, vec,
+                                               /*include_std=*/true,
+                                               tf_warning_or_error);
+         *begin = finish_call_expr (member_begin, &vec, false, true,
+                                    tf_warning_or_error);
+         member_end = perform_koenig_lookup (id_end, vec,
+                                             /*include_std=*/true,
+                                             tf_warning_or_error);
+         *end = finish_call_expr (member_end, &vec, false, true,
+                                  tf_warning_or_error);
+
+         release_tree_vector (vec);
+       }
+
+      /* Last common checks.  */
+      if (*begin == error_mark_node || *end == error_mark_node)
+       {
+         /* If one of the expressions is an error do no more checks.  */
+         *begin = *end = error_mark_node;
+         return error_mark_node;
+       }
+      else
+       {
+         tree iter_type = cv_unqualified (TREE_TYPE (*begin));
+         /* The unqualified type of the __begin and __end temporaries should
+            be the same, as required by the multiple auto declaration.  */
+         if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
+           error ("inconsistent begin/end types in range-based %<for%> "
+                  "statement: %qT and %qT",
+                  TREE_TYPE (*begin), TREE_TYPE (*end));
+         return iter_type;
+       }
+    }
+}
+
+/* Helper function for cp_parser_perform_range_for_lookup.
+   Builds a tree for RANGE.IDENTIFIER().  */
+
+static tree
+cp_parser_range_for_member_function (tree range, tree identifier)
+{
+  tree member, res;
+  VEC(tree,gc) *vec;
+
+  member = finish_class_member_access_expr (range, identifier,
+                                           false, tf_warning_or_error);
+  if (member == error_mark_node)
+    return error_mark_node;
+
+  vec = make_tree_vector ();
+  res = finish_call_expr (member, &vec,
+                         /*disallow_virtual=*/false,
+                         /*koenig_p=*/false,
+                         tf_warning_or_error);
+  release_tree_vector (vec);
+  return res;
+}
 
 /* Parse an iteration-statement.
 
@@ -9091,7 +9727,7 @@ cp_parser_for_init_statement (cp_parser* parser, tree *decl)
          if (cxx_dialect < cxx0x)
            {
              error_at (cp_lexer_peek_token (parser->lexer)->location,
-                       "range-based-for loops are not allowed "
+                       "range-based %<for%> loops are not allowed "
                        "in C++98 mode");
              *decl = error_mark_node;
            }
@@ -9289,7 +9925,7 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
     }
   /* if a compound is opened, we simply parse the statement directly.  */
   else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
-    statement = cp_parser_compound_statement (parser, NULL, false);
+    statement = cp_parser_compound_statement (parser, NULL, false, false);
   /* If the token is not a `{', then we must take special action.  */
   else
     {
@@ -9443,7 +10079,7 @@ cp_parser_declaration (cp_parser* parser)
   /* If the next token is `extern' and the following token is a string
      literal, then we have a linkage specification.  */
   if (token1.keyword == RID_EXTERN
-      && cp_parser_is_string_literal (&token2))
+      && cp_parser_is_pure_string_literal (&token2))
     cp_parser_linkage_specification (parser);
   /* If the next token is `template', then we have either a template
      declaration, an explicit instantiation, or an explicit
@@ -9561,8 +10197,8 @@ cp_parser_block_declaration (cp_parser *parser,
      namespace-alias-definition.  */
   else if (token1->keyword == RID_NAMESPACE)
     cp_parser_namespace_alias_definition (parser);
-  /* If the next keyword is `using', we have either a
-     using-declaration or a using-directive.  */
+  /* If the next keyword is `using', we have a
+     using-declaration, a using-directive, or an alias-declaration.  */
   else if (token1->keyword == RID_USING)
     {
       cp_token *token2;
@@ -9574,6 +10210,14 @@ cp_parser_block_declaration (cp_parser *parser,
       token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
       if (token2->keyword == RID_NAMESPACE)
        cp_parser_using_directive (parser);
+      /* If the second token after 'using' is '=', then we have an
+        alias-declaration.  */
+      else if (cxx_dialect >= cxx0x
+              && token2->type == CPP_NAME
+              && ((cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
+                  || (cp_lexer_peek_nth_token (parser->lexer, 3)->keyword
+                      == RID_ATTRIBUTE)))
+       cp_parser_alias_declaration (parser);
       /* Otherwise, it's a using-declaration.  */
       else
        cp_parser_using_declaration (parser,
@@ -9939,7 +10583,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
               /* Complain about `auto' as a storage specifier, if
                  we're complaining about C++0x compatibility.  */
               warning_at (token->location, OPT_Wc__0x_compat, "%<auto%>"
-                         " will change meaning in C++0x; please remove it");
+                         " changes meaning in C++11; please remove it");
 
               /* Set the storage class anyway.  */
               cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
@@ -10291,6 +10935,14 @@ cp_parser_decltype (cp_parser *parser)
   bool saved_integral_constant_expression_p;
   bool saved_non_integral_constant_expression_p;
   cp_token *id_expr_start_token;
+  cp_token *start_token = cp_lexer_peek_token (parser->lexer);
+
+  if (start_token->type == CPP_DECLTYPE)
+    {
+      /* Already parsed.  */
+      cp_lexer_consume_token (parser->lexer);
+      return start_token->u.value;
+    }
 
   /* Look for the `decltype' token.  */
   if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
@@ -10444,14 +11096,6 @@ cp_parser_decltype (cp_parser *parser)
   parser->non_integral_constant_expression_p
     = saved_non_integral_constant_expression_p;
 
-  if (expr == error_mark_node)
-    {
-      /* Skip everything up to the closing `)'.  */
-      cp_parser_skip_to_closing_parenthesis (parser, true, false,
-                                             /*consume_paren=*/true);
-      return error_mark_node;
-    }
-  
   /* Parse to the closing `)'.  */
   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
     {
@@ -10460,7 +11104,17 @@ cp_parser_decltype (cp_parser *parser)
       return error_mark_node;
     }
 
-  return finish_decltype_type (expr, id_expression_or_member_access_p);
+  expr = finish_decltype_type (expr, id_expression_or_member_access_p,
+                              tf_warning_or_error);
+
+  /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
+     it again.  */
+  start_token->type = CPP_DECLTYPE;
+  start_token->u.value = expr;
+  start_token->keyword = RID_MAX;
+  cp_lexer_purge_tokens_after (parser->lexer, start_token);
+
+  return expr;
 }
 
 /* Special member functions [gram.special] */
@@ -10864,9 +11518,25 @@ cp_parser_operator_function_id (cp_parser* parser)
   return cp_parser_operator (parser);
 }
 
-/* Parse an operator.
+/* Return an identifier node for a user-defined literal operator.
+   The suffix identifier is chained to the operator name identifier.  */
 
-   operator:
+static tree
+cp_literal_operator_id (const char* name)
+{
+  tree identifier;
+  char *buffer = XNEWVEC (char, strlen (UDLIT_OP_ANSI_PREFIX)
+                             + strlen (name) + 10);
+  sprintf (buffer, UDLIT_OP_ANSI_FORMAT, name);
+  identifier = get_identifier (buffer);
+  /*IDENTIFIER_UDLIT_OPNAME_P (identifier) = 1; If we get a flag someday. */
+
+  return identifier;
+}
+
+/* Parse an operator.
+
+   operator:
      new delete new[] delete[] + - * / % ^ & | ~ ! = < >
      += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= &&
      || ++ -- , ->* -> () []
@@ -11083,6 +11753,37 @@ cp_parser_operator (cp_parser* parser)
       cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
       return ansi_opname (ARRAY_REF);
 
+    case CPP_STRING:
+      if (cxx_dialect == cxx98)
+       maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+      if (TREE_STRING_LENGTH (token->u.value) > 2)
+       {
+         error ("expected empty string after %<operator%> keyword");
+         return error_mark_node;
+       }
+      /* Consume the string.  */
+      cp_lexer_consume_token (parser->lexer);
+      /* Look for the suffix identifier.  */
+      token = cp_lexer_peek_token (parser->lexer);
+      if (token->type == CPP_NAME)
+       {
+         id = cp_parser_identifier (parser);
+         if (id != error_mark_node)
+           {
+             const char *name = IDENTIFIER_POINTER (id);
+             return cp_literal_operator_id (name);
+           }
+       }
+      else
+       {
+         error ("expected suffix identifier");
+         return error_mark_node;
+       }
+
+    case CPP_STRING_USERDEF:
+      error ("missing space between %<\"\"%> and suffix identifier");
+      return error_mark_node;
+
     default:
       /* Anything else is an error.  */
       break;
@@ -11314,9 +12015,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
         user may try to do so, so we'll parse them and give an
         appropriate diagnostic here.  */
 
-      /* Consume the `='.  */
       cp_token *start_token = cp_lexer_peek_token (parser->lexer);
-      cp_lexer_consume_token (parser->lexer);
       
       /* Find the name of the parameter pack.  */     
       id_declarator = parameter_declarator->declarator;
@@ -11699,7 +12398,7 @@ cp_parser_template_id (cp_parser *parser,
   /* Build a representation of the specialization.  */
   if (TREE_CODE (templ) == IDENTIFIER_NODE)
     template_id = build_min_nt (TEMPLATE_ID_EXPR, templ, arguments);
-  else if (DECL_CLASS_TEMPLATE_P (templ)
+  else if (DECL_TYPE_TEMPLATE_P (templ)
           || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
     {
       bool entering_scope;
@@ -11981,6 +12680,7 @@ cp_parser_template_argument_list (cp_parser* parser)
   parser->integral_constant_expression_p = false;
   saved_non_ice_p = parser->non_integral_constant_expression_p;
   parser->non_integral_constant_expression_p = false;
+
   /* Parse the arguments.  */
   do
     {
@@ -12308,6 +13008,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   cp_decl_specifier_seq decl_specifiers;
   tree extension_specifier = NULL_TREE;
 
+  timevar_push (TV_TEMPLATE_INST);
+
   /* Look for an (optional) storage-class-specifier or
      function-specifier.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
@@ -12391,6 +13093,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   end_explicit_instantiation ();
 
   cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+  timevar_pop (TV_TEMPLATE_INST);
 }
 
 /* Parse an explicit-specialization.
@@ -12544,7 +13248,7 @@ cp_parser_type_specifier (cp_parser* parser,
            cp_parser_set_decl_spec_type (decl_specs,
                                          type_spec,
                                          token->location,
-                                         /*user_defined_p=*/true);
+                                         /*type_definition_p=*/true);
          return type_spec;
        }
       else
@@ -12573,7 +13277,7 @@ cp_parser_type_specifier (cp_parser* parser,
            cp_parser_set_decl_spec_type (decl_specs,
                                          type_spec,
                                          token->location,
-                                         /*user_defined_p=*/true);
+                                         /*type_definition_p=*/true);
          return type_spec;
        }
 
@@ -12595,7 +13299,7 @@ cp_parser_type_specifier (cp_parser* parser,
        cp_parser_set_decl_spec_type (decl_specs,
                                      type_spec,
                                      token->location,
-                                     /*user_defined_p=*/true);
+                                     /*type_definition_p=*/false);
       return type_spec;
 
     case RID_CONST:
@@ -12677,6 +13381,7 @@ cp_parser_type_specifier (cp_parser* parser,
      decltype ( expression )   
      char16_t
      char32_t
+     __underlying_type ( type-id )
 
    GNU Extension:
 
@@ -12767,15 +13472,13 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       break;
 
     case RID_DECLTYPE:
-      /* Parse the `decltype' type.  */
-      type = cp_parser_decltype (parser);
-
-      if (decl_specs)
-       cp_parser_set_decl_spec_type (decl_specs, type,
-                                     token->location,
-                                     /*user_defined_p=*/true);
-
-      return type;
+      /* Since DR 743, decltype can either be a simple-type-specifier by
+        itself or begin a nested-name-specifier.  Parsing it will replace
+        it with a CPP_DECLTYPE, so just rewind and let the CPP_DECLTYPE
+        handling below decide what to do.  */
+      cp_parser_decltype (parser);
+      cp_lexer_set_token_position (parser->lexer, token);
+      break;
 
     case RID_TYPEOF:
       /* Consume the `typeof' token.  */
@@ -12789,14 +13492,45 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       if (decl_specs)
        cp_parser_set_decl_spec_type (decl_specs, type,
                                      token->location,
-                                     /*user_defined_p=*/true);
+                                     /*type_definition_p=*/false);
 
       return type;
 
+    case RID_UNDERLYING_TYPE:
+      type = cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE);
+      if (decl_specs)
+       cp_parser_set_decl_spec_type (decl_specs, type,
+                                     token->location,
+                                     /*type_definition_p=*/false);
+
+      return type;
+
+    case RID_BASES:
+    case RID_DIRECT_BASES:
+      type = cp_parser_trait_expr (parser, token->keyword);
+      if (decl_specs)
+       cp_parser_set_decl_spec_type (decl_specs, type,
+                                     token->location,
+                                     /*type_definition_p=*/false);
+      return type;
     default:
       break;
     }
 
+  /* If token is an already-parsed decltype not followed by ::,
+     it's a simple-type-specifier.  */
+  if (token->type == CPP_DECLTYPE
+      && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
+    {
+      type = token->u.value;
+      if (decl_specs)
+       cp_parser_set_decl_spec_type (decl_specs, type,
+                                     token->location,
+                                     /*type_definition_p=*/false);
+      cp_lexer_consume_token (parser->lexer);
+      return type;
+    }
+
   /* If the type-specifier was for a built-in type, we're done.  */
   if (type)
     {
@@ -12809,7 +13543,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        cp_parser_set_decl_spec_type (decl_specs,
                                      type,
                                      token->location,
-                                     /*user_defined=*/false);
+                                     /*type_definition_p=*/false);
       if (decl_specs)
        decl_specs->any_specifiers_p = true;
 
@@ -12884,7 +13618,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       if (type && decl_specs)
        cp_parser_set_decl_spec_type (decl_specs, type,
                                      token->location,
-                                     /*user_defined=*/true);
+                                     /*type_definition_p=*/false);
     }
 
   /* If we didn't get a type-name, issue an error message.  */
@@ -12932,6 +13666,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
      class-name
      enum-name
      typedef-name
+     simple-template-id [in c++0x]
 
    enum-name:
      identifier
@@ -12959,8 +13694,37 @@ cp_parser_type_name (cp_parser* parser)
   /* If it's not a class-name, keep looking.  */
   if (!cp_parser_parse_definitely (parser))
     {
-      /* It must be a typedef-name or an enum-name.  */
-      return cp_parser_nonclass_name (parser);
+      if (cxx_dialect < cxx0x)
+       /* It must be a typedef-name or an enum-name.  */
+       return cp_parser_nonclass_name (parser);
+
+      cp_parser_parse_tentatively (parser);
+      /* It is either a simple-template-id representing an
+        instantiation of an alias template...  */
+      type_decl = cp_parser_template_id (parser,
+                                        /*template_keyword_p=*/false,
+                                        /*check_dependency_p=*/false,
+                                        /*is_declaration=*/false);
+      /* Note that this must be an instantiation of an alias template
+        because [temp.names]/6 says:
+        
+            A template-id that names an alias template specialization
+            is a type-name.
+
+        Whereas [temp.names]/7 says:
+        
+            A simple-template-id that names a class template
+            specialization is a class-name.  */
+      if (type_decl != NULL_TREE
+         && TREE_CODE (type_decl) == TYPE_DECL
+         && TYPE_DECL_ALIAS_P (type_decl))
+       gcc_assert (DECL_TEMPLATE_INSTANTIATION (type_decl));
+      else
+       cp_parser_simulate_error (parser);
+
+      if (!cp_parser_parse_definitely (parser))
+       /* ... Or a typedef-name or an enum-name.  */
+       return cp_parser_nonclass_name (parser);
     }
 
   return type_decl;
@@ -13360,7 +14124,13 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
     }
 
   if (tag_type != enum_type)
-    cp_parser_check_class_key (tag_type, type);
+    {
+      /* Indicate whether this class was declared as a `class' or as a
+        `struct'.  */
+      if (TREE_CODE (type) == RECORD_TYPE)
+       CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
+      cp_parser_check_class_key (tag_type, type);
+    }
 
   /* A "<" cannot follow an elaborated type specifier.  If that
      happens, the user was probably trying to form a template-id.  */
@@ -13373,6 +14143,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
    enum-specifier:
      enum-head { enumerator-list [opt] }
+     enum-head { enumerator-list , } [C++0x]
 
    enum-head:
      enum-key identifier [opt] enum-base [opt]
@@ -13392,6 +14163,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
    GNU Extensions:
      enum-key attributes[opt] identifier [opt] enum-base [opt] 
        { enumerator-list [opt] }attributes[opt]
+     enum-key attributes[opt] identifier [opt] enum-base [opt]
+       { enumerator-list, }attributes[opt] [C++0x]
 
    Returns an ENUM_TYPE representing the enumeration, or NULL_TREE
    if the token stream isn't an enum-specifier after all.  */
@@ -13591,6 +14364,7 @@ cp_parser_enum_specifier (cp_parser* parser)
      elaborated-type-specifier.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
+      timevar_push (TV_PARSE_ENUM);
       if (nested_name_specifier)
        {
          /* The following catches invalid code such as:
@@ -13652,6 +14426,7 @@ cp_parser_enum_specifier (cp_parser* parser)
 
       if (scoped_enum_p)
        finish_scope ();
+      timevar_pop (TV_PARSE_ENUM);
     }
   else
     {
@@ -13729,8 +14504,9 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
       /* If the next token is a `}', there is a trailing comma.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
        {
-         if (!in_system_header)
-           pedwarn (input_location, OPT_pedantic, "comma at end of enumerator list");
+         if (cxx_dialect < cxx0x && !in_system_header)
+           pedwarn (input_location, OPT_pedantic,
+                     "comma at end of enumerator list");
          break;
        }
     }
@@ -14144,6 +14920,74 @@ cp_parser_using_declaration (cp_parser* parser,
   return true;
 }
 
+/* Parse an alias-declaration.
+
+   alias-declaration:
+     using identifier attribute-specifier-seq [opt] = type-id  */
+
+static tree
+cp_parser_alias_declaration (cp_parser* parser)
+{
+  tree id, type, decl, pushed_scope = NULL_TREE, attributes;
+  location_t id_location;
+  cp_declarator *declarator;
+  cp_decl_specifier_seq decl_specs;
+  bool member_p;
+
+  /* Look for the `using' keyword.  */
+  cp_parser_require_keyword (parser, RID_USING, RT_USING);
+  id_location = cp_lexer_peek_token (parser->lexer)->location;
+  id = cp_parser_identifier (parser);
+  attributes = cp_parser_attributes_opt (parser);
+  cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+  type = cp_parser_type_id (parser);
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+  /* A typedef-name can also be introduced by an alias-declaration. The
+     identifier following the using keyword becomes a typedef-name. It has
+     the same semantics as if it were introduced by the typedef
+     specifier. In particular, it does not define a new type and it shall
+     not appear in the type-id.  */
+
+  clear_decl_specs (&decl_specs);
+  decl_specs.type = type;
+  decl_specs.attributes = attributes;
+  ++decl_specs.specs[(int) ds_typedef];
+  ++decl_specs.specs[(int) ds_alias];
+
+  declarator = make_id_declarator (NULL_TREE, id, sfk_none);
+  declarator->id_loc = id_location;
+
+  member_p = at_class_scope_p ();
+  if (member_p)
+    decl = grokfield (declarator, &decl_specs, NULL_TREE, false,
+                     NULL_TREE, attributes);
+  else
+    decl = start_decl (declarator, &decl_specs, 0,
+                      attributes, NULL_TREE, &pushed_scope);
+  if (decl == error_mark_node)
+    return decl;
+
+  cp_finish_decl (decl, NULL_TREE, 0, NULL_TREE, 0);
+
+  if (pushed_scope)
+    pop_scope (pushed_scope);
+
+  /* If decl is a template, return its TEMPLATE_DECL so that it gets
+     added into the symbol table; otherwise, return the TYPE_DECL.  */
+  if (DECL_LANG_SPECIFIC (decl)
+      && DECL_TEMPLATE_INFO (decl)
+      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
+    {
+      decl = DECL_TI_TEMPLATE (decl);
+      if (member_p)
+       check_member_template (decl);
+    }
+
+  return decl;
+}
+
 /* Parse a using-directive.
 
    using-directive:
@@ -14395,6 +15239,11 @@ cp_parser_asm_definition (cp_parser* parser)
    function-definition:
      __extension__ function-definition
 
+   TM Extension:
+
+   function-definition:
+     decl-specifier-seq [opt] declarator function-transaction-block
+
    The DECL_SPECIFIERS apply to this declarator.  Returns a
    representation of the entity declared.  If MEMBER_P is TRUE, then
    this declarator appears in a class scope.  The new DECL created by
@@ -14447,7 +15296,7 @@ cp_parser_init_declarator (cp_parser* parser,
   bool is_non_constant_init;
   int ctor_dtor_or_conv_p;
   bool friend_p;
-  tree pushed_scope = NULL;
+  tree pushed_scope = NULL_TREE;
   bool range_for_decl_p = false;
 
   /* Gather the attributes that were provided with the
@@ -14470,7 +15319,7 @@ cp_parser_init_declarator (cp_parser* parser,
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                            &ctor_dtor_or_conv_p,
                            /*parenthesized_p=*/NULL,
-                           /*member_p=*/false);
+                           member_p);
   /* Gather up the deferred checks.  */
   stop_deferring_access_checks ();
 
@@ -14754,7 +15603,7 @@ cp_parser_init_declarator (cp_parser* parser,
       if (pushed_scope)
        {
          pop_scope (pushed_scope);
-         pushed_scope = false;
+         pushed_scope = NULL_TREE;
        }
       decl = grokfield (declarator, decl_specifiers,
                        initializer, !is_non_constant_init,
@@ -14764,9 +15613,9 @@ cp_parser_init_declarator (cp_parser* parser,
        cp_parser_save_default_args (parser, decl);
     }
 
-  /* Finish processing the declaration.  But, skip friend
+  /* Finish processing the declaration.  But, skip member
      declarations.  */
-  if (!friend_p && decl && decl != error_mark_node && !range_for_decl_p)
+  if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
     {
       cp_finish_decl (decl,
                      initializer, !is_non_constant_init,
@@ -15027,11 +15876,15 @@ cp_parser_direct_declarator (cp_parser* parser,
              parser->num_template_parameter_lists
                = saved_num_template_parameter_lists;
 
+             /* Consume the `)'.  */
+             cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
              /* If all went well, parse the cv-qualifier-seq and the
                 exception-specification.  */
              if (member_p || cp_parser_parse_definitely (parser))
                {
                  cp_cv_quals cv_quals;
+                 cp_virt_specifiers virt_specifiers;
                  tree exception_specification;
                  tree late_return;
 
@@ -15040,22 +15893,23 @@ cp_parser_direct_declarator (cp_parser* parser,
                  if (ctor_dtor_or_conv_p)
                    *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
                  first = false;
-                 /* Consume the `)'.  */
-                 cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 
                  /* Parse the cv-qualifier-seq.  */
                  cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
                  /* And the exception-specification.  */
                  exception_specification
                    = cp_parser_exception_specification_opt (parser);
+                 /* Parse the virt-specifier-seq.  */
+                 virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
 
-                 late_return
-                   = cp_parser_late_return_type_opt (parser);
+                 late_return = (cp_parser_late_return_type_opt
+                                (parser, member_p ? cv_quals : -1));
 
                  /* Create the function-declarator.  */
                  declarator = make_call_declarator (declarator,
                                                     params,
                                                     cv_quals,
+                                                    virt_specifiers,
                                                     exception_specification,
                                                     late_return);
                  /* Any subsequent parameter lists are to do with
@@ -15563,17 +16417,103 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
   return cv_quals;
 }
 
+/* Parse an (optional) virt-specifier-seq.
+
+   virt-specifier-seq:
+     virt-specifier virt-specifier-seq [opt]
+
+   virt-specifier:
+     override
+     final
+
+   Returns a bitmask representing the virt-specifiers.  */
+
+static cp_virt_specifiers
+cp_parser_virt_specifier_seq_opt (cp_parser* parser)
+{
+  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
+
+  while (true)
+    {
+      cp_token *token;
+      cp_virt_specifiers virt_specifier;
+
+      /* Peek at the next token.  */
+      token = cp_lexer_peek_token (parser->lexer);
+      /* See if it's a virt-specifier-qualifier.  */
+      if (token->type != CPP_NAME)
+        break;
+      if (!strcmp (IDENTIFIER_POINTER(token->u.value), "override"))
+        {
+          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+          virt_specifier = VIRT_SPEC_OVERRIDE;
+        }
+      else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "final"))
+        {
+          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
+          virt_specifier = VIRT_SPEC_FINAL;
+        }
+      else if (!strcmp (IDENTIFIER_POINTER(token->u.value), "__final"))
+        {
+          virt_specifier = VIRT_SPEC_FINAL;
+        }
+      else
+       break;
+
+      if (virt_specifiers & virt_specifier)
+       {
+         error_at (token->location, "duplicate virt-specifier");
+         cp_lexer_purge_token (parser->lexer);
+       }
+      else
+       {
+         cp_lexer_consume_token (parser->lexer);
+         virt_specifiers |= virt_specifier;
+       }
+    }
+  return virt_specifiers;
+}
+
+/* Used by handling of trailing-return-types and NSDMI, in which 'this'
+   is in scope even though it isn't real.  */
+
+static void
+inject_this_parameter (tree ctype, cp_cv_quals quals)
+{
+  tree this_parm;
+
+  if (current_class_ptr)
+    {
+      /* We don't clear this between NSDMIs.  Is it already what we want?  */
+      tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
+      if (same_type_ignoring_top_level_qualifiers_p (ctype, type)
+         && cp_type_quals (type) == quals)
+       return;
+    }
+
+  this_parm = build_this_parm (ctype, quals);
+  /* Clear this first to avoid shortcut in cp_build_indirect_ref.  */
+  current_class_ptr = NULL_TREE;
+  current_class_ref
+    = cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
+  current_class_ptr = this_parm;
+}
+
 /* Parse a late-specified return type, if any.  This is not a separate
    non-terminal, but part of a function declarator, which looks like
 
    -> trailing-type-specifier-seq abstract-declarator(opt)
 
-   Returns the type indicated by the type-id.  */
+   Returns the type indicated by the type-id.
+
+   QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
+   function.  */
 
 static tree
-cp_parser_late_return_type_opt (cp_parser* parser)
+cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
 {
   cp_token *token;
+  tree type;
 
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
@@ -15584,7 +16524,19 @@ cp_parser_late_return_type_opt (cp_parser* parser)
   /* Consume the ->.  */
   cp_lexer_consume_token (parser->lexer);
 
-  return cp_parser_trailing_type_id (parser);
+  if (quals >= 0)
+    {
+      /* DR 1207: 'this' is in scope in the trailing return type.  */
+      gcc_assert (current_class_ptr == NULL_TREE);
+      inject_this_parameter (current_class_type, quals);
+    }
+
+  type = cp_parser_trailing_type_id (parser);
+
+  if (quals >= 0)
+    current_class_ptr = current_class_ref = NULL_TREE;
+
+  return type;
 }
 
 /* Parse a declarator-id.
@@ -15688,7 +16640,13 @@ static tree cp_parser_type_id (cp_parser *parser)
 
 static tree cp_parser_template_type_arg (cp_parser *parser)
 {
-  return cp_parser_type_id_1 (parser, true, false);
+  tree r;
+  const char *saved_message = parser->type_definition_forbidden_message;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in template arguments");
+  r = cp_parser_type_id_1 (parser, true, false);
+  parser->type_definition_forbidden_message = saved_message;
+  return r;
 }
 
 static tree cp_parser_trailing_type_id (cp_parser *parser)
@@ -15919,7 +16877,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
     {
       cp_parameter_declarator *parameter;
       tree decl = error_mark_node;
-      bool parenthesized_p;
+      bool parenthesized_p = false;
       /* Parse the parameter.  */
       parameter
        = cp_parser_parameter_declaration (parser,
@@ -16122,6 +17080,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
             of some object of type "char" to "int".  */
          && !parser->in_type_id_in_expr_p
          && cp_parser_uncommitted_to_tentative_parse_p (parser)
+         && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
          && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
        cp_parser_commit_to_tentative_parse (parser);
       /* Parse the declarator.  */
@@ -16176,9 +17135,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
   /* If the next token is `=', then process a default argument.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
     {
-      /* Consume the `='.  */
-      cp_lexer_consume_token (parser->lexer);
-
       /* 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 ()
@@ -16356,17 +17312,20 @@ cp_parser_parameter_declaration (cp_parser *parser,
          
          if (id_declarator && id_declarator->kind == cdk_id)
            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",
+                     template_parm_p
+                     ? G_("template parameter pack %qD "
+                          "cannot have a default argument")
+                     : G_("parameter pack %qD cannot have "
+                          "a default argument"),
                      id_declarator->u.id.unqualified_name);
          else
            error_at (declarator_token_start->location,
-                     template_parm_p 
-                     ? "template parameter pack cannot have a default argument"
-                     : "parameter pack cannot have a default argument");
-         
+                     template_parm_p
+                     ? G_("template parameter pack cannot have "
+                          "a default argument")
+                     : G_("parameter pack cannot have a "
+                          "default argument"));
+
          default_argument = NULL_TREE;
        }
     }
@@ -16388,6 +17347,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   tree default_argument = NULL_TREE;
   bool saved_greater_than_is_operator_p;
   bool saved_local_variables_forbidden_p;
+  bool non_constant_p, is_direct_init;
 
   /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
      set correctly.  */
@@ -16401,7 +17361,9 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   if (template_parm_p)
     push_deferring_access_checks (dk_no_deferred);
   default_argument
-    = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+    = cp_parser_initializer (parser, &is_direct_init, &non_constant_p);
+  if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
+    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   if (template_parm_p)
     pop_deferring_access_checks ();
   parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
@@ -16418,7 +17380,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
 static void
 cp_parser_function_body (cp_parser *parser)
 {
-  cp_parser_compound_statement (parser, NULL, false);
+  cp_parser_compound_statement (parser, NULL, false, true);
 }
 
 /* Parse a ctor-initializer-opt followed by a function-body.  Return
@@ -16559,16 +17521,6 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
        = cp_parser_constant_expression (parser,
                                        /*allow_non_constant_p=*/true,
                                        non_constant_p);
-      if (!*non_constant_p)
-       {
-         /* We only want to fold if this is really a constant
-            expression.  FIXME Actually, we don't want to fold here, but in
-            cp_finish_decl.  */
-         tree folded = fold_non_dependent_expr (initializer);
-         folded = maybe_constant_value (folded);
-         if (TREE_CONSTANT (folded))
-           initializer = folded;
-       }
     }
   else
     initializer = cp_parser_braced_list (parser, non_constant_p);
@@ -16623,8 +17575,13 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
    GNU Extension:
 
    initializer-list:
-     identifier : initializer-clause
-     initializer-list, identifier : initializer-clause
+     designation initializer-clause ...[opt]
+     initializer-list , designation initializer-clause ...[opt]
+
+   designation:
+     . identifier =
+     identifier :
+     [ constant-expression ] =
 
    Returns a VEC of constructor_elt.  The VALUE of each elt is an expression
    for the initializer.  If the INDEX of the elt is non-NULL, it is the
@@ -16643,7 +17600,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
   while (true)
     {
       cp_token *token;
-      tree identifier;
+      tree designator;
       tree initializer;
       bool clause_non_constant_p;
 
@@ -16658,12 +17615,41 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          pedwarn (input_location, OPT_pedantic, 
                   "ISO C++ does not allow designated initializers");
          /* Consume the identifier.  */
-         identifier = cp_lexer_consume_token (parser->lexer)->u.value;
+         designator = cp_lexer_consume_token (parser->lexer)->u.value;
          /* Consume the `:'.  */
          cp_lexer_consume_token (parser->lexer);
        }
+      /* Also handle the C99 syntax, '. id ='.  */
+      else if (cp_parser_allow_gnu_extensions_p (parser)
+              && cp_lexer_next_token_is (parser->lexer, CPP_DOT)
+              && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
+              && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
+       {
+         /* Warn the user that they are using an extension.  */
+         pedwarn (input_location, OPT_pedantic,
+                  "ISO C++ does not allow C99 designated initializers");
+         /* Consume the `.'.  */
+         cp_lexer_consume_token (parser->lexer);
+         /* Consume the identifier.  */
+         designator = cp_lexer_consume_token (parser->lexer)->u.value;
+         /* Consume the `='.  */
+         cp_lexer_consume_token (parser->lexer);
+       }
+      /* Also handle C99 array designators, '[ const ] ='.  */
+      else if (cp_parser_allow_gnu_extensions_p (parser)
+              && !c_dialect_objc ()
+              && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+       {
+         /* In C++11, [ could start a lambda-introducer.  */
+         cp_parser_parse_tentatively (parser);
+         cp_lexer_consume_token (parser->lexer);
+         designator = cp_parser_constant_expression (parser, false, NULL);
+         cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+         cp_parser_require (parser, CPP_EQ, RT_EQ);
+         cp_parser_parse_definitely (parser);
+       }
       else
-       identifier = NULL_TREE;
+       designator = NULL_TREE;
 
       /* Parse the initializer.  */
       initializer = cp_parser_initializer_clause (parser,
@@ -16684,7 +17670,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
         }
 
       /* Add it to the vector.  */
-      CONSTRUCTOR_APPEND_ELT(v, identifier, initializer);
+      CONSTRUCTOR_APPEND_ELT (v, designator, initializer);
 
       /* If the next token is not a comma, we have reached the end of
         the list.  */
@@ -16881,13 +17867,15 @@ cp_parser_class_name (cp_parser *parser,
    Returns the TREE_TYPE representing the class.  */
 
 static tree
-cp_parser_class_specifier (cp_parser* parser)
+cp_parser_class_specifier_1 (cp_parser* parser)
 {
   tree type;
   tree attributes = NULL_TREE;
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
   bool saved_in_function_body;
+  unsigned char in_statement;
+  bool in_switch_statement_p;
   bool saved_in_unbraced_linkage_specification_p;
   tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
@@ -16941,6 +17929,12 @@ 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;
+  /* Or in a loop.  */
+  in_statement = parser->in_statement;
+  parser->in_statement = 0;
+  /* Or in a switch.  */
+  in_switch_statement_p = parser->in_switch_statement_p;
+  parser->in_switch_statement_p = false;
   /* We are not immediately inside an extern "lang" block.  */
   saved_in_unbraced_linkage_specification_p
     = parser->in_unbraced_linkage_specification_p;
@@ -17086,11 +18080,12 @@ cp_parser_class_specifier (cp_parser* parser)
      there is no need to delay the parsing of `A::B::f'.  */
   if (--parser->num_classes_being_defined == 0)
     {
-      tree fn;
+      tree decl;
       tree class_type = NULL_TREE;
       tree pushed_scope = NULL_TREE;
       unsigned ix;
       cp_default_arg_entry *e;
+      tree save_ccp, save_ccr;
 
       /* In a first pass, parse default arguments to the functions.
         Then, in a second pass, parse the bodies of the functions.
@@ -17105,7 +18100,7 @@ cp_parser_class_specifier (cp_parser* parser)
       FOR_EACH_VEC_ELT (cp_default_arg_entry, unparsed_funs_with_default_args,
                        ix, e)
        {
-         fn = e->decl;
+         decl = e->decl;
          /* If there are default arguments that have not yet been processed,
             take care of them now.  */
          if (class_type != e->class_type)
@@ -17116,18 +18111,36 @@ cp_parser_class_specifier (cp_parser* parser)
              pushed_scope = push_scope (class_type);
            }
          /* Make sure that any template parameters are in scope.  */
-         maybe_begin_member_template_processing (fn);
+         maybe_begin_member_template_processing (decl);
          /* Parse the default argument expressions.  */
-         cp_parser_late_parsing_default_args (parser, fn);
+         cp_parser_late_parsing_default_args (parser, decl);
          /* Remove any template parameters from the symbol table.  */
          maybe_end_member_template_processing ();
        }
+      VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
+      /* Now parse any NSDMIs.  */
+      save_ccp = current_class_ptr;
+      save_ccr = current_class_ref;
+      FOR_EACH_VEC_ELT (tree, unparsed_nsdmis, ix, decl)
+       {
+         if (class_type != DECL_CONTEXT (decl))
+           {
+             if (pushed_scope)
+               pop_scope (pushed_scope);
+             class_type = DECL_CONTEXT (decl);
+             pushed_scope = push_scope (class_type);
+           }
+         inject_this_parameter (class_type, TYPE_UNQUALIFIED);
+         cp_parser_late_parsing_nsdmi (parser, decl);
+       }
+      VEC_truncate (tree, unparsed_nsdmis, 0);
+      current_class_ptr = save_ccp;
+      current_class_ref = save_ccr;
       if (pushed_scope)
        pop_scope (pushed_scope);
-      VEC_truncate (cp_default_arg_entry, unparsed_funs_with_default_args, 0);
       /* Now parse the body of the functions.  */
-      FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, fn)
-       cp_parser_late_parsing_for_member (parser, fn);
+      FOR_EACH_VEC_ELT (tree, unparsed_funs_with_definitions, ix, decl)
+       cp_parser_late_parsing_for_member (parser, decl);
       VEC_truncate (tree, unparsed_funs_with_definitions, 0);
     }
 
@@ -17135,6 +18148,8 @@ cp_parser_class_specifier (cp_parser* parser)
   pop_deferring_access_checks ();
 
   /* Restore saved state.  */
+  parser->in_switch_statement_p = in_switch_statement_p;
+  parser->in_statement = in_statement;
   parser->in_function_body = saved_in_function_body;
   parser->num_template_parameter_lists
     = saved_num_template_parameter_lists;
@@ -17144,14 +18159,27 @@ cp_parser_class_specifier (cp_parser* parser)
   return type;
 }
 
+static tree
+cp_parser_class_specifier (cp_parser* parser)
+{
+  tree ret;
+  timevar_push (TV_PARSE_STRUCT);
+  ret = cp_parser_class_specifier_1 (parser);
+  timevar_pop (TV_PARSE_STRUCT);
+  return ret;
+}
+
 /* Parse a class-head.
 
    class-head:
      class-key identifier [opt] base-clause [opt]
-     class-key nested-name-specifier identifier base-clause [opt]
+     class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt]
      class-key nested-name-specifier [opt] template-id
        base-clause [opt]
 
+   class-virt-specifier:
+     final
+
    GNU Extensions:
      class-key attributes identifier [opt] base-clause [opt]
      class-key attributes nested-name-specifier identifier base-clause [opt]
@@ -17183,6 +18211,7 @@ cp_parser_class_head (cp_parser* parser,
   tree id = NULL_TREE;
   tree type = NULL_TREE;
   tree attributes;
+  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   bool template_id_p = false;
   bool qualified_p = false;
   bool invalid_nested_name_p = false;
@@ -17326,8 +18355,11 @@ cp_parser_class_head (cp_parser* parser,
   pop_deferring_access_checks ();
 
   if (id)
-    cp_parser_check_for_invalid_template_id (parser, id,
-                                            type_start_token->location);
+    {
+      cp_parser_check_for_invalid_template_id (parser, id,
+                                               type_start_token->location);
+    }
+  virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
 
   /* If it's not a `:' or a `{' then we can't really be looking at a
      class-head, since a class-head only appears as part of a
@@ -17343,6 +18375,13 @@ cp_parser_class_head (cp_parser* parser,
   /* At this point, we're going ahead with the class-specifier, even
      if some other problem occurs.  */
   cp_parser_commit_to_tentative_parse (parser);
+  if (virt_specifiers & VIRT_SPEC_OVERRIDE)
+    {
+      cp_parser_error (parser,
+                       "cannot specify %<override%> for a class");
+      type = error_mark_node;
+      goto out;
+    }
   /* Issue the error about the overly-qualified name now.  */
   if (qualified_p)
     {
@@ -17559,6 +18598,8 @@ cp_parser_class_head (cp_parser* parser,
   if (type)
     DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
   *attributes_p = attributes;
+  if (type && (virt_specifiers & VIRT_SPEC_FINAL))
+    CLASSTYPE_FINAL (type) = 1;
  out:
   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   return type;
@@ -17652,6 +18693,7 @@ cp_parser_member_specification_opt (cp_parser* parser)
      :: [opt] nested-name-specifier template [opt] unqualified-id ;
      using-declaration
      template-declaration
+     alias-declaration
 
    member-declarator-list:
      member-declarator
@@ -17719,10 +18761,25 @@ cp_parser_member_declaration (cp_parser* parser)
   /* Check for a using-declaration.  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
     {
-      /* Parse the using-declaration.  */
-      cp_parser_using_declaration (parser,
-                                  /*access_declaration_p=*/false);
-      return;
+      if (cxx_dialect < cxx0x)
+       {
+         /* Parse the using-declaration.  */
+         cp_parser_using_declaration (parser,
+                                      /*access_declaration_p=*/false);
+         return;
+       }
+      else
+       {
+         tree decl;
+         cp_parser_parse_tentatively (parser);
+         decl = cp_parser_alias_declaration (parser);
+         if (cp_parser_parse_definitely (parser))
+           finish_member_declaration (decl);
+         else
+           cp_parser_using_declaration (parser,
+                                        /*access_declaration_p=*/false);
+         return;
+       }
     }
 
   /* Check for @defs.  */
@@ -17799,9 +18856,10 @@ 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_at (decl_spec_token_start->location,
-                          "a class-key must be used when declaring a friend");
+              if (!declares_class_or_enum && cxx_dialect < cxx0x)
+                pedwarn (decl_spec_token_start->location, OPT_pedantic,
+                         "in C++03 a class-key must be used "
+                         "when declaring a friend");
               /* In this case:
 
                    template <typename T> struct A {
@@ -17810,10 +18868,12 @@ cp_parser_member_declaration (cp_parser* parser)
 
                  A<T>::B will be represented by a TYPENAME_TYPE, and
                  therefore not recognized by check_tag_decl.  */
-              if (!type
-                  && decl_specifiers.type
-                  && TYPE_P (decl_specifiers.type))
-                type = decl_specifiers.type;
+              if (!type)
+                {
+                  type = decl_specifiers.type;
+                  if (type && TREE_CODE (type) == TYPE_DECL)
+                    type = TREE_TYPE (type);
+                }
               if (!type || !TYPE_P (type))
                 error_at (decl_spec_token_start->location,
                           "friend declaration does not name a class or "
@@ -17975,12 +19035,38 @@ cp_parser_member_declaration (cp_parser* parser)
                     constant-initializer.  When we call `grokfield', it will
                     perform more stringent semantics checks.  */
                  initializer_token_start = cp_lexer_peek_token (parser->lexer);
-                 if (function_declarator_p (declarator))
+                 if (function_declarator_p (declarator)
+                     || (decl_specifiers.type
+                         && TREE_CODE (decl_specifiers.type) == TYPE_DECL
+                         && (TREE_CODE (TREE_TYPE (decl_specifiers.type))
+                             == FUNCTION_TYPE)))
                    initializer = cp_parser_pure_specifier (parser);
+                 else if (decl_specifiers.storage_class != sc_static)
+                   initializer = cp_parser_save_nsdmi (parser);
+                 else if (cxx_dialect >= cxx0x)
+                   {
+                     bool nonconst;
+                     /* Don't require a constant rvalue in C++11, since we
+                        might want a reference constant.  We'll enforce
+                        constancy later.  */
+                     cp_lexer_consume_token (parser->lexer);
+                     /* Parse the initializer.  */
+                     initializer = cp_parser_initializer_clause (parser,
+                                                                 &nonconst);
+                   }
                  else
                    /* Parse the initializer.  */
                    initializer = cp_parser_constant_initializer (parser);
                }
+             else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+                      && !function_declarator_p (declarator))
+               {
+                 bool x;
+                 if (decl_specifiers.storage_class != sc_static)
+                   initializer = cp_parser_save_nsdmi (parser);
+                 else
+                   initializer = cp_parser_initializer (parser, &x, &x);
+               }
              /* Otherwise, there is no initializer.  */
              else
                initializer = NULL_TREE;
@@ -18065,6 +19151,11 @@ cp_parser_member_declaration (cp_parser* parser)
 
              if (TREE_CODE (decl) == FUNCTION_DECL)
                cp_parser_save_default_args (parser, decl);
+             else if (TREE_CODE (decl) == FIELD_DECL
+                      && !DECL_C_BIT_FIELD (decl)
+                      && DECL_INITIAL (decl))
+               /* Add DECL to the queue of NSDMI to be parsed later.  */
+               VEC_safe_push (tree, gc, unparsed_nsdmis, decl);
            }
 
          if (assume_semicolon)
@@ -18210,12 +19301,11 @@ cp_parser_base_clause (cp_parser* parser)
         }
 
       /* Add BASE to the front of the list.  */
-      if (base != error_mark_node)
+      if (base && base != error_mark_node)
        {
           if (pack_expansion_p)
             /* Make this a pack expansion type. */
             TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
-          
 
           if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
             {
@@ -18357,19 +19447,27 @@ cp_parser_base_specifier (cp_parser* parser)
   class_scope_p = (parser->scope && TYPE_P (parser->scope));
   template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
 
-  /* Finally, look for the class-name.  */
-  type = cp_parser_class_name (parser,
-                              class_scope_p,
-                              template_p,
-                              typename_type,
-                              /*check_dependency_p=*/true,
-                              /*class_head_p=*/false,
-                              /*is_declaration=*/true);
+  if (!parser->scope
+      && cp_lexer_next_token_is_decltype (parser->lexer))
+    /* DR 950 allows decltype as a base-specifier.  */
+    type = cp_parser_decltype (parser);
+  else
+    {
+      /* Otherwise, look for the class-name.  */
+      type = cp_parser_class_name (parser,
+                                  class_scope_p,
+                                  template_p,
+                                  typename_type,
+                                  /*check_dependency_p=*/true,
+                                  /*class_head_p=*/false,
+                                  /*is_declaration=*/true);
+      type = TREE_TYPE (type);
+    }
 
   if (type == error_mark_node)
     return error_mark_node;
 
-  return finish_base_specifier (TREE_TYPE (type), access, virtual_p);
+  return finish_base_specifier (type, access, virtual_p);
 }
 
 /* Exception handling [gram.exception] */
@@ -18516,7 +19614,7 @@ cp_parser_try_block (cp_parser* parser)
 
   cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
   try_block = begin_try_block ();
-  cp_parser_compound_statement (parser, NULL, true);
+  cp_parser_compound_statement (parser, NULL, true, false);
   finish_try_block (try_block);
   cp_parser_handler_seq (parser);
   finish_handler_sequence (try_block);
@@ -18593,7 +19691,7 @@ cp_parser_handler (cp_parser* parser)
   declaration = cp_parser_exception_declaration (parser);
   finish_handler_parms (declaration, handler);
   cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
-  cp_parser_compound_statement (parser, NULL, false);
+  cp_parser_compound_statement (parser, NULL, false, false);
   finish_handler (handler);
 }
 
@@ -19359,6 +20457,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
   if (DECL_P (decl))
     check_accessibility_of_qualified_id (decl, object_type, parser->scope);
 
+  maybe_record_typedef_use (decl);
+
   return decl;
 }
 
@@ -19632,7 +20732,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
   /* 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))
+      && CLASS_TYPE_P (nested_name_specifier))
     {
       tree id = cp_parser_unqualified_id (parser,
                                          /*template_keyword_p=*/false,
@@ -19789,8 +20889,17 @@ cp_parser_function_definition_from_specifiers_and_declarator
        pop_nested_class ();
     }
   else
-    fn = cp_parser_function_definition_after_declarator (parser,
+    {
+      timevar_id_t tv;
+      if (DECL_DECLARED_INLINE_P (current_function_decl))
+        tv = TV_PARSE_INLINE;
+      else
+        tv = TV_PARSE_FUNC;
+      timevar_push (tv);
+      fn = cp_parser_function_definition_after_declarator (parser,
                                                         /*inline_p=*/false);
+      timevar_pop (tv);
+    }
 
   return fn;
 }
@@ -19852,12 +20961,19 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
 
   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))
+  /* If the next token is `try', `__transaction_atomic', or
+     `__transaction_relaxed`, then we are looking at either function-try-block
+     or function-transaction-block.  Note that all of these include the
+     function-body.  */
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_ATOMIC))
+    ctor_initializer_p = cp_parser_function_transaction (parser,
+       RID_TRANSACTION_ATOMIC);
+  else if (cp_lexer_next_token_is_keyword (parser->lexer,
+      RID_TRANSACTION_RELAXED))
+    ctor_initializer_p = cp_parser_function_transaction (parser,
+       RID_TRANSACTION_RELAXED);
+  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
     ctor_initializer_p = cp_parser_function_try_block (parser);
-  /* A function-try-block includes the function-body, so we only do
-     this next part if we're not processing a function-try-block.  */
   else
     ctor_initializer_p
       = cp_parser_ctor_initializer_opt_and_function_body (parser);
@@ -19961,6 +21077,9 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   if (cp_lexer_next_token_is_keyword (parser->lexer,
                                      RID_TEMPLATE))
     cp_parser_template_declaration_after_export (parser, member_p);
+  else if (cxx_dialect >= cxx0x
+          && cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
+    decl = cp_parser_alias_declaration (parser);
   else
     {
       /* There are no access checks when parsing a template, as we do not
@@ -19995,6 +21114,33 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   /* Finish up.  */
   finish_template_decl (parameter_list);
 
+  /* Check the template arguments for a literal operator template.  */
+  if (decl
+      && (TREE_CODE (decl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (decl))
+      && UDLIT_OPER_P (DECL_NAME (decl)))
+    {
+      bool ok = true;
+      if (parameter_list == NULL_TREE)
+       ok = false;
+      else
+       {
+         int num_parms = TREE_VEC_LENGTH (parameter_list);
+         if (num_parms != 1)
+           ok = false;
+         else
+           {
+             tree parm_list = TREE_VEC_ELT (parameter_list, 0);
+             tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
+             if (TREE_TYPE (parm) != char_type_node
+                 || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+               ok = false;
+           }
+       }
+      if (!ok)
+       error ("literal operator template %qD has invalid parameter list."
+              "  Expected non-type template argument pack <char...>",
+              decl);
+    }
   /* Register member declarations.  */
   if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
     finish_member_declaration (decl);
@@ -20105,8 +21251,15 @@ cp_parser_single_declaration (cp_parser* parser,
     }
 
   /* 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 (!decl_specifiers.any_type_specifiers_p
+      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
+    {
+      /* cp_parser_parse_and_diagnose_invalid_type_name calls
+        cp_parser_skip_to_end_of_block_or_statement, so don't try to parse
+        the rest of this declaration.  */
+      decl = error_mark_node;
+      goto out;
+    }
 
   /* If it's not a template class, try for a template function.  If
      the next token is a `;', then this declaration does not declare
@@ -20140,6 +21293,13 @@ cp_parser_single_declaration (cp_parser* parser,
       }
     }
 
+  /* Look for a trailing `;' after the declaration.  */
+  if (!function_definition_p
+      && (decl == error_mark_node
+         || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
+    cp_parser_skip_to_end_of_block_or_statement (parser);
+
+ out:
   pop_deferring_access_checks ();
 
   /* Clear any current qualification; whatever comes next is the start
@@ -20147,11 +21307,6 @@ cp_parser_single_declaration (cp_parser* parser,
   parser->scope = NULL_TREE;
   parser->qualifying_scope = NULL_TREE;
   parser->object_scope = NULL_TREE;
-  /* Look for a trailing `;' after the declaration.  */
-  if (!function_definition_p
-      && (decl == error_mark_node
-         || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
-    cp_parser_skip_to_end_of_block_or_statement (parser);
 
   return decl;
 }
@@ -20183,7 +21338,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       if (TREE_CODE (type) == TYPE_DECL)
        type = TREE_TYPE (type);
-      return finish_compound_literal (type, expression_list);
+      return finish_compound_literal (type, expression_list,
+                                     tf_warning_or_error);
     }
 
 
@@ -20284,8 +21440,33 @@ cp_parser_save_member_function_body (cp_parser* parser,
   return fn;
 }
 
+/* Save the tokens that make up the in-class initializer for a non-static
+   data member.  Returns a DEFAULT_ARG.  */
+
+static tree
+cp_parser_save_nsdmi (cp_parser* parser)
+{
+  /* Save away the tokens that make up the body of the
+     function.  */
+  cp_token *first = parser->lexer->next_token;
+  cp_token *last;
+  tree node;
+
+  /* Save tokens until the next comma or semicolon.  */
+  cp_parser_cache_group (parser, CPP_COMMA, /*depth=*/0);
+
+  last = parser->lexer->next_token;
+
+  node = make_node (DEFAULT_ARG);
+  DEFARG_TOKENS (node) = cp_token_cache_new (first, last);
+  DEFARG_INSTANTIATIONS (node) = NULL;
+
+  return node;
+}
+
+
 /* Parse a template-argument-list, as well as the trailing ">" (but
-   not the opening ">").  See cp_parser_template_argument_list for the
+   not the opening "<").  See cp_parser_template_argument_list for the
    return value.  */
 
 static tree
@@ -20397,6 +21578,7 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
 static void
 cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
 {
+  timevar_push (TV_PARSE_INMETH);
   /* If this member is a template, get the underlying
      FUNCTION_DECL.  */
   if (DECL_FUNCTION_TEMPLATE_P (member_function))
@@ -20463,6 +21645,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
 
   /* Restore the queue.  */
   pop_unparsed_function_queues (parser);
+  timevar_pop (TV_PARSE_INMETH);
 }
 
 /* If DECL contains any default args, remember it on the unparsed
@@ -20487,6 +21670,83 @@ cp_parser_save_default_args (cp_parser* parser, tree decl)
       }
 }
 
+/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
+   which is either a FIELD_DECL or PARM_DECL.  Parse it and return
+   the result.  For a PARM_DECL, PARMTYPE is the corresponding type
+   from the parameter-type-list.  */
+
+static tree
+cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
+                                     tree default_arg, tree parmtype)
+{
+  cp_token_cache *tokens;
+  tree parsed_arg;
+  bool dummy;
+
+  /* Push the saved tokens for the default argument onto the parser's
+     lexer stack.  */
+  tokens = DEFARG_TOKENS (default_arg);
+  cp_parser_push_lexer_for_tokens (parser, tokens);
+
+  start_lambda_scope (decl);
+
+  /* Parse the default argument.  */
+  parsed_arg = cp_parser_initializer (parser, &dummy, &dummy);
+  if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
+    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+
+  finish_lambda_scope ();
+
+  if (!processing_template_decl)
+    {
+      /* In a non-template class, check conversions now.  In a template,
+        we'll wait and instantiate these as needed.  */
+      if (TREE_CODE (decl) == PARM_DECL)
+       parsed_arg = check_default_argument (parmtype, parsed_arg);
+      else
+       {
+         int flags = LOOKUP_IMPLICIT;
+         if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg)
+             && CONSTRUCTOR_IS_DIRECT_INIT (parsed_arg))
+           flags = LOOKUP_NORMAL;
+         parsed_arg = digest_init_flags (TREE_TYPE (decl), parsed_arg, flags);
+       }
+    }
+
+  /* If the token stream has not been completely used up, then
+     there was extra junk after the end of the default
+     argument.  */
+  if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+    {
+      if (TREE_CODE (decl) == PARM_DECL)
+       cp_parser_error (parser, "expected %<,%>");
+      else
+       cp_parser_error (parser, "expected %<;%>");
+    }
+
+  /* Revert to the main lexer.  */
+  cp_parser_pop_lexer (parser);
+
+  return parsed_arg;
+}
+
+/* FIELD is a non-static data member with an initializer which we saved for
+   later; parse it now.  */
+
+static void
+cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
+{
+  tree def;
+
+  push_unparsed_function_queues (parser);
+  def = cp_parser_late_parse_one_default_arg (parser, field,
+                                             DECL_INITIAL (field),
+                                             NULL_TREE);
+  pop_unparsed_function_queues (parser);
+
+  DECL_INITIAL (field) = def;
+}
+
 /* FN is a FUNCTION_DECL which may contains a parameter with an
    unparsed DEFAULT_ARG.  Parse the default args now.  This function
    assumes that the current scope is the scope in which the default
@@ -20509,13 +21769,14 @@ 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;
 
+  push_defarg_context (fn);
+
   for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
         parmdecl = DECL_ARGUMENTS (fn);
        parm && parm != void_list_node;
        parm = TREE_CHAIN (parm),
         parmdecl = DECL_CHAIN (parmdecl))
     {
-      cp_token_cache *tokens;
       tree default_arg = TREE_PURPOSE (parm);
       tree parsed_arg;
       VEC(tree,gc) *insts;
@@ -20530,43 +21791,25 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
           already declared with default arguments.  */
        continue;
 
-       /* Push the saved tokens for the default argument onto the parser's
-         lexer stack.  */
-      tokens = DEFARG_TOKENS (default_arg);
-      cp_parser_push_lexer_for_tokens (parser, tokens);
-
-      start_lambda_scope (parmdecl);
-
-      /* Parse the assignment-expression.  */
-      parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+      parsed_arg
+       = cp_parser_late_parse_one_default_arg (parser, parmdecl,
+                                               default_arg,
+                                               TREE_VALUE (parm));
       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);
-
       TREE_PURPOSE (parm) = parsed_arg;
 
       /* Update any instantiations we've already created.  */
       for (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
           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.  */
-      if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
-       cp_parser_error (parser, "expected %<,%>");
-
-      /* Revert to the main lexer.  */
-      cp_parser_pop_lexer (parser);
     }
 
+  pop_defarg_context ();
+
   /* Make sure no default arg is missing.  */
   check_default_args (fn);
 
@@ -20759,15 +22002,14 @@ cp_parser_set_storage_class (cp_parser *parser,
     decl_specs->conflicting_specifiers_p = true;
 }
 
-/* Update the DECL_SPECS to reflect the TYPE_SPEC.  If USER_DEFINED_P
-   is true, the type is a user-defined type; otherwise it is a
-   built-in type specified by a keyword.  */
+/* Update the DECL_SPECS to reflect the TYPE_SPEC.  If TYPE_DEFINITION_P
+   is true, the type is a class or enum definition.  */
 
 static void
 cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
                              tree type_spec,
                              location_t location,
-                             bool user_defined_p)
+                             bool type_definition_p)
 {
   decl_specs->any_specifiers_p = true;
 
@@ -20777,7 +22019,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
      declarations so that G++ can work with system headers that are not
      C++-safe.  */
   if (decl_specs->specs[(int) ds_typedef]
-      && !user_defined_p
+      && !type_definition_p
       && (type_spec == boolean_type_node
          || type_spec == char16_type_node
          || type_spec == char32_type_node
@@ -20792,7 +22034,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
       if (!decl_specs->type)
        {
          decl_specs->type = type_spec;
-         decl_specs->user_defined_type_p = false;
+         decl_specs->type_definition_p = false;
          decl_specs->type_location = location;
        }
     }
@@ -20801,7 +22043,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
   else
     {
       decl_specs->type = type_spec;
-      decl_specs->user_defined_type_p = user_defined_p;
+      decl_specs->type_definition_p = type_definition_p;
       decl_specs->redefined_builtin_type = NULL_TREE;
       decl_specs->type_location = location;
     }
@@ -20888,6 +22130,12 @@ cp_parser_required_error (cp_parser *parser,
       case RT_AT_THROW:
        cp_parser_error (parser, "expected %<@throw%>");
        return;
+      case RT_TRANSACTION_ATOMIC:
+       cp_parser_error (parser, "expected %<__transaction_atomic%>");
+       return;
+      case RT_TRANSACTION_RELAXED:
+       cp_parser_error (parser, "expected %<__transaction_relaxed%>");
+       return;
       default:
        break;
     }
@@ -21118,6 +22366,10 @@ cp_parser_token_starts_function_definition_p (cp_token* token)
          || token->type == CPP_COLON
          /* A function-try-block begins with `try'.  */
          || token->keyword == RID_TRY
+         /* A function-transaction-block begins with `__transaction_atomic'
+            or `__transaction_relaxed'.  */
+         || token->keyword == RID_TRANSACTION_ATOMIC
+         || token->keyword == RID_TRANSACTION_RELAXED
          /* The named return value extension begins with `return'.  */
          || token->keyword == RID_RETURN);
 }
@@ -21313,6 +22565,12 @@ cp_parser_cache_group (cp_parser *parser,
           kind of syntax error.  */
        return true;
 
+      /* If we're caching something finished by a comma (or semicolon),
+        such as an NSDMI, don't consume the comma.  */
+      if (end == CPP_COMMA
+         && (token->type == CPP_SEMICOLON || token->type == CPP_COMMA))
+       return false;
+
       /* Consume the token.  */
       cp_lexer_consume_token (parser->lexer);
       /* See if it starts a new group.  */
@@ -21382,6 +22640,8 @@ cp_parser_commit_to_tentative_parse (cp_parser* parser)
 static void
 cp_parser_abort_tentative_parse (cp_parser* parser)
 {
+  gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED
+             || errorcount > 0);
   cp_parser_simulate_error (parser);
   /* Now, pretend that we want to see if the construct was
      successfully parsed.  */
@@ -21528,7 +22788,7 @@ cp_parser_objc_message_expression (cp_parser* parser)
   messageargs = cp_parser_objc_message_args (parser);
   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
-  return objc_build_message_expr (build_tree_list (receiver, messageargs));
+  return objc_build_message_expr (receiver, messageargs);
 }
 
 /* Parse an objc-message-receiver.
@@ -21854,7 +23114,21 @@ static void
 cp_parser_objc_class_declaration (cp_parser* parser)
 {
   cp_lexer_consume_token (parser->lexer);  /* Eat '@class'.  */
-  objc_declare_class (cp_parser_objc_identifier_list (parser));
+  while (true)
+    {
+      tree id;
+      
+      id = cp_parser_identifier (parser);
+      if (id == error_mark_node)
+       break;
+      
+      objc_declare_class (id);
+
+      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+       cp_lexer_consume_token (parser->lexer);
+      else
+       break;
+    }
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 }
 
@@ -22185,7 +23459,8 @@ cp_parser_objc_interstitial_code (cp_parser* parser)
   /* If the next token is `extern' and the following token is a string
      literal, then we have a linkage specification.  */
   if (token->keyword == RID_EXTERN
-      && cp_parser_is_string_literal (cp_lexer_peek_nth_token (parser->lexer, 2)))
+      && cp_parser_is_pure_string_literal
+        (cp_lexer_peek_nth_token (parser->lexer, 2)))
     cp_parser_linkage_specification (parser);
   /* Handle #pragma, if any.  */
   else if (token->type == CPP_PRAGMA)
@@ -22337,7 +23612,8 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
              token = cp_lexer_peek_token (parser->lexer);
              continue;
            }
-         objc_start_method_definition (is_class_method, sig, attribute);
+         objc_start_method_definition (is_class_method, sig, attribute,
+                                       NULL_TREE);
 
          /* For historical reasons, we accept an optional semicolon.  */
          if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -22495,7 +23771,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
                              NULL_TREE, attributes);
 
          /* Add the instance variable.  */
-         objc_add_instance_variable (decl);
+         if (decl != error_mark_node && decl != NULL_TREE)
+           objc_add_instance_variable (decl);
 
          /* Reset PREFIX_ATTRIBUTES.  */
          while (attributes && TREE_CHAIN (attributes) != first_attribute)
@@ -22543,7 +23820,8 @@ cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
     {
       tok = cp_lexer_peek_token (parser->lexer);
       error_at (tok->location, "identifier expected after %<@protocol%>");
-      goto finish;
+      cp_parser_consume_semicolon_at_end_of_statement (parser);
+      return;
     }
 
   /* See if we have a forward declaration or a definition.  */
@@ -22552,9 +23830,21 @@ cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
   /* Try a forward declaration first.  */
   if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
     {
-      objc_declare_protocols (cp_parser_objc_identifier_list (parser), 
-                             attributes);
-     finish:
+      while (true)
+       {
+         tree id;
+         
+         id = cp_parser_identifier (parser);
+         if (id == error_mark_node)
+           break;
+         
+         objc_declare_protocol (id, attributes);
+         
+         if(cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+           cp_lexer_consume_token (parser->lexer);
+         else
+           break;
+       }
       cp_parser_consume_semicolon_at_end_of_statement (parser);
     }
 
@@ -22779,7 +24069,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
   /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
      node, lest it get absorbed into the surrounding block.  */
   stmt = push_stmt_list ();
-  cp_parser_compound_statement (parser, NULL, false);
+  cp_parser_compound_statement (parser, NULL, false, false);
   objc_begin_try_stmt (location, pop_stmt_list (stmt));
 
   while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
@@ -22835,7 +24125,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
             forget about the closing parenthesis and keep going.  */
        }
       objc_begin_catch_clause (parameter_declaration);
-      cp_parser_compound_statement (parser, NULL, false);
+      cp_parser_compound_statement (parser, NULL, false, false);
       objc_finish_catch_clause ();
     }
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
@@ -22845,7 +24135,7 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
       /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
         node, lest it get absorbed into the surrounding block.  */
       stmt = push_stmt_list ();
-      cp_parser_compound_statement (parser, NULL, false);
+      cp_parser_compound_statement (parser, NULL, false, false);
       objc_build_finally_clause (location, pop_stmt_list (stmt));
     }
 
@@ -22876,7 +24166,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser)
   /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
      node, lest it get absorbed into the surrounding block.  */
   stmt = push_stmt_list ();
-  cp_parser_compound_statement (parser, NULL, false);
+  cp_parser_compound_statement (parser, NULL, false, false);
 
   return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
 }
@@ -23150,7 +24440,7 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
                  break;
                }
              cp_lexer_consume_token (parser->lexer); /* eat the = */
-             if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+             if (!cp_parser_objc_selector_p (cp_lexer_peek_token (parser->lexer)->type))
                {
                  cp_parser_error (parser, "expected identifier");
                  syntax_error = true;
@@ -23159,10 +24449,12 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
              if (keyword == RID_SETTER)
                {
                  if (property_setter_ident != NULL_TREE)
-                   cp_parser_error (parser, "the %<setter%> attribute may only be specified once");
+                   {
+                     cp_parser_error (parser, "the %<setter%> attribute may only be specified once");
+                     cp_lexer_consume_token (parser->lexer);
+                   }
                  else
-                   property_setter_ident = cp_lexer_peek_token (parser->lexer)->u.value;
-                 cp_lexer_consume_token (parser->lexer);
+                   property_setter_ident = cp_parser_objc_selector (parser);
                  if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
                    cp_parser_error (parser, "setter name must terminate with %<:%>");
                  else
@@ -23171,10 +24463,12 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
              else
                {
                  if (property_getter_ident != NULL_TREE)
-                   cp_parser_error (parser, "the %<getter%> attribute may only be specified once");
+                   {
+                     cp_parser_error (parser, "the %<getter%> attribute may only be specified once");
+                     cp_lexer_consume_token (parser->lexer);
+                   }
                  else
-                   property_getter_ident = cp_lexer_peek_token (parser->lexer)->u.value;
-                 cp_lexer_consume_token (parser->lexer);
+                   property_getter_ident = cp_parser_objc_selector (parser);
                }
              break;
            default:
@@ -23369,13 +24663,19 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
          break;
        case 'f':
-         if (!strcmp ("firstprivate", p))
+         if (!strcmp ("final", p))
+           result = PRAGMA_OMP_CLAUSE_FINAL;
+         else if (!strcmp ("firstprivate", p))
            result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
          break;
        case 'l':
          if (!strcmp ("lastprivate", p))
            result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
          break;
+       case 'm':
+         if (!strcmp ("mergeable", p))
+           result = PRAGMA_OMP_CLAUSE_MERGEABLE;
+         break;
        case 'n':
          if (!strcmp ("nowait", p))
            result = PRAGMA_OMP_CLAUSE_NOWAIT;
@@ -23605,6 +24905,34 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
   return c;
 }
 
+/* OpenMP 3.1:
+   final ( expression ) */
+
+static tree
+cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
+{
+  tree t, c;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  t = cp_parser_condition (parser);
+
+  if (t == error_mark_node
+      || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                          /*or_comma=*/false,
+                                          /*consume_paren=*/true);
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final", location);
+
+  c = build_omp_clause (location, OMP_CLAUSE_FINAL);
+  OMP_CLAUSE_FINAL_EXPR (c) = t;
+  OMP_CLAUSE_CHAIN (c) = list;
+
+  return c;
+}
+
 /* OpenMP 2.5:
    if ( expression ) */
 
@@ -23633,6 +24961,23 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
   return c;
 }
 
+/* OpenMP 3.1:
+   mergeable */
+
+static tree
+cp_parser_omp_clause_mergeable (cp_parser *parser ATTRIBUTE_UNUSED,
+                               tree list, location_t location)
+{
+  tree c;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable",
+                            location);
+
+  c = build_omp_clause (location, OMP_CLAUSE_MERGEABLE);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+}
+
 /* OpenMP 2.5:
    nowait */
 
@@ -23700,7 +25045,12 @@ cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED,
    reduction ( reduction-operator : variable-list )
 
    reduction-operator:
-     One of: + * - & ^ | && || */
+     One of: + * - & ^ | && ||
+
+   OpenMP 3.1:
+
+   reduction-operator:
+     One of: + * - & ^ | && || min max  */
 
 static tree
 cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
@@ -23737,9 +25087,26 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
     case CPP_OR_OR:
       code = TRUTH_ORIF_EXPR;
       break;
+    case CPP_NAME:
+      {
+       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+       const char *p = IDENTIFIER_POINTER (id);
+
+       if (strcmp (p, "min") == 0)
+         {
+           code = MIN_EXPR;
+           break;
+         }
+       if (strcmp (p, "max") == 0)
+         {
+           code = MAX_EXPR;
+           break;
+         }
+      }
+      /* FALLTHROUGH */
     default:
       cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
-                              "%<|%>, %<&&%>, or %<||%>");
+                              "%<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
     resync_fail:
       cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                             /*or_comma=*/false,
@@ -23912,6 +25279,10 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
                                                  token->location);
          c_name = "default";
          break;
+       case PRAGMA_OMP_CLAUSE_FINAL:
+         clauses = cp_parser_omp_clause_final (parser, clauses, token->location);
+         c_name = "final";
+         break;
        case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
          clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
                                            clauses);
@@ -23926,6 +25297,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
                                            clauses);
          c_name = "lastprivate";
          break;
+       case PRAGMA_OMP_CLAUSE_MERGEABLE:
+         clauses = cp_parser_omp_clause_mergeable (parser, clauses,
+                                                   token->location);
+         c_name = "mergeable";
+         break;
        case PRAGMA_OMP_CLAUSE_NOWAIT:
          clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
          c_name = "nowait";
@@ -24036,34 +25412,140 @@ cp_parser_omp_structured_block (cp_parser *parser)
    binop:
      +, *, -, /, &, ^, |, <<, >>
 
-  where x is an lvalue expression with scalar type.  */
+  where x is an lvalue expression with scalar type.
+
+   OpenMP 3.1:
+   # pragma omp atomic new-line
+     update-stmt
+
+   # pragma omp atomic read new-line
+     read-stmt
+
+   # pragma omp atomic write new-line
+     write-stmt
+
+   # pragma omp atomic update new-line
+     update-stmt
+
+   # pragma omp atomic capture new-line
+     capture-stmt
+
+   # pragma omp atomic capture new-line
+     capture-block
+
+   read-stmt:
+     v = x
+   write-stmt:
+     x = expr
+   update-stmt:
+     expression-stmt | x = x binop expr
+   capture-stmt:
+     v = x binop= expr | v = x++ | v = ++x | v = x-- | v = --x
+   capture-block:
+     { v = x; update-stmt; } | { update-stmt; v = x; }
+
+  where x and v are lvalue expressions with scalar type.  */
 
 static void
 cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
 {
-  tree lhs, rhs;
-  enum tree_code code;
+  tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, lhs1 = NULL_TREE;
+  tree rhs1 = NULL_TREE, orig_lhs;
+  enum tree_code code = OMP_ATOMIC, opcode = NOP_EXPR;
+  bool structured_block = false;
 
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+
+      if (!strcmp (p, "read"))
+       code = OMP_ATOMIC_READ;
+      else if (!strcmp (p, "write"))
+       code = NOP_EXPR;
+      else if (!strcmp (p, "update"))
+       code = OMP_ATOMIC;
+      else if (!strcmp (p, "capture"))
+       code = OMP_ATOMIC_CAPTURE_NEW;
+      else
+       p = NULL;
+      if (p)
+       cp_lexer_consume_token (parser->lexer);
+    }
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
+  switch (code)
+    {
+    case OMP_ATOMIC_READ:
+    case NOP_EXPR: /* atomic write */
+      v = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                     /*cast_p=*/false, NULL);
+      if (v == error_mark_node)
+       goto saw_error;
+      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+       goto saw_error;
+      if (code == NOP_EXPR)
+       lhs = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      else
+       lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                         /*cast_p=*/false, NULL);
+      if (lhs == error_mark_node)
+       goto saw_error;
+      if (code == NOP_EXPR)
+       {
+         /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
+            opcode.  */
+         code = OMP_ATOMIC;
+         rhs = lhs;
+         lhs = v;
+         v = NULL_TREE;
+       }
+      goto done;
+    case OMP_ATOMIC_CAPTURE_NEW:
+      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+       {
+         cp_lexer_consume_token (parser->lexer);
+         structured_block = true;
+       }
+      else
+       {
+         v = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                         /*cast_p=*/false, NULL);
+         if (v == error_mark_node)
+           goto saw_error;
+         if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+           goto saw_error;
+       }
+    default:
+      break;
+    }
+
+restart:
   lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
                                    /*cast_p=*/false, NULL);
+  orig_lhs = lhs;
   switch (TREE_CODE (lhs))
     {
     case ERROR_MARK:
       goto saw_error;
 
-    case PREINCREMENT_EXPR:
     case POSTINCREMENT_EXPR:
+      if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
+       code = OMP_ATOMIC_CAPTURE_OLD;
+      /* FALLTHROUGH */
+    case PREINCREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
-      code = PLUS_EXPR;
+      opcode = PLUS_EXPR;
       rhs = integer_one_node;
       break;
 
-    case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
+      if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
+       code = OMP_ATOMIC_CAPTURE_OLD;
+      /* FALLTHROUGH */
+    case PREDECREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
-      code = MINUS_EXPR;
+      opcode = MINUS_EXPR;
       rhs = integer_one_node;
       break;
 
@@ -24081,48 +25563,123 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
     case MODIFY_EXPR:
       if (TREE_CODE (lhs) == MODIFY_EXPR
         && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
-       {
-        /* Undo effects of boolean_increment.  */
-        if (integer_onep (TREE_OPERAND (lhs, 1)))
-          {
-            /* This is pre or post increment.  */
-            rhs = TREE_OPERAND (lhs, 1);
-            lhs = TREE_OPERAND (lhs, 0);
-            code = NOP_EXPR;
-            break;
-          }
-       }
+       {
+         /* Undo effects of boolean_increment.  */
+         if (integer_onep (TREE_OPERAND (lhs, 1)))
+           {
+             /* This is pre or post increment.  */
+             rhs = TREE_OPERAND (lhs, 1);
+             lhs = TREE_OPERAND (lhs, 0);
+             opcode = NOP_EXPR;
+             if (code == OMP_ATOMIC_CAPTURE_NEW
+                 && !structured_block
+                 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
+               code = OMP_ATOMIC_CAPTURE_OLD;
+             break;
+           }
+       }
       /* FALLTHRU */
     default:
       switch (cp_lexer_peek_token (parser->lexer)->type)
        {
        case CPP_MULT_EQ:
-         code = MULT_EXPR;
+         opcode = MULT_EXPR;
          break;
        case CPP_DIV_EQ:
-         code = TRUNC_DIV_EXPR;
+         opcode = TRUNC_DIV_EXPR;
          break;
        case CPP_PLUS_EQ:
-         code = PLUS_EXPR;
+         opcode = PLUS_EXPR;
          break;
        case CPP_MINUS_EQ:
-         code = MINUS_EXPR;
+         opcode = MINUS_EXPR;
          break;
        case CPP_LSHIFT_EQ:
-         code = LSHIFT_EXPR;
+         opcode = LSHIFT_EXPR;
          break;
        case CPP_RSHIFT_EQ:
-         code = RSHIFT_EXPR;
+         opcode = RSHIFT_EXPR;
          break;
        case CPP_AND_EQ:
-         code = BIT_AND_EXPR;
+         opcode = BIT_AND_EXPR;
          break;
        case CPP_OR_EQ:
-         code = BIT_IOR_EXPR;
+         opcode = BIT_IOR_EXPR;
          break;
        case CPP_XOR_EQ:
-         code = BIT_XOR_EXPR;
+         opcode = BIT_XOR_EXPR;
          break;
+       case CPP_EQ:
+         if (structured_block || code == OMP_ATOMIC)
+           {
+             enum cp_parser_prec oprec;
+             cp_token *token;
+             cp_lexer_consume_token (parser->lexer);
+             rhs1 = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                                /*cast_p=*/false, NULL);
+             if (rhs1 == error_mark_node)
+               goto saw_error;
+             token = cp_lexer_peek_token (parser->lexer);
+             switch (token->type)
+               {
+               case CPP_SEMICOLON:
+                 if (code == OMP_ATOMIC_CAPTURE_NEW)
+                   {
+                     code = OMP_ATOMIC_CAPTURE_OLD;
+                     v = lhs;
+                     lhs = NULL_TREE;
+                     lhs1 = rhs1;
+                     rhs1 = NULL_TREE;
+                     cp_lexer_consume_token (parser->lexer);
+                     goto restart;
+                   }
+                 cp_parser_error (parser,
+                                  "invalid form of %<#pragma omp atomic%>");
+                 goto saw_error;
+               case CPP_MULT:
+                 opcode = MULT_EXPR;
+                 break;
+               case CPP_DIV:
+                 opcode = TRUNC_DIV_EXPR;
+                 break;
+               case CPP_PLUS:
+                 opcode = PLUS_EXPR;
+                 break;
+               case CPP_MINUS:
+                 opcode = MINUS_EXPR;
+                 break;
+               case CPP_LSHIFT:
+                 opcode = LSHIFT_EXPR;
+                 break;
+               case CPP_RSHIFT:
+                 opcode = RSHIFT_EXPR;
+                 break;
+               case CPP_AND:
+                 opcode = BIT_AND_EXPR;
+                 break;
+               case CPP_OR:
+                 opcode = BIT_IOR_EXPR;
+                 break;
+               case CPP_XOR:
+                 opcode = BIT_XOR_EXPR;
+                 break;
+               default:
+                 cp_parser_error (parser,
+                                  "invalid operator for %<#pragma omp atomic%>");
+                 goto saw_error;
+               }
+             oprec = TOKEN_PRECEDENCE (token);
+             gcc_assert (oprec != PREC_NOT_OPERATOR);
+             if (commutative_tree_code (opcode))
+               oprec = (enum cp_parser_prec) (oprec - 1);
+             cp_lexer_consume_token (parser->lexer);
+             rhs = cp_parser_binary_expression (parser, false, false,
+                                                oprec, NULL);
+             if (rhs == error_mark_node)
+               goto saw_error;
+             goto stmt_done;
+           }
+         /* FALLTHROUGH */
        default:
          cp_parser_error (parser,
                           "invalid operator for %<#pragma omp atomic%>");
@@ -24135,12 +25692,46 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
        goto saw_error;
       break;
     }
-  finish_omp_atomic (code, lhs, rhs);
-  cp_parser_consume_semicolon_at_end_of_statement (parser);
+stmt_done:
+  if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
+    {
+      if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
+       goto saw_error;
+      v = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                     /*cast_p=*/false, NULL);
+      if (v == error_mark_node)
+       goto saw_error;
+      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
+       goto saw_error;
+      lhs1 = cp_parser_unary_expression (parser, /*address_p=*/false,
+                                        /*cast_p=*/false, NULL);
+      if (lhs1 == error_mark_node)
+       goto saw_error;
+    }
+  if (structured_block)
+    {
+      cp_parser_consume_semicolon_at_end_of_statement (parser);
+      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+    }
+done:
+  finish_omp_atomic (code, opcode, lhs, rhs, v, lhs1, rhs1);
+  if (!structured_block)
+    cp_parser_consume_semicolon_at_end_of_statement (parser);
   return;
 
  saw_error:
   cp_parser_skip_to_end_of_block_or_statement (parser);
+  if (structured_block)
+    {
+      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+        cp_lexer_consume_token (parser->lexer);
+      else if (code == OMP_ATOMIC_CAPTURE_NEW)
+       {
+         cp_parser_skip_to_end_of_block_or_statement (parser);
+         if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+           cp_lexer_consume_token (parser->lexer);
+       }
+    }
 }
 
 
@@ -24206,8 +25797,6 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
 {
   tree cond = cp_parser_binary_expression (parser, false, true,
                                           PREC_NOT_OPERATOR, NULL);
-  bool overloaded_p;
-
   if (cond == error_mark_node
       || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     {
@@ -24236,7 +25825,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
   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);
+                           /*overload=*/NULL, tf_warning_or_error);
 }
 
 /* Helper function, to parse omp for increment expression.  */
@@ -24444,7 +26033,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                                                    &is_direct_init,
                                                    &is_non_constant_init);
 
-                     if (auto_node && describable_type (init))
+                     if (auto_node)
                        {
                          TREE_TYPE (decl)
                            = do_auto_deduction (TREE_TYPE (decl), init,
@@ -24619,7 +26208,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
          /* If decl is an iterator, preserve the operator on decl
             until finish_omp_for.  */
          if (decl
-             && (type_dependent_expression_p (decl)
+             && ((type_dependent_expression_p (decl)
+                  && !POINTER_TYPE_P (TREE_TYPE (decl)))
                  || CLASS_TYPE_P (TREE_TYPE (decl))))
            incr = cp_parser_omp_for_incr (parser, decl);
          else
@@ -25003,7 +26593,9 @@ cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok)
        | (1u << PRAGMA_OMP_CLAUSE_DEFAULT)             \
        | (1u << PRAGMA_OMP_CLAUSE_PRIVATE)             \
        | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)        \
-       | (1u << PRAGMA_OMP_CLAUSE_SHARED))
+       | (1u << PRAGMA_OMP_CLAUSE_SHARED)              \
+       | (1u << PRAGMA_OMP_CLAUSE_FINAL)               \
+       | (1u << PRAGMA_OMP_CLAUSE_MERGEABLE))
 
 static tree
 cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok)
@@ -25030,6 +26622,16 @@ cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
   finish_omp_taskwait ();
 }
 
+/* OpenMP 3.1:
+   # pragma omp taskyield new-line  */
+
+static void
+cp_parser_omp_taskyield (cp_parser *parser, cp_token *pragma_tok)
+{
+  cp_parser_require_pragma_eol (parser, pragma_tok);
+  finish_omp_taskyield ();
+}
+
 /* OpenMP 2.5:
    # pragma omp threadprivate (variable-list) */
 
@@ -25088,6 +26690,272 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok)
     SET_EXPR_LOCATION (stmt, pragma_tok->location);
 }
 \f
+/* Transactional Memory parsing routines.  */
+
+/* Parse a transaction attribute.
+
+   txn-attribute:
+       attribute
+       [ [ identifier ] ]
+
+   ??? Simplify this when C++0x bracket attributes are
+   implemented properly.  */
+
+static tree
+cp_parser_txn_attribute_opt (cp_parser *parser)
+{
+  cp_token *token;
+  tree attr_name, attr = NULL;
+
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+    return cp_parser_attributes_opt (parser);
+
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
+    return NULL_TREE;
+  cp_lexer_consume_token (parser->lexer);
+  if (!cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE))
+    goto error1;
+
+  token = cp_lexer_peek_token (parser->lexer);
+  if (token->type == CPP_NAME || token->type == CPP_KEYWORD)
+    {
+      token = cp_lexer_consume_token (parser->lexer);
+
+      attr_name = (token->type == CPP_KEYWORD
+                  /* For keywords, use the canonical spelling,
+                     not the parsed identifier.  */
+                  ? ridpointers[(int) token->keyword]
+                  : token->u.value);
+      attr = build_tree_list (attr_name, NULL_TREE);
+    }
+  else
+    cp_parser_error (parser, "expected identifier");
+
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ error1:
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+  return attr;
+}
+
+/* Parse a __transaction_atomic or __transaction_relaxed statement.
+
+   transaction-statement:
+     __transaction_atomic txn-attribute[opt] txn-exception-spec[opt]
+       compound-statement
+     __transaction_relaxed txn-exception-spec[opt] compound-statement
+
+   ??? The exception specification is not yet implemented.
+*/
+
+static tree
+cp_parser_transaction (cp_parser *parser, enum rid keyword)
+{
+  unsigned char old_in = parser->in_transaction;
+  unsigned char this_in = 1, new_in;
+  cp_token *token;
+  tree stmt, attrs;
+
+  gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+      || keyword == RID_TRANSACTION_RELAXED);
+  token = cp_parser_require_keyword (parser, keyword,
+      (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+         : RT_TRANSACTION_RELAXED));
+  gcc_assert (token != NULL);
+
+  if (keyword == RID_TRANSACTION_RELAXED)
+    this_in |= TM_STMT_ATTR_RELAXED;
+  else
+    {
+      attrs = cp_parser_txn_attribute_opt (parser);
+      if (attrs)
+       this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
+    }
+
+  /* Keep track if we're in the lexical scope of an outer transaction.  */
+  new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
+
+  stmt = begin_transaction_stmt (token->location, NULL, this_in);
+
+  parser->in_transaction = new_in;
+  cp_parser_compound_statement (parser, NULL, false, false);
+  parser->in_transaction = old_in;
+
+  finish_transaction_stmt (stmt, NULL, this_in);
+
+  return stmt;
+}
+
+/* Parse a __transaction_atomic or __transaction_relaxed expression.
+
+   transaction-expression:
+     __transaction_atomic txn-exception-spec[opt] ( expression )
+     __transaction_relaxed txn-exception-spec[opt] ( expression )
+
+   ??? The exception specification is not yet implemented.
+*/
+
+static tree
+cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
+{
+  unsigned char old_in = parser->in_transaction;
+  unsigned char this_in = 1;
+  cp_token *token;
+  tree ret;
+
+  gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+      || keyword == RID_TRANSACTION_RELAXED);
+
+  if (!flag_tm)
+    error (keyword == RID_TRANSACTION_RELAXED
+          ? G_("%<__transaction_relaxed%> without transactional memory "
+               "support enabled")
+          : G_("%<__transaction_atomic%> without transactional memory "
+               "support enabled"));
+
+  token = cp_parser_require_keyword (parser, keyword,
+      (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+         : RT_TRANSACTION_RELAXED));
+  gcc_assert (token != NULL);
+
+  if (keyword == RID_TRANSACTION_RELAXED)
+    this_in |= TM_STMT_ATTR_RELAXED;
+
+  parser->in_transaction = this_in;
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+    {
+      tree expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      ret = build_transaction_expr (token->location, expr, this_in);
+    }
+  else
+    {
+      cp_parser_error (parser, "expected %<(%>");
+      ret = error_mark_node;
+    }
+  parser->in_transaction = old_in;
+
+  if (cp_parser_non_integral_constant_expression (parser, NIC_TRANSACTION))
+    return error_mark_node;
+
+  return (flag_tm ? ret : error_mark_node);
+}
+
+/* Parse a function-transaction-block.
+
+   function-transaction-block:
+     __transaction_atomic txn-attribute[opt] ctor-initializer[opt]
+        function-body
+     __transaction_atomic txn-attribute[opt] function-try-block
+     __transaction_relaxed ctor-initializer[opt] function-body
+     __transaction_relaxed function-try-block
+*/
+
+static bool
+cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
+{
+  unsigned char old_in = parser->in_transaction;
+  unsigned char new_in = 1;
+  tree compound_stmt, stmt, attrs;
+  bool ctor_initializer_p;
+  cp_token *token;
+
+  gcc_assert (keyword == RID_TRANSACTION_ATOMIC
+      || keyword == RID_TRANSACTION_RELAXED);
+  token = cp_parser_require_keyword (parser, keyword,
+      (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
+         : RT_TRANSACTION_RELAXED));
+  gcc_assert (token != NULL);
+
+  if (keyword == RID_TRANSACTION_RELAXED)
+    new_in |= TM_STMT_ATTR_RELAXED;
+  else
+    {
+      attrs = cp_parser_txn_attribute_opt (parser);
+      if (attrs)
+       new_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
+    }
+
+  stmt = begin_transaction_stmt (token->location, &compound_stmt, new_in);
+
+  parser->in_transaction = new_in;
+
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+    ctor_initializer_p = cp_parser_function_try_block (parser);
+  else
+    ctor_initializer_p
+      = cp_parser_ctor_initializer_opt_and_function_body (parser);
+
+  parser->in_transaction = old_in;
+
+  finish_transaction_stmt (stmt, compound_stmt, new_in);
+
+  return ctor_initializer_p;
+}
+
+/* Parse a __transaction_cancel statement.
+
+   cancel-statement:
+     __transaction_cancel txn-attribute[opt] ;
+     __transaction_cancel txn-attribute[opt] throw-expression ;
+
+   ??? Cancel and throw is not yet implemented.  */
+
+static tree
+cp_parser_transaction_cancel (cp_parser *parser)
+{
+  cp_token *token;
+  bool is_outer = false;
+  tree stmt, attrs;
+
+  token = cp_parser_require_keyword (parser, RID_TRANSACTION_CANCEL,
+                                    RT_TRANSACTION_CANCEL);
+  gcc_assert (token != NULL);
+
+  attrs = cp_parser_txn_attribute_opt (parser);
+  if (attrs)
+    is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
+
+  /* ??? Parse cancel-and-throw here.  */
+
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+  if (!flag_tm)
+    {
+      error_at (token->location, "%<__transaction_cancel%> without "
+               "transactional memory support enabled");
+      return error_mark_node;
+    }
+  else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
+    {
+      error_at (token->location, "%<__transaction_cancel%> within a "
+               "%<__transaction_relaxed%>");
+      return error_mark_node;
+    }
+  else if (is_outer)
+    {
+      if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
+         && !is_tm_may_cancel_outer (current_function_decl))
+       {
+         error_at (token->location, "outer %<__transaction_cancel%> not "
+                   "within outer %<__transaction_atomic%>");
+         error_at (token->location,
+                   "  or a %<transaction_may_cancel_outer%> function");
+         return error_mark_node;
+       }
+    }
+  else if (parser->in_transaction == 0)
+    {
+      error_at (token->location, "%<__transaction_cancel%> not within "
+               "%<__transaction_atomic%>");
+      return error_mark_node;
+    }
+
+  stmt = build_tm_abort_call (token->location, is_outer);
+  add_stmt (stmt);
+  finish_stmt ();
+
+  return stmt;
+}
+\f
 /* The parser.  */
 
 static GTY (()) cp_parser *the_parser;
@@ -25205,6 +27073,22 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
        }
       break;
 
+    case PRAGMA_OMP_TASKYIELD:
+      switch (context)
+       {
+       case pragma_compound:
+         cp_parser_omp_taskyield (parser, pragma_tok);
+         return false;
+       case pragma_stmt:
+         error_at (pragma_tok->location,
+                   "%<#pragma omp taskyield%> may only be "
+                   "used in compound statements");
+         break;
+       default:
+         goto bad_stmt;
+       }
+      break;
+
     case PRAGMA_OMP_THREADPRIVATE:
       cp_parser_omp_threadprivate (parser, pragma_tok);
       return false;