OSDN Git Service

PR c++/19244
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 1a97868..86a96fb 100644 (file)
@@ -1,5 +1,6 @@
 /* C++ Parser.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004,
+   2005  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -747,8 +748,6 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
    Other parts of the front end that need to create entities (like
    VAR_DECLs or FUNCTION_DECLs) should do that directly.  */
 
-static cp_declarator *make_id_declarator
-  (tree);
 static cp_declarator *make_call_declarator
   (cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
 static cp_declarator *make_array_declarator
@@ -792,15 +791,31 @@ make_declarator (cp_declarator_kind kind)
   return declarator;
 }
 
-/* Make a declarator for a generalized identifier.  */
+/* Make a declarator for a generalized identifier.  If non-NULL, the
+   identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is
+   just UNQUALIFIED_NAME.  */
 
-cp_declarator *
-make_id_declarator (tree id)
+static cp_declarator *
+make_id_declarator (tree qualifying_scope, tree unqualified_name)
 {
   cp_declarator *declarator;
 
+  /* It is valid to write:
+
+       class C { void f(); };
+       typedef C D;
+       void D::f();
+
+     The standard is not clear about whether `typedef const C D' is
+     legal; as of 2002-09-15 the committee is considering that
+     question.  EDG 3.0 allows that syntax.  Therefore, we do as
+     well.  */
+  if (qualifying_scope && TYPE_P (qualifying_scope))
+    qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
+
   declarator = make_declarator (cdk_id);
-  declarator->u.id.name = id;
+  declarator->u.id.qualifying_scope = qualifying_scope;
+  declarator->u.id.unqualified_name = unqualified_name;
   declarator->u.id.sfk = sfk_none;
 
   return declarator;
@@ -1514,7 +1529,7 @@ static bool cp_parser_ctor_initializer_opt_and_function_body
 /* Classes [gram.class] */
 
 static tree cp_parser_class_name
-  (cp_parser *, bool, bool, bool, bool, bool, bool);
+  (cp_parser *, bool, bool, enum tag_types, bool, bool, bool);
 static tree cp_parser_class_specifier
   (cp_parser *);
 static tree cp_parser_class_head
@@ -1623,7 +1638,7 @@ static void cp_parser_label_declaration
 /* Utility Routines */
 
 static tree cp_parser_lookup_name
-  (cp_parser *, tree, bool, bool, bool, bool, bool *);
+  (cp_parser *, tree, enum tag_types, bool, bool, bool, bool *);
 static tree cp_parser_lookup_name_simple
   (cp_parser *, tree);
 static tree cp_parser_maybe_treat_template_as_class
@@ -1702,7 +1717,7 @@ static bool cp_parser_parse_definitely
   (cp_parser *);
 static inline bool cp_parser_parsing_tentatively
   (cp_parser *);
-static bool cp_parser_committed_to_tentative_parse
+static bool cp_parser_uncommitted_to_tentative_parse_p
   (cp_parser *);
 static void cp_parser_error
   (cp_parser *, const char *);
@@ -1713,7 +1728,7 @@ static bool cp_parser_simulate_error
 static void cp_parser_check_type_definition
   (cp_parser *);
 static void cp_parser_check_for_definition_in_return_type
-  (cp_declarator *, int);
+  (cp_declarator *, tree);
 static void cp_parser_check_for_invalid_template_id
   (cp_parser *, tree);
 static bool cp_parser_non_integral_constant_expression
@@ -1784,6 +1799,12 @@ cp_parser_error (cp_parser* parser, const char* message)
       /* This diagnostic makes more sense if it is tagged to the line
         of the token we just peeked at.  */
       cp_lexer_set_source_position_from_token (token);
+      if (token->type == CPP_PRAGMA)
+       {
+         error ("%<#pragma%> is not allowed here"); 
+         cp_lexer_purge_token (parser->lexer);
+         return;
+       }
       c_parse_error (message,
                     /* Because c_parser_error does not understand
                        CPP_KEYWORD, keywords are treated like
@@ -1838,8 +1859,7 @@ cp_parser_name_lookup_error (cp_parser* parser,
 static bool
 cp_parser_simulate_error (cp_parser* parser)
 {
-  if (cp_parser_parsing_tentatively (parser)
-      && !cp_parser_committed_to_tentative_parse (parser))
+  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
     {
       parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
       return true;
@@ -1861,14 +1881,14 @@ cp_parser_check_type_definition (cp_parser* parser)
     error ("%s", parser->type_definition_forbidden_message);
 }
 
-/* This function is called when a declaration is parsed.  If
-   DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM
-   indicates that a type was defined in the decl-specifiers for DECL,
-   then an error is issued.  */
+/* This function is called when the DECLARATOR is processed.  The TYPE
+   was a type defined in the decl-specifiers.  If it is invalid to
+   define a type in the decl-specifiers for DECLARATOR, an error is
+   issued.  */
 
 static void
 cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
-                                              int declares_class_or_enum)
+                                              tree type)
 {
   /* [dcl.fct] forbids type definitions in return types.
      Unfortunately, it's not easy to know whether or not we are
@@ -1879,9 +1899,12 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
             || declarator->kind == cdk_ptrmem))
     declarator = declarator->declarator;
   if (declarator
-      && declarator->kind == cdk_function
-      && declares_class_or_enum & 2)
-    error ("new types may not be defined in a return type");
+      && declarator->kind == cdk_function)
+    {
+      error ("new types may not be defined in a return type");
+      inform ("(perhaps a semicolon is missing after the definition of %qT)",
+             type);
+    }
 }
 
 /* A type-specifier (TYPE) has been parsed which cannot be followed by
@@ -1904,8 +1927,7 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
       else
        error ("invalid template-id");
       /* Remember the location of the invalid "<".  */
-      if (cp_parser_parsing_tentatively (parser)
-         && !cp_parser_committed_to_tentative_parse (parser))
+      if (cp_parser_uncommitted_to_tentative_parse_p (parser))
        start = cp_lexer_token_position (parser->lexer, true);
       /* Consume the "<".  */
       cp_lexer_consume_token (parser->lexer);
@@ -1938,9 +1960,8 @@ cp_parser_non_integral_constant_expression (cp_parser  *parser,
   return false;
 }
 
-/* Emit a diagnostic for an invalid type name. Consider also if it is
-   qualified or not and the result of a lookup, to provide a better
-   message.  */
+/* Emit a diagnostic for an invalid type name.  SCOPE is the
+   qualifying scope (or NULL, if none) for ID.  */
 
 static void
 cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
@@ -2073,8 +2094,8 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
   unsigned brace_depth = 0;
   int result;
 
-  if (recovering && !or_comma && cp_parser_parsing_tentatively (parser)
-      && !cp_parser_committed_to_tentative_parse (parser))
+  if (recovering && !or_comma
+      && cp_parser_uncommitted_to_tentative_parse_p (parser))
     return 0;
 
   while (true)
@@ -2295,12 +2316,13 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id)
   tree result;
   if (TREE_CODE (id) == IDENTIFIER_NODE)
     {
-      result = make_typename_type (scope, id, /*complain=*/0);
+      result = make_typename_type (scope, id, typename_type,
+                                  /*complain=*/0);
       if (result == error_mark_node)
        cp_parser_diagnose_invalid_type_name (parser, scope, id);
       return result;
     }
-  return make_typename_type (scope, id, tf_error);
+  return make_typename_type (scope, id, typename_type, tf_error);
 }
 
 
@@ -2831,7 +2853,7 @@ cp_parser_primary_expression (cp_parser *parser,
            bool ambiguous_p;
 
            decl = cp_parser_lookup_name (parser, id_expression,
-                                         /*is_type=*/false,
+                                         none_type,
                                          /*is_template=*/false,
                                          /*is_namespace=*/false,
                                          /*check_dependency=*/true,
@@ -3164,7 +3186,7 @@ cp_parser_unqualified_id (cp_parser* parser,
            type_decl = cp_parser_class_name (parser,
                                              /*typename_keyword_p=*/false,
                                              /*template_keyword_p=*/false,
-                                             /*type_p=*/false,
+                                             none_type,
                                              /*check_dependency=*/false,
                                              /*class_head_p=*/false,
                                              declarator_p);
@@ -3182,7 +3204,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     /*type_p=*/false,
+                                     none_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3200,7 +3222,7 @@ cp_parser_unqualified_id (cp_parser* parser,
              = cp_parser_class_name (parser,
                                      /*typename_keyword_p=*/false,
                                      /*template_keyword_p=*/false,
-                                     /*type_p=*/false,
+                                     none_type,
                                      /*check_dependency=*/false,
                                      /*class_head_p=*/false,
                                      declarator_p);
@@ -3215,7 +3237,7 @@ cp_parser_unqualified_id (cp_parser* parser,
          = cp_parser_class_name (parser,
                                  /*typename_keyword_p=*/false,
                                  /*template_keyword_p=*/false,
-                                 /*type_p=*/false,
+                                 none_type,
                                  /*check_dependency=*/false,
                                  /*class_head_p=*/false,
                                  declarator_p);
@@ -3234,7 +3256,8 @@ cp_parser_unqualified_id (cp_parser* parser,
           identifier in the declarator for a destructor declaration.  */
        if (declarator_p
            && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
-           && !DECL_SELF_REFERENCE_P (type_decl))
+           && !DECL_SELF_REFERENCE_P (type_decl)
+           && !cp_parser_uncommitted_to_tentative_parse_p (parser))
          error ("typedef-name %qD used as destructor declarator",
                 type_decl);
 
@@ -3320,8 +3343,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
     }
 
   /* Remember where the nested-name-specifier starts.  */
-  if (cp_parser_parsing_tentatively (parser)
-      && !cp_parser_committed_to_tentative_parse (parser))
+  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
     start = cp_lexer_token_position (parser->lexer, false);
 
   push_deferring_access_checks (dk_deferred);
@@ -3579,7 +3601,7 @@ cp_parser_class_or_namespace_name (cp_parser *parser,
   scope = cp_parser_class_name (parser,
                                typename_keyword_p,
                                template_keyword_p,
-                               type_p,
+                               type_p ? class_type : none_type,
                                check_dependency_p,
                                /*class_head_p=*/false,
                                is_declaration);
@@ -3815,6 +3837,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
           functional cast is being performed.  */
        else
          type = make_typename_type (parser->scope, id,
+                                    typename_type,
                                     /*complain=*/1);
 
        postfix_expression = cp_parser_functional_cast (parser, type);
@@ -4275,18 +4298,28 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
       if (parser->scope)
        *idk = CP_ID_KIND_QUALIFIED;
 
-      if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
+      /* If the name is a template-id that names a type, we will get a
+        TYPE_DECL here.  That is invalid code.  */
+      if (TREE_CODE (name) == TYPE_DECL)
        {
-         name = build_nt (SCOPE_REF, parser->scope, name);
-         parser->scope = NULL_TREE;
-         parser->qualifying_scope = NULL_TREE;
-         parser->object_scope = NULL_TREE;
+         error ("invalid use of %qD", name);
+         postfix_expression = error_mark_node;
+       }
+      else
+       {
+         if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
+           {
+             name = build_nt (SCOPE_REF, parser->scope, name);
+             parser->scope = NULL_TREE;
+             parser->qualifying_scope = NULL_TREE;
+             parser->object_scope = NULL_TREE;
+           }
+         if (scope && name && BASELINK_P (name))
+           adjust_result_of_qualified_name_lookup
+             (name, BINFO_TYPE (BASELINK_BINFO (name)), scope);
+         postfix_expression
+           = finish_class_member_access_expr (postfix_expression, name);
        }
-      if (scope && name && BASELINK_P (name))
-       adjust_result_of_qualified_name_lookup
-         (name, BINFO_TYPE (BASELINK_BINFO (name)), scope);
-      postfix_expression
-       = finish_class_member_access_expr (postfix_expression, name);
     }
 
   /* We no longer need to look up names in the scope of the object on
@@ -4886,15 +4919,7 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
       *nelts = declarator->u.array.bounds;
       if (*nelts == error_mark_node)
        *nelts = integer_one_node;
-      else if (!processing_template_decl)
-       {
-         if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, *nelts,
-                                          false))
-           pedwarn ("size in array new must have integral type");
-         *nelts = save_expr (cp_convert (sizetype, *nelts));
-         if (*nelts == integer_zero_node)
-           warning ("zero size array reserves no space");
-       }
+      
       if (outer_declarator)
        outer_declarator->declarator = declarator->declarator;
       else
@@ -6207,13 +6232,13 @@ cp_parser_condition (cp_parser* parser)
         for sure.  */
       if (cp_parser_parse_definitely (parser))
        {
-         bool pop_p;   
+         tree pushed_scope;    
 
          /* Create the declaration.  */
          decl = start_decl (declarator, &type_specifiers,
                             /*initialized_p=*/true,
                             attributes, /*prefix_attributes=*/NULL_TREE,
-                            &pop_p);
+                            &pushed_scope);
          /* Parse the assignment-expression.  */
          initializer = cp_parser_assignment_expression (parser);
 
@@ -6223,8 +6248,8 @@ cp_parser_condition (cp_parser* parser)
                          asm_specification,
                          LOOKUP_ONLYCONVERTING);
 
-         if (pop_p)
-           pop_scope (DECL_CONTEXT (decl));
+         if (pushed_scope)
+           pop_scope (pushed_scope);
 
          return convert_from_reference (decl);
        }
@@ -6939,8 +6964,7 @@ cp_parser_simple_declaration (cp_parser* parser,
          /* If we have already issued an error message we don't need
             to issue another one.  */
          if (decl != error_mark_node
-             || (cp_parser_parsing_tentatively (parser)
-                 && !cp_parser_committed_to_tentative_parse (parser)))
+             || cp_parser_uncommitted_to_tentative_parse_p (parser))
            cp_parser_error (parser, "expected %<,%> or %<;%>");
          /* Skip tokens until we reach the end of the statement.  */
          cp_parser_skip_to_end_of_statement (parser);
@@ -7374,7 +7398,7 @@ cp_parser_conversion_function_id (cp_parser* parser)
   tree saved_scope;
   tree saved_qualifying_scope;
   tree saved_object_scope;
-  bool pop_p = false;
+  tree pushed_scope = NULL_TREE;
 
   /* Look for the `operator' token.  */
   if (!cp_parser_require_keyword (parser, RID_OPERATOR, "`operator'"))
@@ -7399,12 +7423,12 @@ cp_parser_conversion_function_id (cp_parser* parser)
      In order to see that `I' is a type-name in the definition, we
      must be in the scope of `S'.  */
   if (saved_scope)
-    pop_p = push_scope (saved_scope);
+    pushed_scope = push_scope (saved_scope);
   /* Parse the conversion-type-id.  */
   type = cp_parser_conversion_type_id (parser);
   /* Leave the scope of the class, if any.  */
-  if (pop_p)
-    pop_scope (saved_scope);
+  if (pushed_scope)
+    pop_scope (pushed_scope);
   /* Restore the saved scope.  */
   parser->scope = saved_scope;
   parser->qualifying_scope = saved_qualifying_scope;
@@ -7659,7 +7683,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
     return cp_parser_class_name (parser,
                                 /*typename_keyword_p=*/true,
                                 /*template_keyword_p=*/template_p,
-                                /*type_p=*/false,
+                                none_type,
                                 /*check_dependency_p=*/true,
                                 /*class_head_p=*/false,
                                 /*is_declaration=*/true);
@@ -7669,7 +7693,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
   id = cp_parser_class_name (parser,
                             /*typename_keyword_p=*/true,
                             /*template_keyword_p=*/false,
-                            /*type_p=*/false,
+                            none_type,
                             /*check_dependency_p=*/true,
                             /*class_head_p=*/false,
                             /*is_declaration=*/true);
@@ -8014,9 +8038,10 @@ cp_parser_template_parameter_list (cp_parser* parser)
       /* Parse the template-parameter.  */
       parameter = cp_parser_template_parameter (parser, &is_non_type);
       /* Add it to the list.  */
-      parameter_list = process_template_parm (parameter_list,
-                                             parameter,
-                                             is_non_type);
+      if (parameter != error_mark_node)
+       parameter_list = process_template_parm (parameter_list,
+                                               parameter,
+                                               is_non_type);
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
       /* If it's not a `,', we're done.  */
@@ -8035,15 +8060,17 @@ cp_parser_template_parameter_list (cp_parser* parser)
      type-parameter
      parameter-declaration
 
-   Returns a TREE_LIST.  The TREE_VALUE represents the parameter.  The
-   TREE_PURPOSE is the default value, if any.  *IS_NON_TYPE is set to
-   true iff this parameter is a non-type parameter.  */
+   If all goes well, returns a TREE_LIST.  The TREE_VALUE represents
+   the parameter.  The TREE_PURPOSE is the default value, if any.
+   Returns ERROR_MARK_NODE on failure.  *IS_NON_TYPE is set to true
+   iff this parameter is a non-type parameter.  */
 
 static tree
 cp_parser_template_parameter (cp_parser* parser, bool *is_non_type)
 {
   cp_token *token;
   cp_parameter_declarator *parameter_declarator;
+  tree parm;
 
   /* Assume it is a type parameter or a template parameter.  */
   *is_non_type = false;
@@ -8092,12 +8119,13 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type)
   parameter_declarator
      = cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
                                        /*parenthesized_p=*/NULL);
-  return (build_tree_list
-         (parameter_declarator->default_argument,
-          grokdeclarator (parameter_declarator->declarator,
-                          &parameter_declarator->decl_specifiers,
-                          PARM, /*initialized=*/0,
-                          /*attrlist=*/NULL)));
+  parm = grokdeclarator (parameter_declarator->declarator,
+                        &parameter_declarator->decl_specifiers,
+                        PARM, /*initialized=*/0,
+                        /*attrlist=*/NULL);
+  if (parm == error_mark_node)
+    return error_mark_node;
+  return build_tree_list (parameter_declarator->default_argument, parm);
 }
 
 /* Parse a type-parameter.
@@ -8223,11 +8251,11 @@ cp_parser_type_parameter (cp_parser* parser)
              /* Look up the name.  */
              default_argument
                = cp_parser_lookup_name (parser, default_argument,
-                                       /*is_type=*/false,
-                                       /*is_template=*/is_template,
-                                       /*is_namespace=*/false,
-                                       /*check_dependency=*/true,
-                                       /*ambiguous_p=*/NULL);
+                                        none_type,
+                                        /*is_template=*/is_template,
+                                        /*is_namespace=*/false,
+                                        /*check_dependency=*/true,
+                                        /*ambiguous_p=*/NULL);
            /* See if the default argument is valid.  */
            default_argument
              = check_template_template_default_arg (default_argument);
@@ -8307,8 +8335,7 @@ cp_parser_template_id (cp_parser *parser,
     }
 
   /* Remember where the template-id starts.  */
-  if (cp_parser_parsing_tentatively (parser)
-      && !cp_parser_committed_to_tentative_parse (parser))
+  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
     start_of_id = cp_lexer_token_position (parser->lexer, false);
 
   push_deferring_access_checks (dk_deferred);
@@ -8409,8 +8436,9 @@ cp_parser_template_id (cp_parser *parser,
      should we re-parse the token stream, we will not have to repeat
      the effort required to do the parse, nor will we issue duplicate
      error messages about problems during instantiation of the
-     template.  */
-  if (start_of_id)
+     template.  Do so only if parsing succeeded, otherwise we may
+     silently accept template arguments with syntax errors.  */
+  if (start_of_id && !cp_parser_error_occurred (parser))
     {
       cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
       
@@ -8536,14 +8564,9 @@ cp_parser_template_name (cp_parser* parser,
          error ("non-template %qD used as template", identifier);
          inform ("use %<%T::template %D%> to indicate that it is a template",
                  parser->scope, identifier);
-         /* If parsing tentatively, find the location of the "<"
-            token.  */
-         if (cp_parser_parsing_tentatively (parser)
-             && !cp_parser_committed_to_tentative_parse (parser))
-           {
-             cp_parser_simulate_error (parser);
-             start = cp_lexer_token_position (parser->lexer, true);
-           }
+         /* If parsing tentatively, find the location of the "<" token.  */
+         if (cp_parser_simulate_error (parser))
+           start = cp_lexer_token_position (parser->lexer, true);
          /* Parse the template arguments so that we can issue error
             messages about them.  */
          cp_lexer_consume_token (parser->lexer);
@@ -8578,7 +8601,7 @@ cp_parser_template_name (cp_parser* parser,
 
   /* Look up the name.  */
   decl = cp_parser_lookup_name (parser, identifier,
-                               /*is_type=*/false,
+                               none_type,
                                /*is_template=*/false,
                                /*is_namespace=*/false,
                                check_dependency_p,
@@ -8769,7 +8792,7 @@ cp_parser_template_argument (cp_parser* parser)
         at this point in that case.  */
       if (TREE_CODE (argument) != TYPE_DECL)
        argument = cp_parser_lookup_name (parser, argument,
-                                         /*is_type=*/false,
+                                         none_type,
                                          /*is_template=*/template_p,
                                          /*is_namespace=*/false,
                                          /*check_dependency=*/true,
@@ -8806,6 +8829,7 @@ cp_parser_template_argument (cp_parser* parser)
       if (cp_parser_parse_definitely (parser))
        return argument;
     }
+
   /* If the next token is "&", the argument must be the address of an
      object or function with external linkage.  */
   address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
@@ -8828,6 +8852,12 @@ cp_parser_template_argument (cp_parser* parser)
        cp_parser_abort_tentative_parse (parser);
       else
        {
+         if (TREE_CODE (argument) == INDIRECT_REF)
+           {
+             gcc_assert (REFERENCE_REF_P (argument));
+             argument = TREE_OPERAND (argument, 0);
+           }
+         
          if (qualifying_class)
            argument = finish_qualified_id_expr (qualifying_class,
                                                 argument,
@@ -8851,6 +8881,8 @@ cp_parser_template_argument (cp_parser* parser)
                       || TREE_CODE (argument) == SCOPE_REF))
            /* A pointer-to-member.  */
            ;
+         else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
+           ;
          else
            cp_parser_simulate_error (parser);
 
@@ -8869,6 +8901,7 @@ cp_parser_template_argument (cp_parser* parser)
       cp_parser_error (parser, "invalid non-type template argument");
       return error_mark_node;
     }
+
   /* If the argument wasn't successfully parsed as a type-id followed
      by '>>', the argument can only be a constant expression now.
      Otherwise, we try parsing the constant-expression tentatively,
@@ -8971,8 +9004,9 @@ cp_parser_explicit_instantiation (cp_parser* parser)
                                /*ctor_dtor_or_conv_p=*/NULL,
                                /*parenthesized_p=*/NULL,
                                /*member_p=*/false);
-      cp_parser_check_for_definition_in_return_type (declarator,
-                                                    declares_class_or_enum);
+      if (declares_class_or_enum & 2)
+       cp_parser_check_for_definition_in_return_type (declarator,
+                                                      decl_specifiers.type);
       if (declarator != cp_error_declarator)
        {
          decl = grokdeclarator (declarator, &decl_specifiers,
@@ -9114,7 +9148,15 @@ cp_parser_type_specifier (cp_parser* parser,
              && cp_lexer_peek_nth_token (parser->lexer, 3)->type
                 == CPP_OPEN_BRACE))
        {
-         type_spec = cp_parser_enum_specifier (parser);
+         if (parser->num_template_parameter_lists)
+           {
+             error ("template declaration of %qs", "enum");
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             type_spec = error_mark_node;
+           }
+         else
+           type_spec = cp_parser_enum_specifier (parser);
+
          if (declares_class_or_enum)
            *declares_class_or_enum = 2;
          if (decl_specs)
@@ -9460,7 +9502,7 @@ cp_parser_type_name (cp_parser* parser)
   type_decl = cp_parser_class_name (parser,
                                    /*typename_keyword_p=*/false,
                                    /*template_keyword_p=*/false,
-                                   /*type_p=*/false,
+                                   none_type,
                                    /*check_dependency_p=*/true,
                                    /*class_head_p=*/false,
                                    /*is_declaration=*/false);
@@ -9612,6 +9654,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
               && tag_type == typename_type)
        type = make_typename_type (parser->scope, decl,
+                                  typename_type,
                                   /*complain=*/1);
       else
        type = TREE_TYPE (decl);
@@ -9629,7 +9672,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
        }
 
       /* For a `typename', we needn't call xref_tag.  */
-      if (tag_type == typename_type)
+      if (tag_type == typename_type 
+         && TREE_CODE (parser->scope) != NAMESPACE_DECL)
        return cp_parser_make_typename_type (parser, parser->scope,
                                             identifier);
       /* Look up a qualified name in the usual way.  */
@@ -9637,11 +9681,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
        {
          tree decl;
 
-         /* In an elaborated-type-specifier, names are assumed to name
-            types, so we set IS_TYPE to TRUE when calling
-            cp_parser_lookup_name.  */
          decl = cp_parser_lookup_name (parser, identifier,
-                                       /*is_type=*/true,
+                                       tag_type,
                                        /*is_template=*/false,
                                        /*is_namespace=*/false,
                                        /*check_dependency=*/true,
@@ -9674,7 +9715,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
          if (TREE_CODE (decl) != TYPE_DECL)
            {
-             error ("expected type-name");
+             cp_parser_diagnose_invalid_type_name (parser, 
+                                                   parser->scope,
+                                                   identifier);
              return error_mark_node;
            }
 
@@ -9731,15 +9774,23 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
             definition of a new type; a new type can only be declared in a
             declaration context.  */
 
+         tag_scope ts;
+         if (is_friend)
+           /* Friends have special name lookup rules.  */
+           ts = ts_within_enclosing_non_class;
+         else if (is_declaration
+                  && cp_lexer_next_token_is (parser->lexer,
+                                             CPP_SEMICOLON))
+           /* This is a `class-key identifier ;' */
+           ts = ts_current;
+         else
+           ts = ts_global;
+
          /* Warn about attributes. They are ignored.  */
          if (attributes)
            warning ("type attributes are honored only at type definition");
 
-         type = xref_tag (tag_type, identifier,
-                          (is_friend
-                           || !is_declaration
-                           || cp_lexer_next_token_is_not (parser->lexer,
-                                                          CPP_SEMICOLON)),
+         type = xref_tag (tag_type, identifier, ts,
                           parser->num_template_parameter_lists);
        }
     }
@@ -9921,7 +9972,7 @@ cp_parser_namespace_name (cp_parser* parser)
      function if the token after the name is the scope resolution
      operator.)  */
   namespace_decl = cp_parser_lookup_name (parser, identifier,
-                                         /*is_type=*/false,
+                                         none_type,
                                          /*is_template=*/false,
                                          /*is_namespace=*/true,
                                          /*check_dependency=*/true,
@@ -10125,9 +10176,7 @@ cp_parser_using_declaration (cp_parser* parser)
       if (at_class_scope_p ())
        {
          /* Create the USING_DECL.  */
-         decl = do_class_using_decl (build_nt (SCOPE_REF,
-                                               parser->scope,
-                                               identifier));
+         decl = do_class_using_decl (parser->scope, identifier);
          /* Add it to the list of members in this class.  */
          finish_member_declaration (decl);
        }
@@ -10378,7 +10427,7 @@ cp_parser_init_declarator (cp_parser* parser,
   bool is_non_constant_init;
   int ctor_dtor_or_conv_p;
   bool friend_p;
-  bool pop_p = false;
+  tree pushed_scope = NULL;
 
   /* Gather the attributes that were provided with the
      decl-specifiers.  */
@@ -10408,8 +10457,9 @@ cp_parser_init_declarator (cp_parser* parser,
   if (declarator == cp_error_declarator)
     return error_mark_node;
 
-  cp_parser_check_for_definition_in_return_type (declarator,
-                                                declares_class_or_enum);
+  if (declares_class_or_enum & 2)
+    cp_parser_check_for_definition_in_return_type (declarator,
+                                                  decl_specifiers->type);
 
   /* Figure out what scope the entity declared by the DECLARATOR is
      located in.  `grokdeclarator' sometimes changes the scope, so
@@ -10534,12 +10584,12 @@ cp_parser_init_declarator (cp_parser* parser,
        }
       decl = start_decl (declarator, decl_specifiers,
                         is_initialized, attributes, prefix_attributes,
-                        &pop_p);
+                        &pushed_scope);
     }
   else if (scope)
     /* Enter the SCOPE.  That way unqualified names appearing in the
        initializer will be looked up in SCOPE.  */
-    pop_p = push_scope (scope);
+    pushed_scope = push_scope (scope);
 
   /* Perform deferred access control checks, now that we know in which
      SCOPE the declared entity resides.  */
@@ -10589,10 +10639,10 @@ cp_parser_init_declarator (cp_parser* parser,
      declaration.  */
   if (member_p)
     {
-      if (pop_p)
+      if (pushed_scope)
        {
-         pop_scope (scope);
-         pop_p = false;
+         pop_scope (pushed_scope);
+         pushed_scope = false;
        }
       decl = grokfield (declarator, decl_specifiers,
                        initializer, /*asmspec=*/NULL_TREE,
@@ -10614,9 +10664,9 @@ cp_parser_init_declarator (cp_parser* parser,
                         `explicit' constructor cannot be used.  */
                      ((is_parenthesized_init || !is_initialized)
                     ? 0 : LOOKUP_ONLYCONVERTING));
-      if (pop_p)
-       pop_scope (DECL_CONTEXT (decl));
     }
+  if (!friend_p && pushed_scope)
+    pop_scope (pushed_scope);
 
   /* Remember whether or not variables were initialized by
      constant-expressions.  */
@@ -10787,7 +10837,7 @@ cp_parser_direct_declarator (cp_parser* parser,
   bool saved_default_arg_ok_p = parser->default_arg_ok_p;
   bool saved_in_declarator_p = parser->in_declarator_p;
   bool first = true;
-  bool pop_p = false;
+  tree pushed_scope = NULL_TREE;
 
   while (true)
     {
@@ -10982,33 +11032,36 @@ cp_parser_direct_declarator (cp_parser* parser,
        }
       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
        {
-         tree id;
+         tree qualifying_scope;
+         tree unqualified_name;
 
          /* Parse a declarator-id */
          if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
            cp_parser_parse_tentatively (parser);
-         id = cp_parser_declarator_id (parser);
+         unqualified_name = cp_parser_declarator_id (parser);
+         qualifying_scope = parser->scope;
          if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
            {
              if (!cp_parser_parse_definitely (parser))
-               id = error_mark_node;
-             else if (TREE_CODE (id) != IDENTIFIER_NODE)
+               unqualified_name = error_mark_node;
+             else if (qualifying_scope
+                      || (TREE_CODE (unqualified_name) 
+                          != IDENTIFIER_NODE))
                {
                  cp_parser_error (parser, "expected unqualified-id");
-                 id = error_mark_node;
+                 unqualified_name = error_mark_node;
                }
            }
 
-         if (id == error_mark_node)
+         if (unqualified_name == error_mark_node)
            {
              declarator = cp_error_declarator;
              break;
            }
 
-         if (TREE_CODE (id) == SCOPE_REF && at_namespace_scope_p ())
+         if (qualifying_scope && at_namespace_scope_p ()
+             && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
            {
-             tree scope = TREE_OPERAND (id, 0);
-
              /* In the declaration of a member of a template class
                 outside of the class itself, the SCOPE will sometimes
                 be a TYPENAME_TYPE.  For example, given:
@@ -11025,40 +11078,30 @@ cp_parser_direct_declarator (cp_parser* parser,
                 `S<T>::R' not a type.  However, if `S' is
                 specialized, then this `i' will not be used, so there
                 is no harm in resolving the types here.  */
-             if (TREE_CODE (scope) == TYPENAME_TYPE)
-               {
-                 tree type;
-
-                 /* Resolve the TYPENAME_TYPE.  */
-                 type = resolve_typename_type (scope,
-                                                /*only_current_p=*/false);
-                 /* If that failed, the declarator is invalid.  */
-                 if (type == error_mark_node)
-                   error ("%<%T::%D%> is not a type",
-                          TYPE_CONTEXT (scope),
-                          TYPE_IDENTIFIER (scope));
-                 /* Build a new DECLARATOR.  */
-                 id = build_nt (SCOPE_REF, type, TREE_OPERAND (id, 1));
-               }
+             tree type;
+             
+             /* Resolve the TYPENAME_TYPE.  */
+             type = resolve_typename_type (qualifying_scope,
+                                           /*only_current_p=*/false);
+             /* If that failed, the declarator is invalid.  */
+             if (type == error_mark_node)
+               error ("%<%T::%D%> is not a type",
+                      TYPE_CONTEXT (qualifying_scope),
+                      TYPE_IDENTIFIER (qualifying_scope));
+             qualifying_scope = type;
            }
 
-         declarator = make_id_declarator (id);
-         if (id)
+         declarator = make_id_declarator (qualifying_scope, 
+                                          unqualified_name);
+         if (unqualified_name)
            {
              tree class_type;
-             tree unqualified_name;
 
-             if (TREE_CODE (id) == SCOPE_REF
-                 && CLASS_TYPE_P (TREE_OPERAND (id, 0)))
-               {
-                 class_type = TREE_OPERAND (id, 0);
-                 unqualified_name = TREE_OPERAND (id, 1);
-               }
+             if (qualifying_scope
+                 && CLASS_TYPE_P (qualifying_scope))
+               class_type = qualifying_scope;
              else
-               {
-                 class_type = current_class_type;
-                 unqualified_name = id;
-               }
+               class_type = current_class_type;
 
              if (class_type)
                {
@@ -11066,16 +11109,21 @@ cp_parser_direct_declarator (cp_parser* parser,
                    declarator->u.id.sfk = sfk_destructor;
                  else if (IDENTIFIER_TYPENAME_P (unqualified_name))
                    declarator->u.id.sfk = sfk_conversion;
-                 else if (constructor_name_p (unqualified_name,
-                                              class_type)
-                          || (TREE_CODE (unqualified_name) == TYPE_DECL
-                              && same_type_p (TREE_TYPE (unqualified_name),
-                                              class_type)))
+                 else if (/* There's no way to declare a constructor
+                             for an anonymous type, even if the type
+                             got a name for linkage purposes.  */
+                          !TYPE_WAS_ANONYMOUS (class_type)
+                          && (constructor_name_p (unqualified_name,
+                                                  class_type)
+                              || (TREE_CODE (unqualified_name) == TYPE_DECL
+                                  && (same_type_p 
+                                      (TREE_TYPE (unqualified_name),
+                                       class_type)))))
                    declarator->u.id.sfk = sfk_constructor;
 
                  if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
                    *ctor_dtor_or_conv_p = -1;
-                 if (TREE_CODE (id) == SCOPE_REF
+                 if (qualifying_scope
                      && TREE_CODE (unqualified_name) == TYPE_DECL
                      && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
                    {
@@ -11094,7 +11142,7 @@ cp_parser_direct_declarator (cp_parser* parser,
          if (scope)
            /* Any names that appear after the declarator-id for a
               member are looked up in the containing scope.  */
-           pop_p = push_scope (scope);
+           pushed_scope = push_scope (scope);
          parser->in_declarator_p = true;
          if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
              || (declarator && declarator->kind == cdk_id))
@@ -11117,8 +11165,8 @@ cp_parser_direct_declarator (cp_parser* parser,
     cp_parser_error (parser, "expected declarator");
 
   /* If we entered a scope, we must exit it now.  */
-  if (pop_p)
-    pop_scope (scope);
+  if (pushed_scope)
+    pop_scope (pushed_scope);
 
   parser->default_arg_ok_p = saved_default_arg_ok_p;
   parser->in_declarator_p = saved_in_declarator_p;
@@ -11297,8 +11345,6 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 static tree
 cp_parser_declarator_id (cp_parser* parser)
 {
-  tree id_expression;
-
   /* The expression must be an id-expression.  Assume that qualified
      names are the names of types so that:
 
@@ -11313,20 +11359,11 @@ cp_parser_declarator_id (cp_parser* parser)
        int S<T>::R<T>::i = 3;
 
      will work, too.  */
-  id_expression = cp_parser_id_expression (parser,
-                                          /*template_keyword_p=*/false,
-                                          /*check_dependency_p=*/false,
-                                          /*template_p=*/NULL,
-                                          /*declarator_p=*/true);
-  /* If the name was qualified, create a SCOPE_REF to represent
-     that.  */
-  if (parser->scope)
-    {
-      id_expression = build_nt (SCOPE_REF, parser->scope, id_expression);
-      parser->scope = NULL_TREE;
-    }
-
-  return id_expression;
+  return cp_parser_id_expression (parser,
+                                 /*template_keyword_p=*/false,
+                                 /*check_dependency_p=*/false,
+                                 /*template_p=*/NULL,
+                                 /*declarator_p=*/true);
 }
 
 /* Parse a type-id.
@@ -11583,8 +11620,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
             list.  */
          if (!parser->in_template_argument_list_p
              && !parser->in_type_id_in_expr_p
-             && cp_parser_parsing_tentatively (parser)
-             && !cp_parser_committed_to_tentative_parse (parser)
+             && cp_parser_uncommitted_to_tentative_parse_p (parser)
              /* However, a parameter-declaration of the form
                 "foat(f)" (which is a valid declaration of a
                 parameter "f") can also be interpreted as an
@@ -11595,8 +11631,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
       else
        {
          cp_parser_error (parser, "expected %<,%> or %<...%>");
-         if (!cp_parser_parsing_tentatively (parser)
-             || cp_parser_committed_to_tentative_parse (parser))
+         if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
            cp_parser_skip_to_closing_parenthesis (parser,
                                                   /*recovering=*/true,
                                                   /*or_comma=*/false,
@@ -11699,8 +11734,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
             function-type (taking a "char" as a parameter) or a cast
             of some object of type "char" to "int".  */
          && !parser->in_type_id_in_expr_p
-         && cp_parser_parsing_tentatively (parser)
-         && !cp_parser_committed_to_tentative_parse (parser)
+         && cp_parser_uncommitted_to_tentative_parse_p (parser)
          && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
        cp_parser_commit_to_tentative_parse (parser);
       /* Parse the declarator.  */
@@ -12092,11 +12126,10 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
    to indicate that names looked up in dependent types should be
    assumed to be types.  TEMPLATE_KEYWORD_P is true iff the `template'
    keyword has been used to indicate that the name that appears next
-   is a template.  TYPE_P is true iff the next name should be treated
-   as class-name, even if it is declared to be some other kind of name
-   as well.  If CHECK_DEPENDENCY_P is FALSE, names are looked up in
-   dependent scopes.  If CLASS_HEAD_P is TRUE, this class is the class
-   being defined in a class-head.
+   is a template.  TAG_TYPE indicates the explicit tag given before
+   the type name, if any.  If CHECK_DEPENDENCY_P is FALSE, names are
+   looked up in dependent scopes.  If CLASS_HEAD_P is TRUE, this class
+   is the class being defined in a class-head.
 
    Returns the TYPE_DECL representing the class.  */
 
@@ -12104,7 +12137,7 @@ static tree
 cp_parser_class_name (cp_parser *parser,
                      bool typename_keyword_p,
                      bool template_keyword_p,
-                     bool type_p,
+                     enum tag_types tag_type,
                      bool check_dependency_p,
                      bool class_head_p,
                      bool is_declaration)
@@ -12160,10 +12193,10 @@ cp_parser_class_name (cp_parser *parser,
             resolution operator, object, function, and enumerator
             names are ignored.  */
          if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
-           type_p = true;
+           tag_type = typename_type;
          /* Look up the name.  */
          decl = cp_parser_lookup_name (parser, identifier,
-                                       type_p,
+                                       tag_type,
                                        /*is_template=*/false,
                                        /*is_namespace=*/false,
                                        check_dependency_p,
@@ -12185,7 +12218,7 @@ cp_parser_class_name (cp_parser *parser,
   /* If this is a typename, create a TYPENAME_TYPE.  */
   if (typename_p && decl != error_mark_node)
     {
-      decl = make_typename_type (scope, decl, /*complain=*/1);
+      decl = make_typename_type (scope, decl, typename_type, /*complain=*/1);
       if (decl != error_mark_node)
        decl = TYPE_NAME (decl);
     }
@@ -12204,9 +12237,10 @@ cp_parser_class_name (cp_parser *parser,
        standard does not seem to be definitive, but there is no other
        valid interpretation of the following `::'.  Therefore, those
        names are considered class-names.  */
-    decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));
+    decl = TYPE_NAME (make_typename_type (scope, decl, tag_type, tf_error));
   else if (decl == error_mark_node
           || TREE_CODE (decl) != TYPE_DECL
+          || TREE_TYPE (decl) == error_mark_node
           || !IS_AGGR_TYPE (TREE_TYPE (decl)))
     {
       cp_parser_error (parser, "expected class-name");
@@ -12232,7 +12266,7 @@ cp_parser_class_specifier (cp_parser* parser)
   int has_trailing_semicolon;
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
-  bool pop_p = false;
+  tree old_scope = NULL_TREE;
   tree scope = NULL_TREE;
 
   push_deferring_access_checks (dk_no_deferred);
@@ -12271,7 +12305,7 @@ cp_parser_class_specifier (cp_parser* parser)
   if (nested_name_specifier_p)
     {
       scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
-      pop_p = push_scope (scope);
+      old_scope = push_inner_scope (scope);
     }
   type = begin_class_definition (type);
 
@@ -12296,8 +12330,8 @@ cp_parser_class_specifier (cp_parser* parser)
     }
   if (type != error_mark_node)
     type = finish_struct (type, attributes);
-  if (pop_p)
-    pop_scope (scope);
+  if (nested_name_specifier_p)
+    pop_inner_scope (old_scope, scope);
   /* If this class is not itself within the scope of another class,
      then we need to parse the bodies of all of the queued function
      definitions.  Note that the queued functions defined in a class
@@ -12322,8 +12356,8 @@ cp_parser_class_specifier (cp_parser* parser)
     {
       tree queue_entry;
       tree fn;
-      tree class_type;
-      bool pop_p;
+      tree class_type = NULL_TREE;
+      tree pushed_scope = NULL_TREE;
 
       /* In a first pass, parse default arguments to the functions.
         Then, in a second pass, parse the bodies of the functions.
@@ -12335,8 +12369,6 @@ cp_parser_class_specifier (cp_parser* parser)
             };
 
          */
-      class_type = NULL_TREE;
-      pop_p = false;
       for (TREE_PURPOSE (parser->unparsed_functions_queues)
             = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues));
           (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues));
@@ -12348,10 +12380,10 @@ cp_parser_class_specifier (cp_parser* parser)
             take care of them now.  */
          if (class_type != TREE_PURPOSE (queue_entry))
            {
-             if (pop_p)
-               pop_scope (class_type);
+             if (pushed_scope)
+               pop_scope (pushed_scope);
              class_type = TREE_PURPOSE (queue_entry);
-             pop_p = push_scope (class_type);
+             pushed_scope = push_scope (class_type);
            }
          /* Make sure that any template parameters are in scope.  */
          maybe_begin_member_template_processing (fn);
@@ -12360,8 +12392,8 @@ cp_parser_class_specifier (cp_parser* parser)
          /* Remove any template parameters from the symbol table.  */
          maybe_end_member_template_processing ();
        }
-      if (pop_p)
-       pop_scope (class_type);
+      if (pushed_scope)
+       pop_scope (pushed_scope);
       /* Now parse the body of the functions.  */
       for (TREE_VALUE (parser->unparsed_functions_queues)
             = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
@@ -12409,6 +12441,8 @@ cp_parser_class_specifier (cp_parser* parser)
    *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
    involving a nested-name-specifier was used, and FALSE otherwise.
 
+   Returns error_mark_node if this is not a class-head.
+   
    Returns NULL_TREE if the class-head is syntactically valid, but
    semantically invalid in a way that means we should skip the entire
    body of the class.  */
@@ -12427,7 +12461,7 @@ cp_parser_class_head (cp_parser* parser,
   bool qualified_p = false;
   bool invalid_nested_name_p = false;
   bool invalid_explicit_specialization_p = false;
-  bool pop_p = false;
+  tree pushed_scope = NULL_TREE;
   unsigned num_templates;
   tree bases;
 
@@ -12492,7 +12526,7 @@ cp_parser_class_head (cp_parser* parser,
       type = cp_parser_class_name (parser,
                                   /*typename_keyword_p=*/false,
                                   /*template_keyword_p=*/false,
-                                  /*type_p=*/true,
+                                  class_type,
                                   /*check_dependency_p=*/false,
                                   /*class_head_p=*/true,
                                   /*is_declaration=*/false);
@@ -12581,6 +12615,15 @@ cp_parser_class_head (cp_parser* parser,
   else if (nested_name_specifier)
     {
       tree scope;
+
+      /* Reject typedef-names in class heads.  */
+      if (!DECL_IMPLICIT_TYPEDEF_P (type))
+       {
+         error ("invalid class name in declaration of %qD", type);
+         type = NULL_TREE;
+         goto done;
+       }
+
       /* Figure out in what scope the declaration is being placed.  */
       scope = current_scope ();
       /* If that scope does not contain the scope in which the
@@ -12636,19 +12679,12 @@ cp_parser_class_head (cp_parser* parser,
     {
       type = TREE_TYPE (id);
       maybe_process_partial_specialization (type);
+      if (nested_name_specifier)
+       pushed_scope = push_scope (nested_name_specifier);
     }
-  else if (!nested_name_specifier)
-    {
-      /* If the class was unnamed, create a dummy name.  */
-      if (!id)
-       id = make_anon_name ();
-      type = xref_tag (class_key, id, /*globalize=*/false,
-                      parser->num_template_parameter_lists);
-    }
-  else
+  else if (nested_name_specifier)
     {
       tree class_type;
-      bool pop_p = false;
 
       /* Given:
 
@@ -12674,37 +12710,46 @@ cp_parser_class_head (cp_parser* parser,
       maybe_process_partial_specialization (TREE_TYPE (type));
       class_type = current_class_type;
       /* Enter the scope indicated by the nested-name-specifier.  */
-      if (nested_name_specifier)
-       pop_p = push_scope (nested_name_specifier);
+      pushed_scope = push_scope (nested_name_specifier);
       /* Get the canonical version of this type.  */
       type = TYPE_MAIN_DECL (TREE_TYPE (type));
       if (PROCESSING_REAL_TEMPLATE_DECL_P ()
          && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
-       type = push_template_decl (type);
-      type = TREE_TYPE (type);
-      if (nested_name_specifier)
        {
-         *nested_name_specifier_p = true;
-         if (pop_p)
-           pop_scope (nested_name_specifier);
+         type = push_template_decl (type);
+         if (type == error_mark_node)
+           {
+             type = NULL_TREE;
+             goto done;
+           }
        }
+      
+      type = TREE_TYPE (type);
+      *nested_name_specifier_p = true;
+    }
+  else      /* The name is not a nested name.  */
+    {
+      /* If the class was unnamed, create a dummy name.  */
+      if (!id)
+       id = make_anon_name ();
+      type = xref_tag (class_key, id, /*tag_scope=*/ts_current,
+                      parser->num_template_parameter_lists);
     }
+
   /* Indicate whether this class was declared as a `class' or as a
      `struct'.  */
   if (TREE_CODE (type) == RECORD_TYPE)
     CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
   cp_parser_check_class_key (class_key, type);
 
-  /* Enter the scope containing the class; the names of base classes
-     should be looked up in that context.  For example, given:
+  /* We will have entered the scope containing the class; the names of
+     base classes should be looked up in that context.  For example,
+     given:
 
        struct A { struct B {}; struct C; };
        struct A::C : B {};
 
      is valid.  */
-  if (nested_name_specifier)
-    pop_p = push_scope (nested_name_specifier);
-
   bases = NULL_TREE;
 
   /* Get the list of base-classes, if there is one.  */
@@ -12714,12 +12759,12 @@ cp_parser_class_head (cp_parser* parser,
   /* Process the base classes.  */
   xref_basetypes (type, bases);
 
+ done:
   /* Leave the scope given by the nested-name-specifier.  We will
      enter the class scope itself while processing the members.  */
-  if (pop_p)
-    pop_scope (nested_name_specifier);
+  if (pushed_scope)
+    pop_scope (pushed_scope);
 
- done:
   if (invalid_explicit_specialization_p)
     {
       end_specialization ();
@@ -13012,7 +13057,8 @@ cp_parser_member_declaration (cp_parser* parser)
 
              /* Create the bitfield declaration.  */
              decl = grokbitfield (identifier
-                                  ? make_id_declarator (identifier)
+                                  ? make_id_declarator (NULL_TREE,
+                                                        identifier)
                                   : NULL,
                                   &decl_specifiers,
                                   width);
@@ -13050,8 +13096,9 @@ cp_parser_member_declaration (cp_parser* parser)
                  return;
                }
 
-             cp_parser_check_for_definition_in_return_type
-               (declarator, declares_class_or_enum);
+             if (declares_class_or_enum & 2)
+               cp_parser_check_for_definition_in_return_type
+                 (declarator, decl_specifiers.type);
 
              /* Look for an asm-specification.  */
              asm_specification = cp_parser_asm_specification_opt (parser);
@@ -13096,7 +13143,7 @@ cp_parser_member_declaration (cp_parser* parser)
                initializer = NULL_TREE;
 
              /* See if we are probably looking at a function
-                definition.  We are certainly not looking at at a
+                definition.  We are certainly not looking at a
                 member-declarator.  Calling `grokfield' has
                 side-effects, so we must not do it unless we are sure
                 that we are looking at a member-declarator.  */
@@ -13406,7 +13453,7 @@ cp_parser_base_specifier (cp_parser* parser)
   cp_parser_nested_name_specifier_opt (parser,
                                       /*typename_keyword_p=*/true,
                                       /*check_dependency_p=*/true,
-                                      /*type_p=*/true,
+                                      typename_type,
                                       /*is_declaration=*/true);
   /* If the base class is given by a qualified name, assume that names
      we see are type names or templates, as appropriate.  */
@@ -13417,7 +13464,7 @@ cp_parser_base_specifier (cp_parser* parser)
   type = cp_parser_class_name (parser,
                               class_scope_p,
                               template_p,
-                              /*type_p=*/true,
+                              typename_type,
                               /*check_dependency_p=*/true,
                               /*class_head_p=*/false,
                               /*is_declaration=*/true);
@@ -14041,8 +14088,9 @@ cp_parser_label_declaration (cp_parser* parser)
    If there was no entity with the indicated NAME, the ERROR_MARK_NODE
    is returned.
 
-   If IS_TYPE is TRUE, bindings that do not refer to types are
-   ignored.
+   If TAG_TYPE is not NONE_TYPE, it indicates an explicit type keyword
+   (e.g., "struct") that was used.  In that case bindings that do not
+   refer to types are ignored.
 
    If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
    ignored.
@@ -14058,7 +14106,8 @@ cp_parser_label_declaration (cp_parser* parser)
 
 static tree
 cp_parser_lookup_name (cp_parser *parser, tree name,
-                      bool is_type, bool is_template, bool is_namespace,
+                      enum tag_types tag_type,
+                      bool is_template, bool is_namespace,
                       bool check_dependency,
                       bool *ambiguous_p)
 {
@@ -14136,13 +14185,17 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
       if ((check_dependency || !CLASS_TYPE_P (parser->scope))
           && dependent_p)
        {
-         if (is_type)
-           /* The resolution to Core Issue 180 says that `struct A::B'
-              should be considered a type-name, even if `A' is
-              dependent.  */
-           decl = TYPE_NAME (make_typename_type (parser->scope,
-                                                 name,
-                                                 /*complain=*/1));
+         if (tag_type)
+           {
+             tree type;
+
+             /* The resolution to Core Issue 180 says that `struct
+                A::B' should be considered a type-name, even if `A'
+                is dependent.  */
+             type = make_typename_type (parser->scope, name, tag_type,
+                                        /*complain=*/1);
+             decl = TYPE_NAME (type);
+           }
          else if (is_template)
            decl = make_unbound_class_template (parser->scope,
                                                name, NULL_TREE,
@@ -14152,7 +14205,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
        }
       else
        {
-         bool pop_p = false;
+         tree pushed_scope = NULL_TREE;
 
          /* If PARSER->SCOPE is a dependent type, then it must be a
             class type, and we must not be checking dependencies;
@@ -14160,15 +14213,16 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
             that PARSER->SCOPE is not considered a dependent base by
             lookup_member, we must enter the scope here.  */
          if (dependent_p)
-           pop_p = push_scope (parser->scope);
+           pushed_scope = push_scope (parser->scope);
          /* If the PARSER->SCOPE is a a template specialization, it
             may be instantiated during name lookup.  In that case,
             errors may be issued.  Even if we rollback the current
             tentative parse, those errors are valid.  */
-         decl = lookup_qualified_name (parser->scope, name, is_type,
+         decl = lookup_qualified_name (parser->scope, name, 
+                                       tag_type != none_type, 
                                        /*complain=*/true);
-         if (pop_p)
-           pop_scope (parser->scope);
+         if (pushed_scope)
+           pop_scope (pushed_scope);
        }
       parser->qualifying_scope = parser->scope;
       parser->object_scope = NULL_TREE;
@@ -14185,9 +14239,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
           parse, those errors are valid.  */
        object_decl = lookup_member (object_type,
                                     name,
-                                    /*protect=*/0, is_type);
+                                    /*protect=*/0, 
+                                    tag_type != none_type);
       /* Look it up in the enclosing context, too.  */
-      decl = lookup_name_real (name, is_type, /*nonclass=*/0,
+      decl = lookup_name_real (name, tag_type != none_type, 
+                              /*nonclass=*/0,
                               /*block_p=*/true, is_namespace,
                               /*flags=*/0);
       parser->object_scope = object_type;
@@ -14197,7 +14253,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
     }
   else
     {
-      decl = lookup_name_real (name, is_type, /*nonclass=*/0,
+      decl = lookup_name_real (name, tag_type != none_type, 
+                              /*nonclass=*/0,
                               /*block_p=*/true, is_namespace,
                               /*flags=*/0);
       parser->qualifying_scope = NULL_TREE;
@@ -14253,7 +14310,7 @@ static tree
 cp_parser_lookup_name_simple (cp_parser* parser, tree name)
 {
   return cp_parser_lookup_name (parser, name,
-                               /*is_type=*/false,
+                               none_type,
                                /*is_template=*/false,
                                /*is_namespace=*/false,
                                /*check_dependency=*/true,
@@ -14320,13 +14377,13 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
   switch (declarator->kind)
     {
     case cdk_id:
-      if (TREE_CODE (declarator->u.id.name) == SCOPE_REF)
+      if (declarator->u.id.qualifying_scope)
        {
          tree scope;
          tree member;
 
-         scope = TREE_OPERAND (declarator->u.id.name, 0);
-         member = TREE_OPERAND (declarator->u.id.name, 1);
+         scope = declarator->u.id.qualifying_scope;
+         member = declarator->u.id.unqualified_name;
 
          while (scope && CLASS_TYPE_P (scope))
            {
@@ -14349,10 +14406,10 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
              scope = TYPE_CONTEXT (scope);
            }
        }
-
-      /* If the DECLARATOR has the form `X<y>' then it uses one
-        additional level of template parameters.  */
-      if (TREE_CODE (declarator->u.id.name) == TEMPLATE_ID_EXPR)
+      else if (TREE_CODE (declarator->u.id.unqualified_name) 
+              == TEMPLATE_ID_EXPR)
+       /* If the DECLARATOR has the form `X<y>' then it uses one
+          additional level of template parameters.  */
        ++num_templates;
 
       return cp_parser_check_template_parameters (parser,
@@ -14511,7 +14568,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
       type_decl = cp_parser_class_name (parser,
                                        /*typename_keyword_p=*/false,
                                        /*template_keyword_p=*/false,
-                                       /*type_p=*/false,
+                                       none_type,
                                        /*check_dependency_p=*/false,
                                        /*class_head_p=*/false,
                                        /*is_declaration=*/false);
@@ -14541,7 +14598,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
          && !cp_parser_storage_class_specifier_opt (parser))
        {
          tree type;
-         bool pop_p = false;
+         tree pushed_scope = NULL_TREE;
          unsigned saved_num_template_parameter_lists;
 
          /* Names appearing in the type-specifier should be looked up
@@ -14561,7 +14618,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
                      return false;
                    }
                }
-             pop_p = push_scope (type);
+             pushed_scope = push_scope (type);
            }
 
          /* Inside the constructor parameter list, surrounding
@@ -14582,8 +14639,8 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
            = saved_num_template_parameter_lists;
 
          /* Leave the scope of the class.  */
-         if (pop_p)
-           pop_scope (type);
+         if (pushed_scope)
+           pop_scope (pushed_scope);
 
          constructor_p = !cp_parser_error_occurred (parser);
        }
@@ -15776,14 +15833,14 @@ cp_parser_parse_definitely (cp_parser* parser)
   return !error_occurred;
 }
 
-/* Returns true if we are parsing tentatively -- but have decided that
-   we will stick with this tentative parse, even if errors occur.  */
+/* Returns true if we are parsing tentatively and are not committed to
+   this tentative parse.  */
 
 static bool
-cp_parser_committed_to_tentative_parse (cp_parser* parser)
+cp_parser_uncommitted_to_tentative_parse_p (cp_parser* parser)
 {
   return (cp_parser_parsing_tentatively (parser)
-         && parser->context->status == CP_PARSER_STATUS_KIND_COMMITTED);
+         && parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED);
 }
 
 /* Returns nonzero iff an error has occurred during the most recent