OSDN Git Service

PR c++/43648
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 3475723..8a1bb9f 100644 (file)
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
+#include "intl.h"
 #include "c-pragma.h"
 #include "decl.h"
 #include "flags.h"
@@ -889,6 +890,7 @@ make_declarator (cp_declarator_kind kind)
   declarator->attributes = NULL_TREE;
   declarator->declarator = NULL;
   declarator->parameter_pack_p = false;
+  declarator->id_loc = UNKNOWN_LOCATION;
 
   return declarator;
 }
@@ -2400,6 +2402,16 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
        error_at (location, "%qE in namespace %qE does not name a type",
                  id, parser->scope);
+      else if (CLASS_TYPE_P (parser->scope)
+              && constructor_name_p (id, parser->scope))
+       {
+         /* A<T>::A<T>() */
+         error_at (location, "%<%T::%E%> names the constructor, not"
+                   " the type", parser->scope, id);
+         if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+           error_at (location, "and %qT has no template constructors",
+                     parser->scope);
+       }
       else if (TYPE_P (parser->scope)
               && dependent_scope_p (parser->scope))
        error_at (location, "need %<typename%> before %<%T::%E%> because "
@@ -2430,6 +2442,14 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
   tree id;
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
+  /* Avoid duplicate error about ambiguous lookup.  */
+  if (token->type == CPP_NESTED_NAME_SPECIFIER)
+    {
+      cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2);
+      if (next->type == CPP_NAME && next->ambiguous_p)
+       goto out;
+    }
+
   cp_parser_parse_tentatively (parser);
   id = cp_parser_id_expression (parser,
                                /*template_keyword_p=*/false,
@@ -2451,6 +2471,7 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
   /* Emit a diagnostic for the invalid type.  */
   cp_parser_diagnose_invalid_type_name (parser, parser->scope,
                                        id, token->location);
+ out:
   /* If we aren't in the middle of a declarator (i.e. in a
      parameter-declaration-clause), skip to the end of the declaration;
      there's no point in trying to process it.  */
@@ -3320,7 +3341,7 @@ cp_parser_primary_expression (cp_parser *parser,
       if (c_dialect_objc ())
         /* We have an Objective-C++ message. */
         return cp_parser_objc_expression (parser);
-      maybe_warn_cpp0x ("lambda expressions");
+      maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
       return cp_parser_lambda_expression (parser);
 
     case CPP_OBJC_STRING:
@@ -3509,6 +3530,16 @@ cp_parser_primary_expression (cp_parser *parser,
          {
            tree ambiguous_decls;
 
+           /* If we already know that this lookup is ambiguous, then
+              we've already issued an error message; there's no reason
+              to check again.  */
+           if (id_expr_token->type == CPP_NAME
+               && id_expr_token->ambiguous_p)
+             {
+               cp_parser_simulate_error (parser);
+               return error_mark_node;
+             }
+
            decl = cp_parser_lookup_name (parser, id_expression,
                                          none_type,
                                          template_p,
@@ -3866,20 +3897,26 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
        gcc_assert (!scope || TYPE_P (scope));
 
-       /* If the name is of the form "X::~X" it's OK.  */
+       /* If the name is of the form "X::~X" it's OK even if X is a
+          typedef.  */
        token = cp_lexer_peek_token (parser->lexer);
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
-               == CPP_OPEN_PAREN)
-           && constructor_name_p (token->u.value, scope))
+               != CPP_LESS)
+           && (token->u.value == TYPE_IDENTIFIER (scope)
+               || constructor_name_p (token->u.value, scope)))
          {
            cp_lexer_consume_token (parser->lexer);
            return build_nt (BIT_NOT_EXPR, scope);
          }
 
        /* If there was an explicit qualification (S::~T), first look
-          in the scope given by the qualification (i.e., S).  */
+          in the scope given by the qualification (i.e., S).
+
+          Note: in the calls to cp_parser_class_name below we pass
+          typename_type so that lookup finds the injected-class-name
+          rather than the constructor.  */
        done = false;
        type_decl = NULL_TREE;
        if (scope)
@@ -3888,7 +3925,7 @@ cp_parser_unqualified_id (cp_parser* parser,
            type_decl = cp_parser_class_name (parser,
                                              /*typename_keyword_p=*/false,
                                              /*template_keyword_p=*/false,
-                                             none_type,
+                                             typename_type,
                                              /*check_dependency=*/false,
                                              /*class_head_p=*/false,
                                              declarator_p);
@@ -3906,7 +3943,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3924,7 +3961,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3943,7 +3980,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     none_type,
+                                     typename_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -4406,6 +4443,16 @@ cp_parser_qualifying_entity (cp_parser *parser,
      
       /* Parse a typedef-name or enum-name.  */
       scope = cp_parser_nonclass_name (parser);
+
+      /* "If the name found does not designate a namespace or a class,
+        enumeration, or dependent type, the program is ill-formed."
+
+         We cover classes and dependent types above and namespaces below,
+         so this code is only looking for enums.  */
+      if (!scope || TREE_CODE (scope) != TYPE_DECL
+         || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE)
+       cp_parser_simulate_error (parser);
+
       successful_parse_p = cp_parser_parse_definitely (parser);
     }
   /* If that didn't work, try for a namespace-name.  */
@@ -4504,7 +4551,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* New types cannot be defined in the cast.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in casts";
+         = G_("types may not be defined in casts");
 
        /* Look for the opening `<'.  */
        cp_parser_require (parser, CPP_LESS, "%<<%>");
@@ -4567,7 +4614,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
        /* Types cannot be defined in a `typeid' expression.  */
        saved_message = parser->type_definition_forbidden_message;
        parser->type_definition_forbidden_message
-         = "types may not be defined in a %<typeid%> expression";
+         = G_("types may not be defined in a %<typeid%> expression");
        /* We can't be sure yet whether we're looking at a type-id or an
           expression.  */
        cp_parser_parse_tentatively (parser);
@@ -4811,14 +4858,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                         && is_overloaded_fn (postfix_expression))
                  {
                    tree fn = get_first_fn (postfix_expression);
+                   fn = STRIP_TEMPLATE (fn);
 
-                   if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-                     fn = OVL_CURRENT (TREE_OPERAND (fn, 0));
-
-                   /* Only do argument dependent lookup if regular
-                      lookup does not find a set of member functions.
-                      [basic.lookup.koenig]/2a  */
-                   if (!DECL_FUNCTION_MEMBER_P (fn))
+                   /* Do not do argument dependent lookup if regular
+                      lookup finds a member function or a block-scope
+                      function declaration.  [basic.lookup.argdep]/3  */
+                   if (!DECL_FUNCTION_MEMBER_P (fn)
+                       && !DECL_LOCAL_FUNCTION_P (fn))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
@@ -5256,7 +5302,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
            if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
              {
                /* A braced-init-list.  */
-               maybe_warn_cpp0x ("extended initializer lists");
+               maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
                expr = cp_parser_braced_list (parser, &expr_non_constant_p);
                if (non_constant_p && expr_non_constant_p)
                  *non_constant_p = true;
@@ -5596,7 +5642,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
        {
        case INDIRECT_REF:
          non_constant_p = "%<*%>";
-         expression = build_x_indirect_ref (cast_expression, "unary *",
+         expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
                                              tf_warning_or_error);
          break;
 
@@ -5805,7 +5851,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
      complete.)  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in a new-type-id";
+    = G_("types may not be defined in a new-type-id");
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
                                /*is_trailing_return=*/false,
@@ -5973,7 +6019,7 @@ cp_parser_new_initializer (cp_parser* parser)
     {
       tree t;
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       t = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
       expression_list = make_tree_vector_single (t);
@@ -6118,7 +6164,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
       /* Types may not be defined in a cast.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in casts";
+       = G_("types may not be defined in casts");
       /* Consume the `('.  */
       cp_lexer_consume_token (parser->lexer);
       /* A very tricky bit is that `(struct S) { 3 }' is a
@@ -6534,7 +6580,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
              tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
 
              if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
-               maybe_warn_cpp0x ("extended initializer lists");
+               maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
              /* An assignment may not appear in a
                 constant-expression.  */
@@ -7039,6 +7085,8 @@ cp_parser_lambda_expression (cp_parser* parser)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  cp_parser_lambda_introducer (parser, lambda_expr);
+
   type = begin_lambda_type (lambda_expr);
 
   record_lambda_scope (lambda_expr);
@@ -7046,6 +7094,10 @@ cp_parser_lambda_expression (cp_parser* parser)
   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   determine_visibility (TYPE_NAME (type));
 
+  /* Now that we've started the type, add the capture fields for any
+     explicit captures.  */
+  register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
+
   {
     /* Inside the class, surrounding template-parameter-lists do not apply.  */
     unsigned int saved_num_template_parameter_lists
@@ -7053,8 +7105,6 @@ cp_parser_lambda_expression (cp_parser* parser)
 
     parser->num_template_parameter_lists = 0;
 
-    cp_parser_lambda_introducer (parser, lambda_expr);
-
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
 
@@ -7353,21 +7403,12 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
                                     sfk_none);
 
-    quals = TYPE_UNQUALIFIED;
-    if (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) == NULL_TREE
-       && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
-      {
-       /* A lambda with no captures has a static op() and a conversion op
-          to function type.  */
-       if (LAMBDA_EXPR_MUTABLE_P (lambda_expr))
-         error ("lambda expression with no captures declared mutable");
-       return_type_specs.storage_class = sc_static;
-      }
-    else if (!LAMBDA_EXPR_MUTABLE_P (lambda_expr))
-      quals = TYPE_QUAL_CONST;
+    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
+            ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
     declarator = make_call_declarator (declarator, param_list, quals,
                                       exception_spec,
                                        /*late_return_type=*/NULL_TREE);
+    declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
 
     fco = grokmethod (&return_type_specs,
                      declarator,
@@ -7771,13 +7812,24 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
     statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
-  /* Give a helpful message for "A<T>::type t;"  */
+  /* Give a helpful message for "A<T>::type t;" and the like.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
-      && !cp_parser_uncommitted_to_tentative_parse_p (parser)
-      && TREE_CODE (statement) == SCOPE_REF)
-    error_at (token->location, "need %<typename%> before %qE because "
-             "%qT is a dependent scope",
-             statement, TREE_OPERAND (statement, 0));
+      && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+    {
+      if (TREE_CODE (statement) == SCOPE_REF)
+       error_at (token->location, "need %<typename%> before %qE because "
+                 "%qT is a dependent scope",
+                 statement, TREE_OPERAND (statement, 0));
+      else if (is_overloaded_fn (statement)
+              && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
+       {
+         /* A::A a; */
+         tree fn = get_first_fn (statement);
+         error_at (token->location,
+                   "%<%T::%D%> names the constructor, not the type",
+                   DECL_CONTEXT (fn), DECL_NAME (fn));
+       }
+    }
 
   /* Consume the final `;'.  */
   cp_parser_consume_semicolon_at_end_of_statement (parser);
@@ -8060,7 +8112,7 @@ cp_parser_condition (cp_parser* parser)
      condition.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in conditions";
+    = G_("types may not be defined in conditions");
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration==*/true,
                                /*is_trailing_return=*/false,
@@ -8124,7 +8176,7 @@ cp_parser_condition (cp_parser* parser)
              initializer = cp_parser_initializer_clause (parser, &non_constant_p);
            }
          if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
          if (!non_constant_p)
            initializer = fold_non_dependent_expr (initializer);
@@ -8304,7 +8356,7 @@ cp_parser_for_init_statement (cp_parser* parser)
        return;
     }
 
-  cp_parser_expression_statement (parser, false);
+  cp_parser_expression_statement (parser, NULL_TREE);
 }
 
 /* Parse a jump-statement.
@@ -8388,7 +8440,7 @@ cp_parser_jump_statement (cp_parser* parser)
 
        if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
          {
-           maybe_warn_cpp0x ("extended initializer lists");
+           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
            expr = cp_parser_braced_list (parser, &expr_non_constant_p);
          }
        else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -9470,7 +9522,7 @@ cp_parser_decltype (cp_parser *parser)
 
   /* And create the new one.  */
   parser->type_definition_forbidden_message
-    = "types may not be defined in %<decltype%> expressions";
+    = G_("types may not be defined in %<decltype%> expressions");
 
   /* The restrictions on constant-expressions do not apply inside
      decltype expressions.  */
@@ -9903,7 +9955,7 @@ cp_parser_mem_initializer (cp_parser* parser)
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       expression_list = build_tree_list (NULL_TREE, expression_list);
@@ -9991,7 +10043,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
     return cp_parser_class_name (parser,
                                 /*typename_keyword_p=*/true,
                                 /*template_keyword_p=*/template_p,
-                                none_type,
+                                typename_type,
                                 /*check_dependency_p=*/true,
                                 /*class_head_p=*/false,
                                 /*is_declaration=*/true);
@@ -10498,7 +10550,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
 
   parm = grokdeclarator (parameter_declarator->declarator,
                         &parameter_declarator->decl_specifiers,
-                        PARM, /*initialized=*/0,
+                        TPARM, /*initialized=*/0,
                         /*attrlist=*/NULL);
   if (parm == error_mark_node)
     return error_mark_node;
@@ -10606,14 +10658,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
 
     case RID_TEMPLATE:
       {
-       tree parameter_list;
        tree identifier;
        tree default_argument;
 
        /* Look for the `<'.  */
        cp_parser_require (parser, CPP_LESS, "%<<%>");
        /* Parse the template-parameter-list.  */
-       parameter_list = cp_parser_template_parameter_list (parser);
+       cp_parser_template_parameter_list (parser);
        /* Look for the `>'.  */
        cp_parser_require (parser, CPP_GREATER, "%<>%>");
        /* Look for the `class' keyword.  */
@@ -10747,7 +10798,7 @@ cp_parser_template_id (cp_parser *parser,
   cp_token_position start_of_id = 0;
   deferred_access_check *chk;
   VEC (deferred_access_check,gc) *access_check;
-  cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL;
+  cp_token *next_token = NULL, *next_token_2 = NULL;
   bool is_identifier;
 
   /* If the next token corresponds to a template-id, there is no need
@@ -10795,7 +10846,6 @@ cp_parser_template_id (cp_parser *parser,
 
   /* Parse the template-name.  */
   is_identifier = false;
-  token = cp_lexer_peek_token (parser->lexer);
   templ = cp_parser_template_name (parser, template_keyword_p,
                                   check_dependency_p,
                                   is_declaration,
@@ -11076,12 +11126,11 @@ cp_parser_template_name (cp_parser* parser,
   /* Look up the name.  */
   decl = cp_parser_lookup_name (parser, identifier,
                                none_type,
-                               /*is_template=*/false,
+                               /*is_template=*/true,
                                /*is_namespace=*/false,
                                check_dependency_p,
                                /*ambiguous_decls=*/NULL,
                                token->location);
-  decl = maybe_get_template_decl_from_type_decl (decl);
 
   /* If DECL is a template, then the name was a template-name.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
@@ -11206,6 +11255,9 @@ cp_parser_template_argument_list (cp_parser* parser)
   parser->non_integral_constant_expression_p = saved_non_ice_p;
   parser->integral_constant_expression_p = saved_ice_p;
   parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+#ifdef ENABLE_CHECKING
+  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+#endif
   return vec;
 }
 
@@ -11473,7 +11525,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   int declares_class_or_enum;
   cp_decl_specifier_seq decl_specifiers;
   tree extension_specifier = NULL_TREE;
-  cp_token *token;
 
   /* Look for an (optional) storage-class-specifier or
      function-specifier.  */
@@ -11496,7 +11547,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
      control while processing explicit instantiation directives.  */
   push_deferring_access_checks (dk_no_check);
   /* Parse a decl-specifier-seq.  */
-  token = cp_lexer_peek_token (parser->lexer);
   cp_parser_decl_specifier_seq (parser,
                                CP_PARSER_FLAGS_OPTIONAL,
                                &decl_specifiers,
@@ -11915,7 +11965,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       break;
       
     case RID_AUTO:
-      maybe_warn_cpp0x ("C++0x auto");
+      maybe_warn_cpp0x (CPP0X_AUTO);
       type = make_auto ();
       break;
 
@@ -11953,8 +12003,6 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   /* If the type-specifier was for a built-in type, we're done.  */
   if (type)
     {
-      tree id;
-
       /* Record the type.  */
       if (decl_specs
          && (token->keyword != RID_SIGNED
@@ -11969,7 +12017,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
        decl_specs->any_specifiers_p = true;
 
       /* Consume the token.  */
-      id = cp_lexer_consume_token (parser->lexer)->u.value;
+      cp_lexer_consume_token (parser->lexer);
 
       /* There is no valid C++ program where a non-template type is
         followed by a "<".  That usually indicates that the user thought
@@ -12222,7 +12270,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
           || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
         {
           if (cxx_dialect == cxx98)
-            maybe_warn_cpp0x ("scoped enums");
+            maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
           /* Consume the `struct' or `class'.  */
           cp_lexer_consume_token (parser->lexer);
@@ -12559,7 +12607,7 @@ cp_parser_enum_specifier (cp_parser* parser)
       || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
     {
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       /* Consume the `struct' or `class' token.  */
       cp_lexer_consume_token (parser->lexer);
@@ -12593,7 +12641,7 @@ cp_parser_enum_specifier (cp_parser* parser)
        return NULL_TREE;
 
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       has_underlying_type = true;
 
@@ -13433,6 +13481,11 @@ cp_parser_init_declarator (cp_parser* parser,
      we compute it now.  */
   scope = get_scope_of_declarator (declarator);
 
+  /* Perform any lookups in the declared type which were thought to be
+     dependent, but are not in the scope of the declarator.  */
+  decl_specifiers->type
+    = maybe_update_decl_type (decl_specifiers->type, scope);
+
   /* If we're allowing GNU extensions, look for an asm-specification
      and attributes.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
@@ -13757,7 +13810,6 @@ cp_parser_declarator (cp_parser* parser,
                      bool* parenthesized_p,
                      bool member_p)
 {
-  cp_token *token;
   cp_declarator *declarator;
   enum tree_code code;
   cp_cv_quals cv_quals;
@@ -13772,9 +13824,6 @@ cp_parser_declarator (cp_parser* parser,
   if (cp_parser_allow_gnu_extensions_p (parser))
     attributes = cp_parser_attributes_opt (parser);
 
-  /* Peek at the next token.  */
-  token = cp_lexer_peek_token (parser->lexer);
-
   /* Check for the ptr-operator production.  */
   cp_parser_parse_tentatively (parser);
   /* Parse the ptr-operator.  */
@@ -14059,11 +14108,13 @@ cp_parser_direct_declarator (cp_parser* parser,
                bounds = fold_non_dependent_expr (bounds);
              /* Normally, the array bound must be an integral constant
                 expression.  However, as an extension, we allow VLAs
-                in function scopes.  */
-             else if (!parser->in_function_body)
+                in function scopes as long as they aren't part of a
+                parameter declaration.  */
+             else if (!parser->in_function_body
+                      || current_binding_level->kind == sk_function_parms)
                {
-                 error_at (token->location,
-                           "array bound is not an integer constant");
+                 cp_parser_error (parser,
+                                  "array bound is not an integer constant");
                  bounds = error_mark_node;
                }
              else if (processing_template_decl && !error_operand_p (bounds))
@@ -14181,10 +14232,17 @@ cp_parser_direct_declarator (cp_parser* parser,
                                              /*only_current_p=*/false);
                /* If that failed, the declarator is invalid.  */
                if (TREE_CODE (type) == TYPENAME_TYPE)
-                 error_at (declarator_id_start_token->location,
-                           "%<%T::%E%> is not a type",
-                           TYPE_CONTEXT (qualifying_scope),
-                           TYPE_IDENTIFIER (qualifying_scope));
+                 {
+                   if (typedef_variant_p (type))
+                     error_at (declarator_id_start_token->location,
+                               "cannot define member of dependent typedef "
+                               "%qT", type);
+                   else
+                     error_at (declarator_id_start_token->location,
+                               "%<%T::%E%> is not a type",
+                               TYPE_CONTEXT (qualifying_scope),
+                               TYPE_IDENTIFIER (qualifying_scope));
+                 }
                qualifying_scope = type;
              }
 
@@ -14250,6 +14308,10 @@ cp_parser_direct_declarator (cp_parser* parser,
                        unqualified_name = constructor_name (class_type);
                        sfk = sfk_constructor;
                      }
+                   else if (is_overloaded_fn (unqualified_name)
+                            && DECL_CONSTRUCTOR_P (get_first_fn
+                                                   (unqualified_name)))
+                     sfk = sfk_constructor;
 
                    if (ctor_dtor_or_conv_p && sfk != sfk_none)
                      *ctor_dtor_or_conv_p = -1;
@@ -14958,7 +15020,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
                                 bool *parenthesized_p)
 {
   int declares_class_or_enum;
-  bool greater_than_is_operator_p;
   cp_decl_specifier_seq decl_specifiers;
   cp_declarator *declarator;
   tree default_argument;
@@ -14973,12 +15034,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
      template-parameter, the first non-nested `>' is taken as the end
      of the template parameter-list rather than a greater-than
      operator.  */
-  greater_than_is_operator_p = !template_parm_p;
 
   /* Type definitions may not appear in parameter types.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in parameter types";
+    = G_("types may not be defined in parameter types");
 
   /* Parse the declaration-specifiers.  */
   cp_parser_decl_specifier_seq (parser,
@@ -15400,7 +15460,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
     }
   else if (token->type == CPP_OPEN_BRACE)
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       init = cp_parser_braced_list (parser, non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
     }
@@ -15685,14 +15745,8 @@ cp_parser_class_name (cp_parser *parser,
                                        identifier_token->location);
          if (ambiguous_decls)
            {
-             error_at (identifier_token->location,
-                       "reference to %qD is ambiguous", identifier);
-             print_candidates (ambiguous_decls);
              if (cp_parser_parsing_tentatively (parser))
-               {
-                 identifier_token->ambiguous_p = true;
-                 cp_parser_simulate_error (parser);
-               }
+               cp_parser_simulate_error (parser);
              return error_mark_node;
            }
        }
@@ -16870,7 +16924,7 @@ cp_parser_pure_specifier (cp_parser* parser)
   if (token->keyword == RID_DEFAULT
       || token->keyword == RID_DELETE)
     {
-      maybe_warn_cpp0x ("defaulted and deleted functions");
+      maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
       return token->u.value;
     }
 
@@ -17174,7 +17228,7 @@ cp_parser_exception_specification_opt (cp_parser* parser)
       /* Types may not be defined in an exception-specification.  */
       saved_message = parser->type_definition_forbidden_message;
       parser->type_definition_forbidden_message
-       = "types may not be defined in an exception-specification";
+       = G_("types may not be defined in an exception-specification");
       /* Parse the type-id-list.  */
       type_id_list = cp_parser_type_id_list (parser);
       /* Restore the saved message.  */
@@ -17355,7 +17409,7 @@ cp_parser_exception_declaration (cp_parser* parser)
   /* Types may not be defined in exception-declarations.  */
   saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
-    = "types may not be defined in exception-declarations";
+    = G_("types may not be defined in exception-declarations");
 
   /* Parse the type-specifier-seq.  */
   cp_parser_type_specifier_seq (parser, /*is_declaration=*/true,
@@ -17944,6 +17998,26 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
             lookup_member, we must enter the scope here.  */
          if (dependent_p)
            pushed_scope = push_scope (parser->scope);
+
+         /* 3.4.3.1: In a lookup in which the constructor is an acceptable
+            lookup result and the nested-name-specifier nominates a class C:
+              * if the name specified after the nested-name-specifier, when
+              looked up in C, is the injected-class-name of C (Clause 9), or
+              * if the name specified after the nested-name-specifier is the
+              same as the identifier or the simple-template-id's template-
+              name in the last component of the nested-name-specifier,
+            the name is instead considered to name the constructor of
+            class C. [ Note: for example, the constructor is not an
+            acceptable lookup result in an elaborated-type-specifier so
+            the constructor would not be used in place of the
+            injected-class-name. --end note ] Such a constructor name
+            shall be used only in the declarator-id of a declaration that
+            names a constructor or in a using-declaration.  */
+         if (tag_type == none_type
+             && CLASS_TYPE_P (parser->scope)
+             && constructor_name_p (name, parser->scope))
+           name = ctor_identifier;
+
          /* If the PARSER->SCOPE is a template specialization, it
             may be instantiated during name lookup.  In that case,
             errors may be issued.  Even if we rollback the current
@@ -18028,6 +18102,10 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
   if (!decl || decl == error_mark_node)
     return error_mark_node;
 
+  /* Pull out the template from an injected-class-name (or multiple).  */
+  if (is_template)
+    decl = maybe_get_template_decl_from_type_decl (decl);
+
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   if (TREE_CODE (decl) == TREE_LIST)
     {
@@ -18143,10 +18221,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
       if (declarator->u.id.qualifying_scope)
        {
          tree scope;
-         tree member;
 
          scope = declarator->u.id.qualifying_scope;
-         member = declarator->u.id.unqualified_name;
 
          while (scope && CLASS_TYPE_P (scope))
            {
@@ -18291,8 +18367,7 @@ static bool
 cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
 {
   bool constructor_p;
-  tree type_decl = NULL_TREE;
-  bool nested_name_p;
+  tree nested_name_specifier;
   cp_token *next_token;
 
   /* The common case is that this is not a constructor declarator, so
@@ -18318,34 +18393,48 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
   cp_parser_global_scope_opt (parser,
                              /*current_scope_valid_p=*/false);
   /* Look for the nested-name-specifier.  */
-  nested_name_p
+  nested_name_specifier
     = (cp_parser_nested_name_specifier_opt (parser,
                                            /*typename_keyword_p=*/false,
                                            /*check_dependency_p=*/false,
                                            /*type_p=*/false,
-                                           /*is_declaration=*/false)
-       != NULL_TREE);
+                                           /*is_declaration=*/false));
   /* Outside of a class-specifier, there must be a
      nested-name-specifier.  */
-  if (!nested_name_p &&
+  if (!nested_name_specifier &&
       (!at_class_scope_p () || !TYPE_BEING_DEFINED (current_class_type)
        || friend_p))
     constructor_p = false;
+  else if (nested_name_specifier == error_mark_node)
+    constructor_p = false;
+
+  /* If we have a class scope, this is easy; DR 147 says that S::S always
+     names the constructor, and no other qualified name could.  */
+  if (constructor_p && nested_name_specifier
+      && TYPE_P (nested_name_specifier))
+    {
+      tree id = cp_parser_unqualified_id (parser,
+                                         /*template_keyword_p=*/false,
+                                         /*check_dependency_p=*/false,
+                                         /*declarator_p=*/true,
+                                         /*optional_p=*/false);
+      if (is_overloaded_fn (id))
+       id = DECL_NAME (get_first_fn (id));
+      if (!constructor_name_p (id, nested_name_specifier))
+       constructor_p = false;
+    }
   /* If we still think that this might be a constructor-declarator,
      look for a class-name.  */
-  if (constructor_p)
+  else if (constructor_p)
     {
       /* If we have:
 
-          template <typename T> struct S { S(); };
-          template <typename T> S<T>::S ();
-
-        we must recognize that the nested `S' names a class.
-        Similarly, for:
+          template <typename T> struct S {
+            S();
+          };
 
-          template <typename T> S<T>::S<T> ();
-
-        we must recognize that the nested `S' names a template.  */
+        we must recognize that the nested `S' names a class.  */
+      tree type_decl;
       type_decl = cp_parser_class_name (parser,
                                        /*typename_keyword_p=*/false,
                                        /*template_keyword_p=*/false,
@@ -18355,22 +18444,23 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
                                        /*is_declaration=*/false);
       /* If there was no class-name, then this is not a constructor.  */
       constructor_p = !cp_parser_error_occurred (parser);
-    }
 
-  /* If we're still considering a constructor, we have to see a `(',
-     to begin the parameter-declaration-clause, followed by either a
-     `)', an `...', or a decl-specifier.  We need to check for a
-     type-specifier to avoid being fooled into thinking that:
+      /* If we're still considering a constructor, we have to see a `(',
+        to begin the parameter-declaration-clause, followed by either a
+        `)', an `...', or a decl-specifier.  We need to check for a
+        type-specifier to avoid being fooled into thinking that:
 
-       S::S (f) (int);
+          S (f) (int);
 
-     is a constructor.  (It is actually a function named `f' that
-     takes one parameter (of type `int') and returns a value of type
-     `S::S'.  */
-  if (constructor_p
-      && cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
-    {
-      if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
+        is a constructor.  (It is actually a function named `f' that
+        takes one parameter (of type `int') and returns a value of type
+        `S'.  */
+      if (constructor_p
+         && !cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
+       constructor_p = false;
+
+      if (constructor_p
+         && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
          && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
          /* A parameter declaration begins with a decl-specifier,
             which is either the "attribute" keyword, a storage class
@@ -18425,8 +18515,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
          constructor_p = !cp_parser_error_occurred (parser);
        }
     }
-  else
-    constructor_p = false;
+
   /* We did not really want to consume any tokens.  */
   cp_parser_abort_tentative_parse (parser);
 
@@ -18866,7 +18955,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &nonconst_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       if (TREE_CODE (type) == TYPE_DECL)
@@ -23032,7 +23121,6 @@ pragma_lex (tree *value)
 void
 c_parse_file (void)
 {
-  bool error_occurred;
   static bool already_called = false;
 
   if (already_called)
@@ -23045,7 +23133,7 @@ c_parse_file (void)
   the_parser = cp_parser_new ();
   push_deferring_access_checks (flag_access_control
                                ? dk_no_deferred : dk_no_check);
-  error_occurred = cp_parser_translation_unit (the_parser);
+  cp_parser_translation_unit (the_parser);
   the_parser = NULL;
 }