OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index fde4c6d..cdb524e 100644 (file)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009, 2010, 2011, 2012  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -2007,7 +2007,7 @@ static tree cp_parser_class_name
 static tree cp_parser_class_specifier
   (cp_parser *);
 static tree cp_parser_class_head
-  (cp_parser *, bool *, tree *, tree *);
+  (cp_parser *, bool *);
 static enum tag_types cp_parser_class_key
   (cp_parser *);
 static void cp_parser_member_specification_opt
@@ -2249,6 +2249,8 @@ static void cp_parser_pre_parsed_nested_name_specifier
   (cp_parser *);
 static bool cp_parser_cache_group
   (cp_parser *, enum cpp_ttype, unsigned);
+static tree cp_parser_cache_defarg
+  (cp_parser *parser, bool nsdmi);
 static void cp_parser_parse_tentatively
   (cp_parser *);
 static void cp_parser_commit_to_tentative_parse
@@ -3547,40 +3549,85 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
   return value;
 }
 
+/* Look up a literal operator with the name and the exact arguments.  */
+
+static tree
+lookup_literal_operator (tree name, VEC(tree,gc) *args)
+{
+  tree decl, fns;
+  decl = lookup_name (name);
+  if (!decl || !is_overloaded_fn (decl))
+    return error_mark_node;
+
+  for (fns = decl; fns; fns = OVL_NEXT (fns))
+    {
+      unsigned int ix;
+      bool found = true;
+      tree fn = OVL_CURRENT (fns);
+      tree argtypes = NULL_TREE;
+      argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
+      if (argtypes != NULL_TREE)
+       {
+         for (ix = 0; ix < VEC_length (tree, args) && argtypes != NULL_TREE;
+              ++ix, argtypes = TREE_CHAIN (argtypes))
+           {
+             tree targ = TREE_VALUE (argtypes);
+             tree tparm = TREE_TYPE (VEC_index (tree, args, ix));
+             bool ptr = TREE_CODE (targ) == POINTER_TYPE;
+             bool arr = TREE_CODE (tparm) == ARRAY_TYPE;
+             if ((ptr || arr || !same_type_p (targ, tparm))
+                 && (!ptr || !arr
+                     || !same_type_p (TREE_TYPE (targ),
+                                      TREE_TYPE (tparm))))
+               found = false;
+           }
+         if (found
+             && ix == VEC_length (tree, args)
+             /* May be this should be sufficient_parms_p instead,
+                depending on how exactly should user-defined literals
+                work in presence of default arguments on the literal
+                operator parameters.  */
+             && argtypes == void_list_node)
+           return fn;
+       }
+    }
+
+  return error_mark_node;
+}
+
 /* 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));
+  cp_token *token = cp_lexer_consume_token (parser->lexer);
+  tree literal = token->u.value;
+  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  tree value = USERDEF_LITERAL_VALUE (literal);
+  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+  tree decl, result;
 
   /* 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);
+  VEC(tree,gc) *args = make_tree_vector ();
+  VEC_safe_push (tree, gc, args, value);
+  decl = lookup_literal_operator (name, args);
   if (!decl || decl == error_mark_node)
     {
-      error ("unable to find user-defined character literal operator %qD",
-            name);
-      release_tree_vector (vec);
+      error ("unable to find character literal operator %qD with %qT argument",
+            name, TREE_TYPE (value));
+      release_tree_vector (args);
       return error_mark_node;
     }
-  result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
-  release_tree_vector (vec);
+  result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
+  release_tree_vector (args);
+  if (result != error_mark_node)
+    return result;
 
-  return result;
+  error ("unable to find character literal operator %qD with %qT argument",
+        name, TREE_TYPE (value));
+  return error_mark_node;
 }
 
 /* A subroutine of cp_parser_userdef_numeric_literal to
@@ -3615,26 +3662,20 @@ make_char_string_pack (tree value)
 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;
+  cp_token *token = cp_lexer_consume_token (parser->lexer);
+  tree literal = token->u.value;
+  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  tree value = USERDEF_LITERAL_VALUE (literal);
+  tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
+  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+  tree decl, result;
   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.  */
+  /* Look for a literal operator taking the exact type of numeric argument
+     as the literal value.  */
   args = make_tree_vector ();
   VEC_safe_push (tree, gc, args, value);
-  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+  decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
     {
       result = finish_call_expr (decl, &args, false, true, tf_none);
@@ -3651,7 +3692,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
      in string format.  */
   args = make_tree_vector ();
   VEC_safe_push (tree, gc, args, num_string);
-  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
+  decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
     {
       result = finish_call_expr (decl, &args, false, true, tf_none);
@@ -3667,7 +3708,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
      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);
+  decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
     {
       tree tmpl_args = make_char_string_pack (num_string);
@@ -3681,10 +3722,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
     }
   release_tree_vector (args);
 
-  if (result == error_mark_node)
-    error ("unable to find user-defined numeric literal operator %qD", name);
-
-  return result;
+  error ("unable to find numeric literal operator %qD", name);
+  return error_mark_node;
 }
 
 /* Parse a user-defined string constant.  Returns a call to a user-defined
@@ -3694,38 +3733,34 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
 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 literal = token->u.value;
+  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
+  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
+  tree value = USERDEF_LITERAL_VALUE (literal);
+  int len = TREE_STRING_LENGTH (value)
        / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
+  tree decl, result;
+
   /* 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);
+  VEC(tree,gc) *args = make_tree_vector ();
+  VEC_safe_push (tree, gc, args, value);
+  VEC_safe_push (tree, gc, args, build_int_cst (size_type_node, len));
+  decl = lookup_name (name);
   if (!decl || decl == error_mark_node)
     {
-      error ("unable to find user-defined string literal operator %qD", name);
-      release_tree_vector (vec);
+      error ("unable to find string literal operator %qD", name);
+      release_tree_vector (args);
       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);
+  result = finish_call_expr (decl, &args, false, true, tf_none);
+  release_tree_vector (args);
+  if (result != error_mark_node)
+    return result;
 
-  return result;
+  error ("unable to find string literal operator %qD with %qT, %qT arguments",
+        name, TREE_TYPE (value), size_type_node);
+  return error_mark_node;
 }
 
 
@@ -3827,6 +3862,7 @@ cp_parser_translation_unit (cp_parser* parser)
      __is_convertible_to ( type-id , type-id )     
      __is_empty ( type-id )
      __is_enum ( type-id )
+     __is_final ( type-id )
      __is_literal_type ( type-id )
      __is_pod ( type-id )
      __is_polymorphic ( type-id )
@@ -4172,6 +4208,7 @@ cp_parser_primary_expression (cp_parser *parser,
        case RID_IS_CONVERTIBLE_TO:
        case RID_IS_EMPTY:
        case RID_IS_ENUM:
+       case RID_IS_FINAL:
        case RID_IS_LITERAL_TYPE:
        case RID_IS_POD:
        case RID_IS_POLYMORPHIC:
@@ -5800,6 +5837,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
    by cp_parser_builtin_offsetof.  We're looking for
 
      postfix-expression [ expression ]
+     postfix-expression [ braced-init-list ] (C++11)
 
    FOR_OFFSETOF is set if we're being called in that context, which
    changes how we deal with integer constant expressions.  */
@@ -5825,7 +5863,16 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
   if (for_offsetof)
     index = cp_parser_constant_expression (parser, false, NULL);
   else
-    index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+    {
+      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+       {
+         bool expr_nonconst_p;
+         maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+         index = cp_parser_braced_list (parser, &expr_nonconst_p);
+       }
+      else
+       index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+    }
 
   /* Look for the closing `]'.  */
   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
@@ -6004,9 +6051,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
              parser->qualifying_scope = NULL_TREE;
              parser->object_scope = NULL_TREE;
            }
-         if (scope && name && BASELINK_P (name))
+         if (parser->scope && name && BASELINK_P (name))
            adjust_result_of_qualified_name_lookup
-             (name, BINFO_TYPE (BASELINK_ACCESS_BINFO (name)), scope);
+             (name, parser->scope, scope);
          postfix_expression
            = finish_class_member_access_expr (postfix_expression, name,
                                               template_p, 
@@ -6627,10 +6674,17 @@ cp_parser_new_expression (cp_parser* parser)
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
       cp_token *token;
+      const char *saved_message = parser->type_definition_forbidden_message;
+
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
+
       /* Parse the type-id.  */
+      parser->type_definition_forbidden_message
+       = G_("types may not be defined in a new-expression");
       type = cp_parser_type_id (parser);
+      parser->type_definition_forbidden_message = saved_message;
+
       /* Look for the closing `)'.  */
       cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
       token = cp_lexer_peek_token (parser->lexer);
@@ -6956,8 +7010,9 @@ cp_parser_delete_expression (cp_parser* parser)
    otherwise.  */
 
 static bool
-cp_parser_token_starts_cast_expression (cp_token *token)
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
 {
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
   switch (token->type)
     {
     case CPP_COMMA:
@@ -6998,6 +7053,12 @@ cp_parser_token_starts_cast_expression (cp_token *token)
     case CPP_EOF:
       return false;
 
+    case CPP_OPEN_PAREN:
+      /* In ((type ()) () the last () isn't a valid cast-expression,
+        so the whole must be parsed as postfix-expression.  */
+      return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+            != CPP_CLOSE_PAREN;
+
       /* '[' may start a primary-expression in obj-c++.  */
     case CPP_OPEN_SQUARE:
       return c_dialect_objc ();
@@ -7090,8 +7151,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
         parenthesized ctor such as `(T ())' that looks like a cast to
         function returning T.  */
       if (!cp_parser_error_occurred (parser)
-         && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
-                                                    (parser->lexer)))
+         && cp_parser_tokens_start_cast_expression (parser))
        {
          cp_parser_parse_definitely (parser);
          expr = cp_parser_cast_expression (parser,
@@ -7222,6 +7282,9 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
   lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
   lhs_type = ERROR_MARK;
 
+  if (cp_parser_error_occurred (parser))
+    return error_mark_node;
+
   for (;;)
     {
       /* Get an operator token.  */
@@ -7841,6 +7904,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
     case RID_IS_ENUM:
       kind = CPTK_IS_ENUM;
       break;
+    case RID_IS_FINAL:
+      kind = CPTK_IS_FINAL;
+      break;
     case RID_IS_LITERAL_TYPE:
       kind = CPTK_IS_LITERAL_TYPE;
       break;
@@ -8006,6 +8072,8 @@ cp_parser_lambda_expression (cp_parser* parser)
   cp_parser_lambda_introducer (parser, lambda_expr);
 
   type = begin_lambda_type (lambda_expr);
+  if (type == error_mark_node)
+    return error_mark_node;
 
   record_lambda_scope (lambda_expr);
 
@@ -9292,6 +9360,8 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl)
      at instantiation. If not, it is done just ahead. */
   if (processing_template_decl)
     {
+      if (check_for_bare_parameter_packs (range_expr))
+       range_expr = error_mark_node;
       stmt = begin_range_for_stmt (scope, init);
       finish_range_for_decl (stmt, range_decl, range_expr);
       if (!type_dependent_expression_p (range_expr)
@@ -9495,9 +9565,11 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
       id_begin = get_identifier ("begin");
       id_end = get_identifier ("end");
       member_begin = lookup_member (TREE_TYPE (range), id_begin,
-                                   /*protect=*/2, /*want_type=*/false);
+                                   /*protect=*/2, /*want_type=*/false,
+                                   tf_warning_or_error);
       member_end = lookup_member (TREE_TYPE (range), id_end,
-                                 /*protect=*/2, /*want_type=*/false);
+                                 /*protect=*/2, /*want_type=*/false,
+                                 tf_warning_or_error);
 
       if (member_begin != NULL_TREE || member_end != NULL_TREE)
        {
@@ -11290,6 +11362,7 @@ static void
 cp_parser_mem_initializer_list (cp_parser* parser)
 {
   tree mem_initializer_list = NULL_TREE;
+  tree target_ctor = error_mark_node;
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   /* Let the semantic analysis code know that we are starting the
@@ -11327,6 +11400,27 @@ cp_parser_mem_initializer_list (cp_parser* parser)
           if (mem_initializer != error_mark_node)
             mem_initializer = make_pack_expansion (mem_initializer);
         }
+      if (target_ctor != error_mark_node
+         && mem_initializer != error_mark_node)
+       {
+         error ("mem-initializer for %qD follows constructor delegation",
+                TREE_PURPOSE (mem_initializer));
+         mem_initializer = error_mark_node;
+       }
+      /* Look for a target constructor. */
+      if (mem_initializer != error_mark_node
+         && TYPE_P (TREE_PURPOSE (mem_initializer))
+         && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
+       {
+         maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
+         if (mem_initializer_list)
+           {
+             error ("constructor delegation follows mem-initializer for %qD",
+                    TREE_PURPOSE (mem_initializer_list));
+             mem_initializer = error_mark_node;
+           }
+         target_ctor = mem_initializer;
+       }
       /* Add it to the list, unless it was erroneous.  */
       if (mem_initializer != error_mark_node)
        {
@@ -11879,8 +11973,7 @@ cp_parser_template_parameter_list (cp_parser* parser)
                                                parm_loc,
                                                parameter,
                                                is_non_type,
-                                               is_parameter_pack,
-                                               0);
+                                               is_parameter_pack);
       else
        {
          tree err_parm = build_tree_list (parameter, parameter);
@@ -12643,7 +12736,7 @@ cp_parser_template_name (cp_parser* parser,
      its name; we will look it up again during template instantiation.  */
   if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl))
     {
-      tree scope = CP_DECL_CONTEXT (get_first_fn (decl));
+      tree scope = ovl_scope (decl);
       if (TYPE_P (scope) && dependent_type_p (scope))
        return identifier;
     }
@@ -13754,6 +13847,26 @@ cp_parser_nonclass_name (cp_parser* parser)
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
+  if (TREE_CODE (type_decl) == USING_DECL)
+    {
+      if (!DECL_DEPENDENT_P (type_decl))
+       type_decl = strip_using_decl (type_decl);
+      else if (USING_DECL_TYPENAME_P (type_decl))
+       {
+         /* We have found a type introduced by a using
+            declaration at class scope that refers to a dependent
+            type.
+            
+            using typename :: [opt] nested-name-specifier unqualified-id ;
+         */
+         type_decl = make_typename_type (TREE_TYPE (type_decl),
+                                         DECL_NAME (type_decl),
+                                         typename_type, tf_error);
+         if (type_decl != error_mark_node)
+           type_decl = TYPE_NAME (type_decl);
+       }
+    }
+  
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
     {
@@ -13922,11 +14035,14 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
                                   typename_type,
                                   /*complain=*/tf_error);
       /* If the `typename' keyword is in effect and DECL is not a type
-        decl. Then type is non existant.   */
+        decl, then type is non existent.   */
       else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
-        type = NULL_TREE; 
-      else 
-       type = TREE_TYPE (decl);
+        ; 
+      else if (TREE_CODE (decl) == TYPE_DECL)
+        type = check_elaborated_type_specifier (tag_type, decl,
+                                               /*allow_template_p=*/true);
+      else if (decl == error_mark_node)
+       type = error_mark_node; 
     }
 
   if (!type)
@@ -14806,9 +14922,14 @@ cp_parser_using_declaration (cp_parser* parser,
   tree decl;
   tree identifier;
   tree qscope;
+  int oldcount = errorcount;
+  cp_token *diag_token = NULL;
 
   if (access_declaration_p)
-    cp_parser_parse_tentatively (parser);
+    {
+      diag_token = cp_lexer_peek_token (parser->lexer);
+      cp_parser_parse_tentatively (parser);
+    }
   else
     {
       /* Look for the `using' keyword.  */
@@ -14890,9 +15011,12 @@ cp_parser_using_declaration (cp_parser* parser,
          /* Create the USING_DECL.  */
          decl = do_class_using_decl (parser->scope, identifier);
 
+         if (decl && typename_p)
+           USING_DECL_TYPENAME_P (decl) = 1;
+
          if (check_for_bare_parameter_packs (decl))
             return false;
-          else
+         else
            /* Add it to the list of members in this class.  */
            finish_member_declaration (decl);
        }
@@ -14916,7 +15040,13 @@ cp_parser_using_declaration (cp_parser* parser,
 
   /* Look for the final `;'.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
-  
+
+  if (access_declaration_p && errorcount == oldcount)
+    warning_at (diag_token->location, OPT_Wdeprecated,
+               "access declarations are deprecated "
+               "in favour of using-declarations; "
+               "suggestion: add the %<using%> keyword");
+
   return true;
 }
 
@@ -14933,16 +15063,58 @@ cp_parser_alias_declaration (cp_parser* parser)
   cp_declarator *declarator;
   cp_decl_specifier_seq decl_specs;
   bool member_p;
+  const char *saved_message = NULL;
 
   /* 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);
+  if (id == error_mark_node)
+    return error_mark_node;
+
   attributes = cp_parser_attributes_opt (parser);
+  if (attributes == error_mark_node)
+    return error_mark_node;
+
   cp_parser_require (parser, CPP_EQ, RT_EQ);
 
+  if (cp_parser_error_occurred (parser))
+    return error_mark_node;
+
+  /* Now we are going to parse the type-id of the declaration.  */
+
+  /*
+    [dcl.type]/3 says:
+
+       "A type-specifier-seq shall not define a class or enumeration
+        unless it appears in the type-id of an alias-declaration (7.1.3) that
+        is not the declaration of a template-declaration."
+
+    In other words, if we currently are in an alias template, the
+    type-id should not define a type.
+
+    So let's set parser->type_definition_forbidden_message in that
+    case; cp_parser_check_type_definition (called by
+    cp_parser_class_specifier) will then emit an error if a type is
+    defined in the type-id.  */
+  if (parser->num_template_parameter_lists)
+    {
+      saved_message = parser->type_definition_forbidden_message;
+      parser->type_definition_forbidden_message =
+       G_("types may not be defined in alias template declarations");
+    }
+
   type = cp_parser_type_id (parser);
 
+  /* Restore the error message if need be.  */
+  if (parser->num_template_parameter_lists)
+    parser->type_definition_forbidden_message = saved_message;
+
+  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
+  if (cp_parser_error_occurred (parser))
+    return error_mark_node;
+
   /* 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
@@ -15571,8 +15743,7 @@ cp_parser_init_declarator (cp_parser* parser,
        {
          /* We want to record the extra mangling scope for in-class
             initializers of class members and initializers of static data
-            member templates.  The former is a C++0x feature which isn't
-            implemented yet, and I expect it will involve deferring
+            member templates.  The former involves deferring
             parsing of the initializer until end of class as with default
             arguments.  So right here we only handle the latter.  */
          if (!member_p && processing_template_decl)
@@ -15987,18 +16158,20 @@ cp_parser_direct_declarator (cp_parser* parser,
                                                 &non_constant_p);
              if (!non_constant_p)
                /* OK */;
-             /* Normally, the array bound must be an integral constant
-                expression.  However, as an extension, we allow VLAs
-                in function scopes as long as they aren't part of a
-                parameter declaration.  */
+             else if (error_operand_p (bounds))
+               /* Already gave an error.  */;
              else if (!parser->in_function_body
                       || current_binding_level->kind == sk_function_parms)
                {
+                 /* Normally, the array bound must be an integral constant
+                    expression.  However, as an extension, we allow VLAs
+                    in function scopes as long as they aren't part of a
+                    parameter declaration.  */
                  cp_parser_error (parser,
                                   "array bound is not an integer constant");
                  bounds = error_mark_node;
                }
-             else if (processing_template_decl && !error_operand_p (bounds))
+             else if (processing_template_decl)
                {
                  /* Remember this wasn't a constant-expression.  */
                  bounds = build_nop (TREE_TYPE (bounds), bounds);
@@ -16329,6 +16502,9 @@ cp_parser_ptr_operator (cp_parser* parser,
 
          if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
            error_at (token->location, "%qD is a namespace", parser->scope);
+         else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE)
+           error_at (token->location, "cannot form pointer to member of "
+                     "non-class %q#T", parser->scope);
          else
            {
              /* The type of which the member is a member is given by the
@@ -17134,159 +17310,18 @@ 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))
     {
+      token = cp_lexer_peek_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 ()
          && TYPE_BEING_DEFINED (current_class_type)
          && !LAMBDA_TYPE_P (current_class_type))
-       {
-         unsigned depth = 0;
-         int maybe_template_id = 0;
-         cp_token *first_token;
-         cp_token *token;
-
-         /* Add tokens until we have processed the entire default
-            argument.  We add the range [first_token, token).  */
-         first_token = cp_lexer_peek_token (parser->lexer);
-         while (true)
-           {
-             bool done = false;
-
-             /* Peek at the next token.  */
-             token = cp_lexer_peek_token (parser->lexer);
-             /* What we do depends on what token we have.  */
-             switch (token->type)
-               {
-                 /* In valid code, a default argument must be
-                    immediately followed by a `,' `)', or `...'.  */
-               case CPP_COMMA:
-                 if (depth == 0 && maybe_template_id)
-                   {
-                     /* If we've seen a '<', we might be in a
-                        template-argument-list.  Until Core issue 325 is
-                        resolved, we don't know how this situation ought
-                        to be handled, so try to DTRT.  We check whether
-                        what comes after the comma is a valid parameter
-                        declaration list.  If it is, then the comma ends
-                        the default argument; otherwise the default
-                        argument continues.  */
-                     bool error = false;
-                     tree t;
-
-                     /* Set ITALP so cp_parser_parameter_declaration_list
-                        doesn't decide to commit to this parse.  */
-                     bool saved_italp = parser->in_template_argument_list_p;
-                     parser->in_template_argument_list_p = true;
-
-                     cp_parser_parse_tentatively (parser);
-                     cp_lexer_consume_token (parser->lexer);
-                     begin_scope (sk_function_parms, NULL_TREE);
-                     cp_parser_parameter_declaration_list (parser, &error);
-                     for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
-                       pop_binding (DECL_NAME (t), t);
-                     leave_scope ();
-                     if (!cp_parser_error_occurred (parser) && !error)
-                       done = true;
-                     cp_parser_abort_tentative_parse (parser);
-
-                     parser->in_template_argument_list_p = saved_italp;
-                     break;
-                   }
-               case CPP_CLOSE_PAREN:
-               case CPP_ELLIPSIS:
-                 /* If we run into a non-nested `;', `}', or `]',
-                    then the code is invalid -- but the default
-                    argument is certainly over.  */
-               case CPP_SEMICOLON:
-               case CPP_CLOSE_BRACE:
-               case CPP_CLOSE_SQUARE:
-                 if (depth == 0)
-                   done = true;
-                 /* Update DEPTH, if necessary.  */
-                 else if (token->type == CPP_CLOSE_PAREN
-                          || token->type == CPP_CLOSE_BRACE
-                          || token->type == CPP_CLOSE_SQUARE)
-                   --depth;
-                 break;
-
-               case CPP_OPEN_PAREN:
-               case CPP_OPEN_SQUARE:
-               case CPP_OPEN_BRACE:
-                 ++depth;
-                 break;
-
-               case CPP_LESS:
-                 if (depth == 0)
-                   /* This might be the comparison operator, or it might
-                      start a template argument list.  */
-                   ++maybe_template_id;
-                 break;
-
-                case CPP_RSHIFT:
-                  if (cxx_dialect == cxx98)
-                    break;
-                  /* Fall through for C++0x, which treats the `>>'
-                     operator like two `>' tokens in certain
-                     cases.  */
-
-               case CPP_GREATER:
-                 if (depth == 0)
-                   {
-                     /* This might be an operator, or it might close a
-                        template argument list.  But if a previous '<'
-                        started a template argument list, this will have
-                        closed it, so we can't be in one anymore.  */
-                     maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
-                     if (maybe_template_id < 0)
-                       maybe_template_id = 0;
-                   }
-                 break;
-
-                 /* If we run out of tokens, issue an error message.  */
-               case CPP_EOF:
-               case CPP_PRAGMA_EOL:
-                 error_at (token->location, "file ends in default argument");
-                 done = true;
-                 break;
-
-               case CPP_NAME:
-               case CPP_SCOPE:
-                 /* In these cases, we should look for template-ids.
-                    For example, if the default argument is
-                    `X<int, double>()', we need to do name lookup to
-                    figure out whether or not `X' is a template; if
-                    so, the `,' does not end the default argument.
-
-                    That is not yet done.  */
-                 break;
-
-               default:
-                 break;
-               }
-
-             /* If we've reached the end, stop.  */
-             if (done)
-               break;
-
-             /* Add the token to the token block.  */
-             token = cp_lexer_consume_token (parser->lexer);
-           }
-
-         /* Create a DEFAULT_ARG to represent the unparsed default
-            argument.  */
-         default_argument = make_node (DEFAULT_ARG);
-         DEFARG_TOKENS (default_argument)
-           = cp_token_cache_new (first_token, token);
-         DEFARG_INSTANTIATIONS (default_argument) = NULL;
-       }
+       default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);
       /* Outside of a class definition, we can just parse the
         assignment-expression.  */
       else
-       {
-         token = cp_lexer_peek_token (parser->lexer);
-         default_argument 
-           = cp_parser_default_argument (parser, template_parm_p);
-       }
+       default_argument
+         = cp_parser_default_argument (parser, template_parm_p);
 
       if (!parser->default_arg_ok_p)
        {
@@ -17408,11 +17443,8 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser)
      cp_parser_function_body changed its state.  */
   if (check_body_p)
     {
-      list = body;
-      if (TREE_CODE (list) == BIND_EXPR)
-       list = BIND_EXPR_BODY (list);
-      if (TREE_CODE (list) == STATEMENT_LIST
-         && STATEMENT_LIST_TAIL (list) != NULL)
+      list = cur_stmt_list;
+      if (STATEMENT_LIST_TAIL (list))
        last = STATEMENT_LIST_TAIL (list)->stmt;
     }
   /* Parse the function-body.  */
@@ -17640,12 +17672,17 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
               && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
        {
          /* In C++11, [ could start a lambda-introducer.  */
+         bool non_const = false;
+
          cp_parser_parse_tentatively (parser);
          cp_lexer_consume_token (parser->lexer);
-         designator = cp_parser_constant_expression (parser, false, NULL);
+         designator = cp_parser_constant_expression (parser, true, &non_const);
          cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
          cp_parser_require (parser, CPP_EQ, RT_EQ);
-         cp_parser_parse_definitely (parser);
+         if (!cp_parser_parse_definitely (parser))
+           designator = NULL_TREE;
+         else if (non_const)
+           require_potential_rvalue_constant_expression (designator);
        }
       else
        designator = NULL_TREE;
@@ -17821,6 +17858,8 @@ cp_parser_class_name (cp_parser *parser,
        decl = TYPE_NAME (decl);
     }
 
+  decl = strip_using_decl (decl);
+
   /* Check to see that it is really the name of a class.  */
   if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
       && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
@@ -17878,16 +17917,13 @@ cp_parser_class_specifier_1 (cp_parser* parser)
   bool saved_in_unbraced_linkage_specification_p;
   tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
-  tree bases;
   cp_token *closing_brace;
 
   push_deferring_access_checks (dk_no_deferred);
 
   /* Parse the class-head.  */
   type = cp_parser_class_head (parser,
-                              &nested_name_specifier_p,
-                              &attributes,
-                              &bases);
+                              &nested_name_specifier_p);
   /* If the class-head was a semantic disaster, skip the entire body
      of the class.  */
   if (!type)
@@ -17904,18 +17940,6 @@ cp_parser_class_specifier_1 (cp_parser* parser)
       return error_mark_node;
     }
 
-  /* Process the base classes. If they're invalid, skip the 
-     entire class body.  */
-  if (!xref_basetypes (type, bases))
-    {
-      /* Consuming the closing brace yields better error messages
-         later on.  */
-      if (cp_parser_skip_to_closing_brace (parser))
-       cp_lexer_consume_token (parser->lexer);
-      pop_deferring_access_checks ();
-      return error_mark_node;
-    }
-
   /* Issue an error message if type-definitions are forbidden here.  */
   cp_parser_check_type_definition (parser);
   /* Remember that we are defining one more class.  */
@@ -17945,7 +17969,7 @@ cp_parser_class_specifier_1 (cp_parser* parser)
       scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
       old_scope = push_inner_scope (scope);
     }
-  type = begin_class_definition (type, attributes);
+  type = begin_class_definition (type);
 
   if (type == error_mark_node)
     /* If the type is erroneous, skip the entire body of the class.  */
@@ -18201,15 +18225,14 @@ cp_parser_class_specifier (cp_parser* parser)
 
 static tree
 cp_parser_class_head (cp_parser* parser,
-                     bool* nested_name_specifier_p,
-                     tree *attributes_p,
-                     tree *bases)
+                     bool* nested_name_specifier_p)
 {
   tree nested_name_specifier;
   enum tag_types class_key;
   tree id = NULL_TREE;
   tree type = NULL_TREE;
   tree attributes;
+  tree bases;
   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   bool template_id_p = false;
   bool qualified_p = false;
@@ -18226,8 +18249,6 @@ cp_parser_class_head (cp_parser* parser,
   num_templates = 0;
   parser->colon_corrects_to_scope_p = false;
 
-  *bases = NULL_TREE;
-
   /* Look for the class-key.  */
   class_key = cp_parser_class_key (parser);
   if (class_key == none_type)
@@ -18570,6 +18591,14 @@ cp_parser_class_head (cp_parser* parser,
   else if (type == error_mark_node)
     type = NULL_TREE;
 
+  if (type)
+    {
+      /* Apply attributes now, before any use of the class as a template
+        argument in its base list.  */
+      cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
+      fixup_attribute_variants (type);
+    }
+
   /* We will have entered the scope containing the class; the names of
      base classes should be looked up in that context.  For example:
 
@@ -18580,7 +18609,15 @@ cp_parser_class_head (cp_parser* parser,
 
   /* Get the list of base-classes, if there is one.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-    *bases = cp_parser_base_clause (parser);
+    bases = cp_parser_base_clause (parser);
+  else
+    bases = NULL_TREE;
+
+  /* If we're really defining a class, process the base classes.
+     If they're invalid, fail.  */
+  if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+      && !xref_basetypes (type, bases))
+    type = NULL_TREE;
 
  done:
   /* Leave the scope given by the nested-name-specifier.  We will
@@ -18596,7 +18633,6 @@ 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:
@@ -18807,7 +18843,7 @@ cp_parser_member_declaration (cp_parser* parser)
   parser->colon_corrects_to_scope_p = false;
 
   if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
-    goto out;
+      goto out;
 
   /* Parse the decl-specifier-seq.  */
   decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
@@ -19083,7 +19119,7 @@ cp_parser_member_declaration (cp_parser* parser)
                     possible that this fact is an oversight in the
                     standard, since a pure function may be defined
                     outside of the class-specifier.  */
-                 if (initializer)
+                 if (initializer && initializer_token_start)
                    error_at (initializer_token_start->location,
                              "pure-specifier on function-definition");
                  decl = cp_parser_save_member_function_body (parser,
@@ -19471,19 +19507,25 @@ cp_parser_base_specifier (cp_parser* parser)
 
 /* Exception handling [gram.exception] */
 
-/* Parse an (optional) exception-specification.
+/* Parse an (optional) noexcept-specification.
 
-   exception-specification:
-     throw ( type-id-list [opt] )
+   noexcept-specification:
+     noexcept ( constant-expression ) [opt]
 
-   Returns a TREE_LIST representing the exception-specification.  The
-   TREE_VALUE of each node is a type.  */
+   If no noexcept-specification is present, returns NULL_TREE.
+   Otherwise, if REQUIRE_CONSTEXPR is false, then either parse and return any
+   expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
+   there are no parentheses.  CONSUMED_EXPR will be set accordingly.
+   Otherwise, returns a noexcept specification unless RETURN_COND is true,
+   in which case a boolean condition is returned instead.  */
 
 static tree
-cp_parser_exception_specification_opt (cp_parser* parser)
+cp_parser_noexcept_specification_opt (cp_parser* parser,
+                                     bool require_constexpr,
+                                     bool* consumed_expr,
+                                     bool return_cond)
 {
   cp_token *token;
-  tree type_id_list;
   const char *saved_message;
 
   /* Peek at the next token.  */
@@ -19499,23 +19541,67 @@ cp_parser_exception_specification_opt (cp_parser* parser)
        {
          cp_lexer_consume_token (parser->lexer);
 
-         /* Types may not be defined in an exception-specification.  */
-         saved_message = parser->type_definition_forbidden_message;
-         parser->type_definition_forbidden_message
-           = G_("types may not be defined in an exception-specification");
+         if (require_constexpr)
+           {
+             /* Types may not be defined in an exception-specification.  */
+             saved_message = parser->type_definition_forbidden_message;
+             parser->type_definition_forbidden_message
+             = G_("types may not be defined in an exception-specification");
 
-         expr = cp_parser_constant_expression (parser, false, NULL);
+             expr = cp_parser_constant_expression (parser, false, NULL);
 
-         /* Restore the saved message.  */
-         parser->type_definition_forbidden_message = saved_message;
+             /* Restore the saved message.  */
+             parser->type_definition_forbidden_message = saved_message;
+           }
+         else
+           {
+             expr = cp_parser_expression (parser, false, NULL);
+             *consumed_expr = true;
+           }
 
          cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
        }
       else
-       expr = boolean_true_node;
+       {
+         expr = boolean_true_node;
+         if (!require_constexpr)
+           *consumed_expr = false;
+       }
 
-      return build_noexcept_spec (expr, tf_warning_or_error);
+      /* We cannot build a noexcept-spec right away because this will check
+        that expr is a constexpr.  */
+      if (!return_cond)
+       return build_noexcept_spec (expr, tf_warning_or_error);
+      else
+       return expr;
     }
+  else
+    return NULL_TREE;
+}
+
+/* Parse an (optional) exception-specification.
+
+   exception-specification:
+     throw ( type-id-list [opt] )
+
+   Returns a TREE_LIST representing the exception-specification.  The
+   TREE_VALUE of each node is a type.  */
+
+static tree
+cp_parser_exception_specification_opt (cp_parser* parser)
+{
+  cp_token *token;
+  tree type_id_list;
+  const char *saved_message;
+
+  /* Peek at the next token.  */
+  token = cp_lexer_peek_token (parser->lexer);
+
+  /* Is it a noexcept-specification?  */
+  type_id_list = cp_parser_noexcept_specification_opt(parser, true, NULL,
+                                                     false);
+  if (type_id_list != NULL_TREE)
+    return type_id_list;
 
   /* If it's not `throw', then there's no exception-specification.  */
   if (!cp_parser_is_keyword (token, RID_THROW))
@@ -20397,7 +20483,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
        object_decl = lookup_member (object_type,
                                     name,
                                     /*protect=*/0,
-                                    tag_type != none_type);
+                                    tag_type != none_type,
+                                    tf_warning_or_error);
       /* Look it up in the enclosing context, too.  */
       decl = lookup_name_real (name, tag_type != none_type,
                               /*nonclass=*/0,
@@ -21058,7 +21145,6 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
     {
       /* Parse the template parameters.  */
       parameter_list = cp_parser_template_parameter_list (parser);
-      fixup_template_parms ();
     }
 
   /* Get the deferred access checks from the parameter list.  These
@@ -21445,25 +21531,9 @@ cp_parser_save_member_function_body (cp_parser* parser,
 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;
+  return cp_parser_cache_defarg (parser, /*nsdmi=*/true);
 }
 
-
 /* Parse a template-argument-list, as well as the trailing ">" (but
    not the opening "<").  See cp_parser_template_argument_list for the
    return value.  */
@@ -21682,6 +21752,9 @@ cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
   tree parsed_arg;
   bool dummy;
 
+  if (default_arg == error_mark_node)
+    return error_mark_node;
+
   /* Push the saved tokens for the default argument onto the parser's
      lexer stack.  */
   tokens = DEFARG_TOKENS (default_arg);
@@ -22450,11 +22523,17 @@ cp_parser_token_is_class_key (cp_token* token)
 static void
 cp_parser_check_class_key (enum tag_types class_key, tree type)
 {
+  if (type == error_mark_node)
+    return;
   if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
-    permerror (input_location, "%qs tag used in naming %q#T",
-           class_key == union_type ? "union"
-            : class_key == record_type ? "struct" : "class",
-            type);
+    {
+      permerror (input_location, "%qs tag used in naming %q#T",
+                class_key == union_type ? "union"
+                : class_key == record_type ? "struct" : "class",
+                type);
+      inform (DECL_SOURCE_LOCATION (TYPE_NAME (type)),
+             "%q#T was previously declared here", type);
+    }
 }
 
 /* Issue an error message if DECL is redeclared with different
@@ -22564,12 +22643,6 @@ 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.  */
@@ -22595,6 +22668,178 @@ cp_parser_cache_group (cp_parser *parser,
     }
 }
 
+/* Like above, for caching a default argument or NSDMI.  Both of these are
+   terminated by a non-nested comma, but it can be unclear whether or not a
+   comma is nested in a template argument list unless we do more parsing.
+   In order to handle this ambiguity, when we encounter a ',' after a '<'
+   we try to parse what follows as a parameter-declaration-list (in the
+   case of a default argument) or a member-declarator (in the case of an
+   NSDMI).  If that succeeds, then we stop caching.  */
+
+static tree
+cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
+{
+  unsigned depth = 0;
+  int maybe_template_id = 0;
+  cp_token *first_token;
+  cp_token *token;
+  tree default_argument;
+
+  /* Add tokens until we have processed the entire default
+     argument.  We add the range [first_token, token).  */
+  first_token = cp_lexer_peek_token (parser->lexer);
+  if (first_token->type == CPP_OPEN_BRACE)
+    {
+      /* For list-initialization, this is straightforward.  */
+      cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
+      token = cp_lexer_peek_token (parser->lexer);
+    }
+  else while (true)
+    {
+      bool done = false;
+
+      /* Peek at the next token.  */
+      token = cp_lexer_peek_token (parser->lexer);
+      /* What we do depends on what token we have.  */
+      switch (token->type)
+       {
+         /* In valid code, a default argument must be
+            immediately followed by a `,' `)', or `...'.  */
+       case CPP_COMMA:
+         if (depth == 0 && maybe_template_id)
+           {
+             /* If we've seen a '<', we might be in a
+                template-argument-list.  Until Core issue 325 is
+                resolved, we don't know how this situation ought
+                to be handled, so try to DTRT.  We check whether
+                what comes after the comma is a valid parameter
+                declaration list.  If it is, then the comma ends
+                the default argument; otherwise the default
+                argument continues.  */
+             bool error = false;
+             tree t;
+
+             /* Set ITALP so cp_parser_parameter_declaration_list
+                doesn't decide to commit to this parse.  */
+             bool saved_italp = parser->in_template_argument_list_p;
+             parser->in_template_argument_list_p = true;
+
+             cp_parser_parse_tentatively (parser);
+             cp_lexer_consume_token (parser->lexer);
+
+             if (nsdmi)
+               {
+                 int ctor_dtor_or_conv_p;
+                 cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+                                       &ctor_dtor_or_conv_p,
+                                       /*parenthesized_p=*/NULL,
+                                       /*member_p=*/true);
+               }
+             else
+               {
+                 begin_scope (sk_function_parms, NULL_TREE);
+                 cp_parser_parameter_declaration_list (parser, &error);
+                 for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
+                   pop_binding (DECL_NAME (t), t);
+                 leave_scope ();
+               }
+             if (!cp_parser_error_occurred (parser) && !error)
+               done = true;
+             cp_parser_abort_tentative_parse (parser);
+
+             parser->in_template_argument_list_p = saved_italp;
+             break;
+           }
+       case CPP_CLOSE_PAREN:
+       case CPP_ELLIPSIS:
+         /* If we run into a non-nested `;', `}', or `]',
+            then the code is invalid -- but the default
+            argument is certainly over.  */
+       case CPP_SEMICOLON:
+       case CPP_CLOSE_BRACE:
+       case CPP_CLOSE_SQUARE:
+         if (depth == 0)
+           done = true;
+         /* Update DEPTH, if necessary.  */
+         else if (token->type == CPP_CLOSE_PAREN
+                  || token->type == CPP_CLOSE_BRACE
+                  || token->type == CPP_CLOSE_SQUARE)
+           --depth;
+         break;
+
+       case CPP_OPEN_PAREN:
+       case CPP_OPEN_SQUARE:
+       case CPP_OPEN_BRACE:
+         ++depth;
+         break;
+
+       case CPP_LESS:
+         if (depth == 0)
+           /* This might be the comparison operator, or it might
+              start a template argument list.  */
+           ++maybe_template_id;
+         break;
+
+       case CPP_RSHIFT:
+         if (cxx_dialect == cxx98)
+           break;
+         /* Fall through for C++0x, which treats the `>>'
+            operator like two `>' tokens in certain
+            cases.  */
+
+       case CPP_GREATER:
+         if (depth == 0)
+           {
+             /* This might be an operator, or it might close a
+                template argument list.  But if a previous '<'
+                started a template argument list, this will have
+                closed it, so we can't be in one anymore.  */
+             maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
+             if (maybe_template_id < 0)
+               maybe_template_id = 0;
+           }
+         break;
+
+         /* If we run out of tokens, issue an error message.  */
+       case CPP_EOF:
+       case CPP_PRAGMA_EOL:
+         error_at (token->location, "file ends in default argument");
+         done = true;
+         break;
+
+       case CPP_NAME:
+       case CPP_SCOPE:
+         /* In these cases, we should look for template-ids.
+            For example, if the default argument is
+            `X<int, double>()', we need to do name lookup to
+            figure out whether or not `X' is a template; if
+            so, the `,' does not end the default argument.
+
+            That is not yet done.  */
+         break;
+
+       default:
+         break;
+       }
+
+      /* If we've reached the end, stop.  */
+      if (done)
+       break;
+
+      /* Add the token to the token block.  */
+      token = cp_lexer_consume_token (parser->lexer);
+    }
+
+  /* Create a DEFAULT_ARG to represent the unparsed default
+     argument.  */
+  default_argument = make_node (DEFAULT_ARG);
+  DEFARG_TOKENS (default_argument)
+    = cp_token_cache_new (first_token, token);
+  DEFARG_INSTANTIATIONS (default_argument) = NULL;
+
+  return default_argument;
+}
+
 /* Begin parsing tentatively.  We always save tokens while parsing
    tentatively so that if the tentative parsing fails we can restore the
    tokens.  */
@@ -26206,11 +26451,11 @@ 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)
-                  && !POINTER_TYPE_P (TREE_TYPE (decl)))
-                 || CLASS_TYPE_P (TREE_TYPE (decl))))
-           incr = cp_parser_omp_for_incr (parser, decl);
+         if (real_decl
+             && ((processing_template_decl
+                  && !POINTER_TYPE_P (TREE_TYPE (real_decl)))
+                 || CLASS_TYPE_P (TREE_TYPE (real_decl))))
+           incr = cp_parser_omp_for_incr (parser, real_decl);
          else
            incr = cp_parser_expression (parser, false, NULL);
        }
@@ -26739,11 +26984,9 @@ cp_parser_txn_attribute_opt (cp_parser *parser)
 /* Parse a __transaction_atomic or __transaction_relaxed statement.
 
    transaction-statement:
-     __transaction_atomic txn-attribute[opt] txn-exception-spec[opt]
+     __transaction_atomic txn-attribute[opt] txn-noexcept-spec[opt]
        compound-statement
-     __transaction_relaxed txn-exception-spec[opt] compound-statement
-
-   ??? The exception specification is not yet implemented.
+     __transaction_relaxed txn-noexcept-spec[opt] compound-statement
 */
 
 static tree
@@ -26752,7 +26995,7 @@ 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;
+  tree stmt, attrs, noex;
 
   gcc_assert (keyword == RID_TRANSACTION_ATOMIC
       || keyword == RID_TRANSACTION_RELAXED);
@@ -26770,6 +27013,9 @@ cp_parser_transaction (cp_parser *parser, enum rid keyword)
        this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
     }
 
+  /* Parse a noexcept specification.  */
+  noex = cp_parser_noexcept_specification_opt (parser, true, NULL, true);
+
   /* Keep track if we're in the lexical scope of an outer transaction.  */
   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
 
@@ -26779,7 +27025,7 @@ cp_parser_transaction (cp_parser *parser, enum rid keyword)
   cp_parser_compound_statement (parser, NULL, false, false);
   parser->in_transaction = old_in;
 
-  finish_transaction_stmt (stmt, NULL, this_in);
+  finish_transaction_stmt (stmt, NULL, this_in, noex);
 
   return stmt;
 }
@@ -26787,10 +27033,8 @@ cp_parser_transaction (cp_parser *parser, enum rid keyword)
 /* 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.
+     __transaction_atomic txn-noexcept-spec[opt] ( expression )
+     __transaction_relaxed txn-noexcept-spec[opt] ( expression )
 */
 
 static tree
@@ -26799,7 +27043,8 @@ 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;
+  tree expr, noex;
+  bool noex_expr;
 
   gcc_assert (keyword == RID_TRANSACTION_ATOMIC
       || keyword == RID_TRANSACTION_RELAXED);
@@ -26819,23 +27064,42 @@ cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
   if (keyword == RID_TRANSACTION_RELAXED)
     this_in |= TM_STMT_ATTR_RELAXED;
 
+  /* Set this early.  This might mean that we allow transaction_cancel in
+     an expression that we find out later actually has to be a constexpr.
+     However, we expect that cxx_constant_value will be able to deal with
+     this; also, if the noexcept has no constexpr, then what we parse next
+     really is a transaction's body.  */
   parser->in_transaction = this_in;
-  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+
+  /* Parse a noexcept specification.  */
+  noex = cp_parser_noexcept_specification_opt (parser, false, &noex_expr,
+                                              true);
+
+  if (!noex || !noex_expr
+      || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
     {
-      tree expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
-      ret = build_transaction_expr (token->location, expr, this_in);
+      cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+
+      expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      finish_parenthesized_expr (expr);
+
+      cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
     }
   else
     {
-      cp_parser_error (parser, "expected %<(%>");
-      ret = error_mark_node;
+      /* The only expression that is available got parsed for the noexcept
+         already.  noexcept is true then.  */
+      expr = noex;
+      noex = boolean_true_node;
     }
+
+  expr = build_transaction_expr (token->location, expr, this_in, noex);
   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);
+  return (flag_tm ? expr : error_mark_node);
 }
 
 /* Parse a function-transaction-block.
@@ -26885,7 +27149,7 @@ cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
 
   parser->in_transaction = old_in;
 
-  finish_transaction_stmt (stmt, compound_stmt, new_in);
+  finish_transaction_stmt (stmt, compound_stmt, new_in, NULL_TREE);
 
   return ctor_initializer_p;
 }