OSDN Git Service

cp:
[pf3gnuchains/gcc-fork.git] / gcc / cp / parser.c
index 192855d..dc650d4 100644 (file)
@@ -53,7 +53,7 @@ typedef struct cp_token GTY (())
   ENUM_BITFIELD (rid) keyword : 8;
   /* Token flags.  */
   unsigned char flags;
-  /* True if this token is from a system header. */
+  /* True if this token is from a system header.  */
   BOOL_BITFIELD in_system_header : 1;
   /* True if this token is from a context where it is implicitly extern "C" */
   BOOL_BITFIELD implicit_extern_c : 1;
@@ -63,31 +63,47 @@ typedef struct cp_token GTY (())
   location_t location;
 } cp_token;
 
+/* We use a stack of token pointer for saving token sets.  */
+typedef struct cp_token *cp_token_position;
+DEF_VEC_MALLOC_P (cp_token_position);
+
+static const cp_token eof_token =
+{
+  CPP_EOF, RID_MAX, 0, 0, 0, NULL_TREE,
+#if USE_MAPPED_LOCATION
+  0
+#else
+  {0, 0}
+#endif
+};
+
 /* The cp_lexer structure represents the C++ lexer.  It is responsible
    for managing the token stream from the preprocessor and supplying
    it to the parser.  Tokens are never added to the cp_lexer after
-   it is created. */
+   it is created.  */
 
 typedef struct cp_lexer GTY (())
 {
-  /* The memory allocated for the buffer.  Never NULL.  */
-  cp_token * GTY ((length ("(%h.buffer_end - %h.buffer)"))) buffer;
-  /* A pointer just past the end of the memory allocated for the buffer.  */
-  cp_token * GTY ((skip)) buffer_end;
+  /* The memory allocated for the buffer.  NULL if this lexer does not
+     own the token buffer.  */
+  cp_token * GTY ((length ("%h.buffer_length"))) buffer;
+  /* If the lexer owns the buffer, this is the number of tokens in the
+     buffer.  */
+  size_t buffer_length;
+  
   /* A pointer just past the last available token.  The tokens
-     in this lexer are [buffer, last_token). */
-  cp_token * GTY ((skip)) last_token;
+     in this lexer are [buffer, last_token).  */
+  cp_token_position GTY ((skip)) last_token;
 
-  /* The next available token.  If NEXT_TOKEN is NULL, then there are
+  /* The next available token.  If NEXT_TOKEN is &eof_token, then there are
      no more available tokens.  */
-  cp_token * GTY ((skip)) next_token;
+  cp_token_position GTY ((skip)) next_token;
 
   /* A stack indicating positions at which cp_lexer_save_tokens was
      called.  The top entry is the most recent position at which we
-     began saving tokens.  The entries are differences in token
-     position between BUFFER and the first saved token.
-     If the stack is non-empty, we are saving tokens.  */
-  varray_type saved_tokens;
+     began saving tokens.  If the stack is non-empty, we are saving
+     tokens.  */
+  VEC (cp_token_position) *GTY ((skip)) saved_tokens;
 
   /* True if we should output debugging information.  */
   bool debugging_p;
@@ -100,14 +116,14 @@ typedef struct cp_lexer GTY (())
    allocate heap memory for it, since tokens are never removed from the
    lexer's array.  There is also no need for the GC to walk through
    a cp_token_cache, since everything in here is referenced through
-   a lexer. */
+   a lexer.  */
 
 typedef struct cp_token_cache GTY(())
 {
-  /* The beginning of the token range. */
+  /* The beginning of the token range.  */
   cp_token * GTY((skip)) first;
 
-  /* Points immediately after the last token in the range. */
+  /* Points immediately after the last token in the range.  */
   cp_token * GTY ((skip)) last;
 } cp_token_cache;
 
@@ -121,14 +137,10 @@ static void cp_lexer_destroy
   (cp_lexer *);
 static int cp_lexer_saving_tokens
   (const cp_lexer *);
-static cp_token *cp_lexer_next_token
-  (cp_lexer *, cp_token *);
-static cp_token *cp_lexer_prev_token
-  (cp_lexer *, cp_token *);
-static ptrdiff_t cp_lexer_token_difference
-  (cp_lexer *, cp_token *, cp_token *);
-static void cp_lexer_grow_buffer
-  (cp_lexer *);
+static cp_token_position cp_lexer_token_position
+  (cp_lexer *, bool);
+static cp_token *cp_lexer_token_at
+  (cp_lexer *, cp_token_position);
 static void cp_lexer_get_preprocessor_token
   (cp_lexer *, cp_token *);
 static inline cp_token *cp_lexer_peek_token
@@ -146,7 +158,7 @@ static cp_token *cp_lexer_consume_token
 static void cp_lexer_purge_token
   (cp_lexer *);
 static void cp_lexer_purge_tokens_after
-  (cp_lexer *, cp_token *);
+  (cp_lexer *, cp_token_position);
 static void cp_lexer_handle_pragma
   (cp_lexer *);
 static void cp_lexer_save_tokens
@@ -164,8 +176,6 @@ static void cp_lexer_start_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
 static void cp_lexer_stop_debugging
   (cp_lexer *) ATTRIBUTE_UNUSED;
-static void cp_lexer_peek_token_emit_debug_info
-  (cp_lexer *, cp_token *);
 #else
 /* If we define cp_lexer_debug_stream to NULL it will provoke warnings
    about passing NULL to functions that require non-NULL arguments
@@ -174,16 +184,14 @@ static void cp_lexer_peek_token_emit_debug_info
 #define cp_lexer_debug_stream stdout
 #define cp_lexer_print_token(str, tok) (void) 0
 #define cp_lexer_debugging_p(lexer) 0
-#define cp_lexer_peek_token_emit_debug_info(lexer, tok) (void) 0
 #endif /* ENABLE_CHECKING */
 
 static cp_token_cache *cp_token_cache_new
   (cp_token *, cp_token *);
 
 /* Manifest constants.  */
-
 #define CP_LEXER_BUFFER_SIZE 10000
-#define CP_SAVED_TOKENS_SIZE 5
+#define CP_SAVED_TOKEN_STACK 5
 
 /* A token type for keywords, as opposed to ordinary identifiers.  */
 #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
@@ -203,7 +211,7 @@ static cp_token_cache *cp_token_cache_new
 
 /* A token type for tokens that are not tokens at all; these are used
    to represent slots in the array where there used to be a token
-   that has now been deleted. */
+   that has now been deleted.  */
 #define CPP_PURGED ((enum cpp_ttype) (CPP_NESTED_NAME_SPECIFIER + 1))
 
 /* The number of token types, including C++-specific ones.  */
@@ -222,10 +230,14 @@ static FILE *cp_lexer_debug_stream;
 static cp_lexer *
 cp_lexer_new_main (void)
 {
-  cp_lexer *lexer;
   cp_token first_token;
+  cp_lexer *lexer;
+  cp_token *pos;
+  size_t alloc;
+  size_t space;
+  cp_token *buffer;
 
-  /* Tell cpplib we want CPP_PRAGMA tokens. */
+  /* Tell cpplib we want CPP_PRAGMA tokens.  */
   cpp_get_options (parse_in)->defer_pragmas = true;
 
   /* Tell c_lex not to merge string constants.  */
@@ -240,30 +252,38 @@ cp_lexer_new_main (void)
   /* Allocate the memory.  */
   lexer = GGC_CNEW (cp_lexer);
 
-  /* Create the buffer.  */
-  lexer->buffer = ggc_calloc (CP_LEXER_BUFFER_SIZE, sizeof (cp_token));
-  lexer->buffer_end = lexer->buffer + CP_LEXER_BUFFER_SIZE;
-  /* There is one token in the buffer.  */
-  lexer->last_token = lexer->buffer + 1;
-  lexer->next_token = lexer->buffer;
-  *lexer->next_token = first_token;
-
-  /* Create the SAVED_TOKENS stack.  */
-  VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
-
 #ifdef ENABLE_CHECKING  
   /* Initially we are not debugging.  */
   lexer->debugging_p = false;
 #endif /* ENABLE_CHECKING */
+  lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
+        
+  /* Create the buffer.  */
+  alloc = CP_LEXER_BUFFER_SIZE;
+  buffer = ggc_alloc (alloc * sizeof (cp_token));
 
-  /* Get the rest of the tokens from the preprocessor. */
-  while (lexer->last_token[-1].type != CPP_EOF)
+  /* Put the first token in the buffer.  */
+  space = alloc;
+  pos = buffer;
+  *pos = first_token;
+  
+  /* Get the remaining tokens from the preprocessor.  */
+  while (pos->type != CPP_EOF)
     {
-      if (lexer->last_token == lexer->buffer_end)
-       cp_lexer_grow_buffer (lexer);
-      cp_lexer_get_preprocessor_token (lexer, lexer->last_token++);
+      pos++;
+      if (!--space)
+       {
+         space = alloc;
+         alloc *= 2;
+         buffer = ggc_realloc (buffer, alloc * sizeof (cp_token));
+         pos = buffer + space;
+       }
+      cp_lexer_get_preprocessor_token (lexer, pos);
     }
+  lexer->buffer = buffer;
+  lexer->buffer_length = alloc - space;
+  lexer->last_token = pos;
+  lexer->next_token = lexer->buffer_length ? buffer : (cp_token *)&eof_token;
 
   /* Pragma processing (via cpp_handle_deferred_pragma) may result in
      direct calls to c_lex.  Those callers all expect c_lex to do
@@ -283,26 +303,14 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
   cp_token *first = cache->first;
   cp_token *last = cache->last;
   cp_lexer *lexer = GGC_CNEW (cp_lexer);
-  cp_token *eof;
-
-  /* Allocate a new buffer.  The reason we do this is to make sure
-     there's a CPP_EOF token at the end.  An alternative would be to
-     modify cp_lexer_peek_token so that it checks for end-of-buffer
-     and returns a CPP_EOF when appropriate. */
 
-  lexer->buffer = GGC_NEWVEC (cp_token, (last - first) + 1);
-  memcpy (lexer->buffer, first, sizeof (cp_token) * (last - first));
-  lexer->next_token = lexer->buffer;
-  lexer->buffer_end = lexer->last_token = lexer->buffer + (last - first);
-
-  eof = lexer->buffer + (last - first);
-  eof->type = CPP_EOF;
-  eof->location = UNKNOWN_LOCATION;
-  eof->value = NULL_TREE;
-  eof->keyword = RID_MAX;
-
-  /* Create the SAVED_TOKENS stack.  */
-  VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
+  /* We do not own the buffer.  */
+  lexer->buffer = NULL;
+  lexer->buffer_length = 0;
+  lexer->next_token = first == last ? (cp_token *)&eof_token : first;
+  lexer->last_token = last;
+  
+  lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
 
 #ifdef ENABLE_CHECKING
   /* Initially we are not debugging.  */
@@ -313,12 +321,14 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
   return lexer;
 }
 
-/* Frees all resources associated with LEXER. */
+/* Frees all resources associated with LEXER.  */
 
 static void
 cp_lexer_destroy (cp_lexer *lexer)
 {
-  ggc_free (lexer->buffer);
+  if (lexer->buffer)
+    ggc_free (lexer->buffer);
+  VEC_free (cp_token_position, lexer->saved_tokens);
   ggc_free (lexer);
 }
 
@@ -334,123 +344,45 @@ cp_lexer_debugging_p (cp_lexer *lexer)
 
 #endif /* ENABLE_CHECKING */
 
-/* TOKEN points into the circular token buffer.  Return a pointer to
-   the next token in the buffer.  */
-
-static inline cp_token *
-cp_lexer_next_token (cp_lexer* lexer ATTRIBUTE_UNUSED, cp_token* token)
+static inline cp_token_position
+cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
 {
-  token++;
-  return token;
+  gcc_assert (!previous_p || lexer->next_token != &eof_token);
+  
+  return lexer->next_token - previous_p;
 }
 
-/* TOKEN points into the circular token buffer.  Return a pointer to
-   the previous token in the buffer.  */
-
 static inline cp_token *
-cp_lexer_prev_token (cp_lexer* lexer ATTRIBUTE_UNUSED, cp_token* token)
+cp_lexer_token_at (cp_lexer *lexer ATTRIBUTE_UNUSED, cp_token_position pos)
 {
-  return token - 1;
+  return pos;
 }
 
 /* nonzero if we are presently saving tokens.  */
 
-static int
+static inline int
 cp_lexer_saving_tokens (const cp_lexer* lexer)
 {
-  return VARRAY_ACTIVE_SIZE (lexer->saved_tokens) != 0;
-}
-
-/* Return a pointer to the token that is N tokens beyond TOKEN in the
-   buffer.  */
-
-static inline cp_token *
-cp_lexer_advance_token (cp_lexer *lexer ATTRIBUTE_UNUSED,
-                       cp_token *token, ptrdiff_t n)
-{
-  return token + n;
-}
-
-/* Returns the number of times that START would have to be incremented
-   to reach FINISH.  If START and FINISH are the same, returns zero.  */
-
-static inline ptrdiff_t
-cp_lexer_token_difference (cp_lexer* lexer ATTRIBUTE_UNUSED,
-                          cp_token* start, cp_token* finish)
-{
-  return finish - start;
-}
-
-/* If the buffer is full, make it bigger.  */
-static void
-cp_lexer_grow_buffer (cp_lexer* lexer)
-{
-  cp_token *old_buffer;
-  cp_token *new_buffer;
-  ptrdiff_t buffer_length;
-
-  /* This function should only be called when buffer is full. */
-  gcc_assert (lexer->last_token == lexer->buffer_end);
-
-  /* Remember the current buffer pointer.  It will become invalid,
-     but we will need to do pointer arithmetic involving this
-     value.  */
-  old_buffer = lexer->buffer;
-  /* Compute the current buffer size.  */
-  buffer_length = lexer->buffer_end - lexer->buffer;
-  /* Allocate a buffer twice as big.  */
-  new_buffer = ggc_realloc (lexer->buffer,
-                           2 * buffer_length * sizeof (cp_token));
-
-  /* Recompute buffer positions. */
-  lexer->buffer = new_buffer;
-  lexer->buffer_end = new_buffer + 2 * buffer_length;
-  lexer->last_token = new_buffer + (lexer->last_token - old_buffer);
-  lexer->next_token = new_buffer + (lexer->next_token - old_buffer);
-
-  /* Clear the rest of the buffer.  We never look at this storage,
-     but the garbage collector may.  */
-  memset (lexer->last_token, 0,
-         (lexer->buffer_end - lexer->last_token) * sizeof(cp_token));
+  return VEC_length (cp_token_position, lexer->saved_tokens) != 0;
 }
 
-/* Store the next token from the preprocessor in *TOKEN.  */
+/* Store the next token from the preprocessor in *TOKEN.  Return true
+   if we reach EOF.  */
 
 static void
 cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
                                  cp_token *token)
 {
   static int is_extern_c = 0;
-  bool done;
-
-  done = false;
-  /* Keep going until we get a token we like.  */
-  while (!done)
-    {
-      /* Get a new token from the preprocessor.  */
-      token->type = c_lex_with_flags (&token->value, &token->flags);
-      /* Issue messages about tokens we cannot process.  */
-      switch (token->type)
-       {
-       case CPP_ATSIGN:
-       case CPP_HASH:
-       case CPP_PASTE:
-         error ("invalid token");
-         break;
 
-       default:
-         /* This is a good token, so we exit the loop.  */
-         done = true;
-         break;
-       }
-    }
-  /* Now we've got our token.  */
+   /* Get a new token from the preprocessor.  */
+  token->type = c_lex_with_flags (&token->value, &token->flags);
   token->location = input_location;
   token->in_system_header = in_system_header;
 
   /* On some systems, some header files are surrounded by an 
      implicit extern "C" block.  Set a flag in the token if it
-     comes from such a header. */
+     comes from such a header.  */
   is_extern_c += pending_lang_change;
   pending_lang_change = 0;
   token->implicit_extern_c = is_extern_c > 0;
@@ -473,7 +405,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
     token->keyword = RID_MAX;
 }
 
-/* Update the globals input_location and in_system_header from TOKEN.   */
+/* Update the globals input_location and in_system_header from TOKEN.  */
 static inline void
 cp_lexer_set_source_position_from_token (cp_token *token)
 {
@@ -491,25 +423,14 @@ static inline cp_token *
 cp_lexer_peek_token (cp_lexer *lexer)
 {
   if (cp_lexer_debugging_p (lexer))
-    cp_lexer_peek_token_emit_debug_info (lexer, lexer->next_token);
+    {
+      fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
+      cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
+      putc ('\n', cp_lexer_debug_stream);
+    }
   return lexer->next_token;
 }
 
-#ifdef ENABLE_CHECKING
-/* Emit debug output for cp_lexer_peek_token.  Split out into a
-   separate function so that cp_lexer_peek_token can be small and
-   inlinable. */
-
-static void
-cp_lexer_peek_token_emit_debug_info (cp_lexer *lexer ATTRIBUTE_UNUSED,
-                                    cp_token *token ATTRIBUTE_UNUSED)
-{
-  fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
-  cp_lexer_print_token (cp_lexer_debug_stream, token);
-  putc ('\n', cp_lexer_debug_stream);
-}
-#endif
-
 /* Return true if the next token has the indicated TYPE.  */
 
 static inline bool
@@ -551,7 +472,7 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
   cp_token *token;
 
   /* N is 1-based, not zero-based.  */
-  gcc_assert (n > 0);
+  gcc_assert (n > 0 && lexer->next_token != &eof_token);
 
   if (cp_lexer_debugging_p (lexer))
     fprintf (cp_lexer_debug_stream,
@@ -562,6 +483,12 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
   while (n != 0)
     {
       ++token;
+      if (token == lexer->last_token)
+       {
+         token = (cp_token *)&eof_token;
+         break;
+       }
+      
       if (token->type != CPP_PURGED)
        --n;
     }
@@ -583,12 +510,22 @@ cp_lexer_consume_token (cp_lexer* lexer)
 {
   cp_token *token = lexer->next_token;
 
+  gcc_assert (token != &eof_token);
+  
   do
-    ++lexer->next_token;
+    {
+      lexer->next_token++;
+      if (lexer->next_token == lexer->last_token)
+       {
+         lexer->next_token = (cp_token *)&eof_token;
+         break;
+       }
+      
+    }
   while (lexer->next_token->type == CPP_PURGED);
-
+  
   cp_lexer_set_source_position_from_token (token);
-
+  
   /* Provide debugging output.  */
   if (cp_lexer_debugging_p (lexer))
     {
@@ -596,7 +533,7 @@ cp_lexer_consume_token (cp_lexer* lexer)
       cp_lexer_print_token (cp_lexer_debug_stream, token);
       putc ('\n', cp_lexer_debug_stream);
     }
-
+  
   return token;
 }
 
@@ -608,14 +545,24 @@ static void
 cp_lexer_purge_token (cp_lexer *lexer)
 {
   cp_token *tok = lexer->next_token;
+  
+  gcc_assert (tok != &eof_token);
   tok->type = CPP_PURGED;
   tok->location = UNKNOWN_LOCATION;
   tok->value = NULL_TREE;
   tok->keyword = RID_MAX;
 
   do
-    ++lexer->next_token;
-  while (lexer->next_token->type == CPP_PURGED);
+    {
+      tok++;
+      if (tok == lexer->last_token)
+       {
+         tok = (cp_token *)&eof_token;
+         break;
+       }
+    }
+  while (tok->type == CPP_PURGED);
+  lexer->next_token = tok;
 }
 
 /* Permanently remove all tokens after TOK, up to, but not
@@ -625,9 +572,11 @@ cp_lexer_purge_token (cp_lexer *lexer)
 static void
 cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
 {
-  cp_token *peek;
+  cp_token *peek = lexer->next_token;
 
-  peek = cp_lexer_peek_token (lexer);
+  if (peek == &eof_token)
+    peek = lexer->last_token;
+  
   gcc_assert (tok < peek);
 
   for ( tok += 1; tok != peek; tok += 1)
@@ -639,7 +588,7 @@ cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
     }
 }
 
-/* Consume and handle a pragma token.   */
+/* Consume and handle a pragma token.  */
 static void
 cp_lexer_handle_pragma (cp_lexer *lexer)
 {
@@ -668,10 +617,7 @@ cp_lexer_save_tokens (cp_lexer* lexer)
   if (cp_lexer_debugging_p (lexer))
     fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");
 
-  VARRAY_PUSH_INT (lexer->saved_tokens,
-                  cp_lexer_token_difference (lexer,
-                                             lexer->buffer,
-                                             lexer->next_token));
+  VEC_safe_push (cp_token_position, lexer->saved_tokens, lexer->next_token);
 }
 
 /* Commit to the portion of the token stream most recently saved.  */
@@ -683,7 +629,7 @@ cp_lexer_commit_tokens (cp_lexer* lexer)
   if (cp_lexer_debugging_p (lexer))
     fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");
 
-  VARRAY_POP (lexer->saved_tokens);
+  VEC_pop (cp_token_position, lexer->saved_tokens);
 }
 
 /* Return all tokens saved since the last call to cp_lexer_save_tokens
@@ -692,20 +638,11 @@ cp_lexer_commit_tokens (cp_lexer* lexer)
 static void
 cp_lexer_rollback_tokens (cp_lexer* lexer)
 {
-  size_t delta;
-
   /* Provide debugging output.  */
   if (cp_lexer_debugging_p (lexer))
     fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");
 
-  /* Find the token that was the NEXT_TOKEN when we started saving
-     tokens.  */
-  delta = VARRAY_TOP_INT(lexer->saved_tokens);
-  /* Make it the next token again now.  */
-  lexer->next_token = cp_lexer_advance_token (lexer, lexer->buffer, delta);
-
-  /* Stop saving tokens.  */
-  VARRAY_POP (lexer->saved_tokens);
+  lexer->next_token = VEC_pop (cp_token_position, lexer->saved_tokens);
 }
 
 /* Print a representation of the TOKEN on the STREAM.  */
@@ -778,7 +715,7 @@ cp_lexer_stop_debugging (cp_lexer* lexer)
 
 #endif /* ENABLE_CHECKING */
 
-/* Create a new cp_token_cache, representing a range of tokens. */
+/* Create a new cp_token_cache, representing a range of tokens.  */
 
 static cp_token_cache *
 cp_token_cache_new (cp_token *first, cp_token *last)
@@ -1074,8 +1011,8 @@ enum cp_parser_prec
   PREC_INCLUSIVE_OR_EXPRESSION,
   PREC_EXCLUSIVE_OR_EXPRESSION,
   PREC_AND_EXPRESSION,
-  PREC_RELATIONAL_EXPRESSION,
   PREC_EQUALITY_EXPRESSION,
+  PREC_RELATIONAL_EXPRESSION,
   PREC_SHIFT_EXPRESSION,
   PREC_ADDITIVE_EXPRESSION,
   PREC_MULTIPLICATIVE_EXPRESSION,
@@ -1328,7 +1265,7 @@ typedef struct cp_parser GTY(())
   bool in_type_id_in_expr_p;
 
   /* TRUE if we are currently in a header file where declarations are
-     implicitly extern "C". */
+     implicitly extern "C".  */
   bool implicit_extern_c;
 
   /* TRUE if strings in expressions should be translated to the execution
@@ -1543,9 +1480,9 @@ static void cp_parser_linkage_specification
 static tree cp_parser_init_declarator
   (cp_parser *, cp_decl_specifier_seq *, bool, bool, int, bool *);
 static cp_declarator *cp_parser_declarator
-  (cp_parser *, cp_parser_declarator_kind, int *, bool *);
+  (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
 static cp_declarator *cp_parser_direct_declarator
-  (cp_parser *, cp_parser_declarator_kind, int *);
+  (cp_parser *, cp_parser_declarator_kind, int *, bool);
 static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, cp_cv_quals *);
 static cp_cv_quals cp_parser_cv_qualifier_seq_opt
@@ -1577,7 +1514,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
@@ -1686,7 +1623,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
@@ -1765,7 +1702,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 *);
@@ -1776,7 +1713,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
@@ -1872,26 +1809,26 @@ cp_parser_name_lookup_error (cp_parser* parser,
   if (decl == error_mark_node)
     {
       if (parser->scope && parser->scope != global_namespace)
-       error ("`%D::%D' has not been declared",
+       error ("%<%D::%D%> has not been declared",
               parser->scope, name);
       else if (parser->scope == global_namespace)
-       error ("`::%D' has not been declared", name);
+       error ("%<::%D%> has not been declared", name);
       else if (parser->object_scope 
               && !CLASS_TYPE_P (parser->object_scope))
-       error ("request for member `%D' in non-class type `%T'",
+       error ("request for member %qD in non-class type %qT",
               name, parser->object_scope);
       else if (parser->object_scope)
-       error ("`%T::%D' has not been declared", 
+       error ("%<%T::%D%> has not been declared", 
               parser->object_scope, name);
       else
-       error ("`%D' has not been declared", name);
+       error ("%qD has not been declared", name);
     }
   else if (parser->scope && parser->scope != global_namespace)
-    error ("`%D::%D' %s", parser->scope, name, desired);
+    error ("%<%D::%D%> %s", parser->scope, name, desired);
   else if (parser->scope == global_namespace)
-    error ("`::%D' %s", name, desired);
+    error ("%<::%D%> %s", name, desired);
   else
-    error ("`%D' %s", name, desired);
+    error ("%qD %s", name, desired);
 }
 
 /* If we are parsing tentatively, remember that an error has occurred
@@ -1901,8 +1838,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;
@@ -1924,14 +1860,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
@@ -1942,9 +1878,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
@@ -1956,42 +1895,27 @@ static void
 cp_parser_check_for_invalid_template_id (cp_parser* parser,
                                         tree type)
 {
-  ptrdiff_t start;
-  cp_token *token;
+  cp_token_position start = 0;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
     {
       if (TYPE_P (type))
-       error ("`%T' is not a template", type);
+       error ("%qT is not a template", type);
       else if (TREE_CODE (type) == IDENTIFIER_NODE)
-       error ("`%E' is not a template", type);
+       error ("%qE is not a template", type);
       else
        error ("invalid template-id");
       /* Remember the location of the invalid "<".  */
-      if (cp_parser_parsing_tentatively (parser)
-         && !cp_parser_committed_to_tentative_parse (parser))
-       {
-         token = cp_lexer_peek_token (parser->lexer);
-         token = cp_lexer_prev_token (parser->lexer, token);
-         start = cp_lexer_token_difference (parser->lexer,
-                                            parser->lexer->buffer,
-                                            token);
-       }
-      else
-       start = -1;
+      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);
       /* Parse the template arguments.  */
       cp_parser_enclosed_template_argument_list (parser);
       /* Permanently remove the invalid template arguments so that
         this error message is not issued again.  */
-      if (start >= 0)
-       {
-         token = cp_lexer_advance_token (parser->lexer,
-                                         parser->lexer->buffer,
-                                         start);
-         cp_lexer_purge_tokens_after (parser->lexer, token);
-       }
+      if (start)
+       cp_lexer_purge_tokens_after (parser->lexer, start);
     }
 }
 
@@ -2015,9 +1939,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)
@@ -2031,12 +1954,12 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
   /* If the lookup found a template-name, it means that the user forgot
   to specify an argument list. Emit an useful error message.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
-    error ("invalid use of template-name `%E' without an argument list",
+    error ("invalid use of template-name %qE without an argument list",
       decl);
   else if (!parser->scope)
     {
       /* Issue an error message.  */
-      error ("`%E' does not name a type", id);
+      error ("%qE does not name a type", id);
       /* If we're in a template class, it's possible that the user was
         referring to a type from a base class.  For example:
 
@@ -2067,7 +1990,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
                    if (TREE_CODE (field) == TYPE_DECL
                        && DECL_NAME (field) == id)
                      {
-                       inform ("(perhaps `typename %T::%E' was intended)",
+                       inform ("(perhaps %<typename %T::%E%> was intended)",
                                BINFO_TYPE (b), id);
                        break;
                      }
@@ -2082,11 +2005,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
   else
     {
       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
-       error ("`%E' in namespace `%E' does not name a type",
+       error ("%qE in namespace %qE does not name a type",
               id, parser->scope);
       else if (TYPE_P (parser->scope))
-       error ("`%E' in class `%T' does not name a type",
-              id, parser->scope);
+       error ("%qE in class %qT does not name a type", id, parser->scope);
       else
        gcc_unreachable ();
     }
@@ -2151,8 +2073,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)
@@ -2373,12 +2295,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);
 }
 
 
@@ -2439,7 +2362,7 @@ cp_parser_new (void)
   /* We are not parsing a type-id inside an expression.  */
   parser->in_type_id_in_expr_p = false;
 
-  /* Declarations aren't implicitly extern "C". */
+  /* Declarations aren't implicitly extern "C".  */
   parser->implicit_extern_c = false;
 
   /* String literals should be translated to the execution character set.  */
@@ -2635,10 +2558,7 @@ cp_parser_translation_unit (cp_parser* parser)
       /* If there are no tokens left then all went well.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
        {
-         /* Consume the EOF token.  */
-         cp_parser_require (parser, CPP_EOF, "end-of-file");
-
-         /* Get rid of the token array; we don't need it any more. */
+         /* Get rid of the token array; we don't need it any more.  */
          cp_lexer_destroy (parser->lexer);
          parser->lexer = NULL;
 
@@ -2816,7 +2736,7 @@ cp_parser_primary_expression (cp_parser *parser,
          cp_lexer_consume_token (parser->lexer);
          if (parser->local_variables_forbidden_p)
            {
-             error ("`this' may not be used in this context");
+             error ("%<this%> may not be used in this context");
              return error_mark_node;
            }
          /* Pointers cannot appear in constant-expressions.  */
@@ -2912,7 +2832,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,
@@ -2951,7 +2871,7 @@ cp_parser_primary_expression (cp_parser *parser,
                decl = check_for_out_of_scope_variable (decl);
                if (local_variable_p (decl))
                  {
-                   error ("local variable `%D' may not appear in this context",
+                   error ("local variable %qD may not appear in this context",
                           decl);
                    return error_mark_node;
                  }
@@ -3245,7 +3165,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);
@@ -3263,7 +3183,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);
@@ -3281,7 +3201,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);
@@ -3296,7 +3216,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);
@@ -3316,7 +3236,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (declarator_p
            && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
            && !DECL_SELF_REFERENCE_P (type_decl))
-         error ("typedef-name `%D' used as destructor declarator",
+         error ("typedef-name %qD used as destructor declarator",
                 type_decl);
 
        return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
@@ -3383,8 +3303,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
 {
   bool success = false;
   tree access_check = NULL_TREE;
-  ptrdiff_t start;
-  cp_tokentoken;
+  cp_token_position start = 0;
+  cp_token *token;
 
   /* If the next token corresponds to a nested name specifier, there
      is no need to reparse it.  However, if CHECK_DEPENDENCY_P is
@@ -3401,16 +3321,8 @@ 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))
-    {
-      token = cp_lexer_peek_token (parser->lexer);
-      start = cp_lexer_token_difference (parser->lexer,
-                                        parser->lexer->buffer,
-                                        token);
-    }
-  else
-    start = -1;
+  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+    start = cp_lexer_token_position (parser->lexer, false);
 
   push_deferring_access_checks (dk_deferred);
 
@@ -3522,8 +3434,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
 
                  decl = cp_parser_lookup_name_simple (parser, token->value);
                  if (TREE_CODE (decl) == TEMPLATE_DECL)
-                   error ("`%D' used without template parameters",
-                          decl);
+                   error ("%qD used without template parameters", decl);
                  else
                    cp_parser_name_lookup_error
                      (parser, token->value, decl,
@@ -3572,21 +3483,18 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
      token.  That way, 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.  */
-  if (success && start >= 0)
+  if (success && start)
     {
-      /* Find the token that corresponds to the start of the
-        template-id.  */
-      token = cp_lexer_advance_token (parser->lexer,
-                                     parser->lexer->buffer,
-                                     start);
-
+      cp_token *token = cp_lexer_token_at (parser->lexer, start);
+      
       /* Reset the contents of the START token.  */
       token->type = CPP_NESTED_NAME_SPECIFIER;
       token->value = build_tree_list (access_check, parser->scope);
       TREE_TYPE (token->value) = parser->qualifying_scope;
       token->keyword = RID_MAX;
+      
       /* Purge all subsequent tokens.  */
-      cp_lexer_purge_tokens_after (parser->lexer, token);
+      cp_lexer_purge_tokens_after (parser->lexer, start);
     }
 
   pop_deferring_access_checks ();
@@ -3671,7 +3579,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);
@@ -3907,6 +3815,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);
@@ -4063,20 +3972,38 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
            koenig_p = false;
            if (idk == CP_ID_KIND_UNQUALIFIED)
              {
+               if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
+                 {
+                   if (args)
+                     {
+                       koenig_p = true;
+                       postfix_expression
+                         = perform_koenig_lookup (postfix_expression, args);
+                     }
+                   else
+                     postfix_expression
+                       = unqualified_fn_lookup_error (postfix_expression);
+                 }
                /* We do not perform argument-dependent lookup if
                   normal lookup finds a non-function, in accordance
                   with the expected resolution of DR 218.  */
-               if (args
-                   && (is_overloaded_fn (postfix_expression)
-                       || TREE_CODE (postfix_expression) == IDENTIFIER_NODE))
+               else if (args && is_overloaded_fn (postfix_expression))
                  {
-                   koenig_p = true;
-                   postfix_expression
-                     = perform_koenig_lookup (postfix_expression, args);
+                   tree fn = get_first_fn (postfix_expression);
+
+                   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))
+                     {
+                       koenig_p = true;
+                       postfix_expression
+                         = perform_koenig_lookup (postfix_expression, args);
+                     }
                  }
-               else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
-                 postfix_expression
-                   = unqualified_fn_lookup_error (postfix_expression);
              }
 
            if (TREE_CODE (postfix_expression) == COMPONENT_REF)
@@ -4258,6 +4185,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
   tree name;
   bool dependent_p;
   bool template_p;
+  bool pseudo_destructor_p;
   tree scope = NULL_TREE;
 
   /* If this is a `->' operator, dereference the pointer.  */
@@ -4299,11 +4227,34 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
        postfix_expression = error_mark_node;
     }
 
-  /* If the SCOPE is not a scalar type, we are looking at an
-     ordinary class member access expression, rather than a
-     pseudo-destructor-name.  */
-  if (!scope || !SCALAR_TYPE_P (scope))
+  /* Assume this expression is not a pseudo-destructor access.  */
+  pseudo_destructor_p = false;
+
+  /* If the SCOPE is a scalar type, then, if this is a valid program,
+     we must be looking at a pseudo-destructor-name.  */
+  if (scope && SCALAR_TYPE_P (scope))
+    {
+      tree s;
+      tree type;
+
+      cp_parser_parse_tentatively (parser);
+      /* Parse the pseudo-destructor-name.  */
+      s = NULL_TREE;
+      cp_parser_pseudo_destructor_name (parser, &s, &type);
+      if (cp_parser_parse_definitely (parser))
+       {
+         pseudo_destructor_p = true;
+         postfix_expression
+           = finish_pseudo_destructor_expr (postfix_expression,
+                                            s, TREE_TYPE (type));
+       }
+    }
+
+  if (!pseudo_destructor_p)
     {
+      /* If the SCOPE is not a scalar type, we are looking at an
+        ordinary class member access expression, rather than a
+        pseudo-destructor-name.  */
       template_p = cp_parser_optional_template_keyword (parser);
       /* Parse the id-expression.  */
       name = cp_parser_id_expression (parser, template_p,
@@ -4325,31 +4276,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);
-    }
-  /* Otherwise, try the pseudo-destructor-name production.  */
-  else
-    {
-      tree s = NULL_TREE;
-      tree type;
-
-      /* Parse the pseudo-destructor-name.  */
-      cp_parser_pseudo_destructor_name (parser, &s, &type);
-      /* Form the call.  */
-      postfix_expression
-       = finish_pseudo_destructor_expr (postfix_expression,
-                                        s, TREE_TYPE (type));
     }
 
   /* We no longer need to look up names in the scope of the object on
@@ -4393,6 +4341,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
                                         bool *non_constant_p)
 {
   tree expression_list = NULL_TREE;
+  bool fold_expr_p = is_attribute_list;
   tree identifier = NULL_TREE;
 
   /* Assume all the expressions will be constant.  */
@@ -4435,6 +4384,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
            else
              expr = cp_parser_assignment_expression (parser);
 
+           if (fold_expr_p)
+             expr = fold_non_dependent_expr (expr);
+
             /* Add it to the list.  We add error_mark_node
                expressions to the list, so that we can still tell if
                the correct form for a parenthesized expression-list
@@ -4846,7 +4798,7 @@ cp_parser_new_expression (cp_parser* parser)
          inform ("try removing the parentheses around the type-id");
          cp_parser_direct_new_declarator (parser);
        }
-      nelts = integer_one_node;
+      nelts = NULL_TREE;
     }
   /* Otherwise, there must be a new-type-id.  */
   else
@@ -4945,15 +4897,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
@@ -5051,7 +4995,8 @@ cp_parser_direct_new_declarator (cp_parser* parser)
                                              /*complain=*/true);
              if (!expression)
                {
-                 error ("expression in new-declarator must have integral or enumeration type");
+                 error ("expression in new-declarator must have integral "
+                         "or enumeration type");
                  expression = error_mark_node;
                }
            }
@@ -5357,7 +5302,7 @@ cp_parser_binary_expression (cp_parser* parser)
            will happen repeatedly;
          - or, we found an operator which has lower priority.  This is the case 
            where the recursive descent *ascends*, as in `3 * 4 + 5' after
-           parsing `3 * 4'. */
+           parsing `3 * 4'.  */
       if (new_prec <= prec)
         {
           if (sp == stack)
@@ -5369,7 +5314,7 @@ cp_parser_binary_expression (cp_parser* parser)
      get_rhs:
       tree_type = binops_by_token[token->type].tree_type;
 
-      /* We used the operator token. */
+      /* We used the operator token.  */
       cp_lexer_consume_token (parser->lexer);
 
       /* Extract another operand.  It may be the RHS of this expression
@@ -5378,7 +5323,7 @@ cp_parser_binary_expression (cp_parser* parser)
 
       /* Get another operator token.  Look up its precedence to avoid
          building a useless (immediately popped) stack entry for common
-         cases such as 3 + 4 + 5 or 3 * 4 + 5.   */
+         cases such as 3 + 4 + 5 or 3 * 4 + 5.  */
       token = cp_lexer_peek_token (parser->lexer);
       lookahead_prec = TOKEN_PRECEDENCE (token);
       if (lookahead_prec > new_prec)
@@ -5987,7 +5932,7 @@ cp_parser_labeled_statement (cp_parser* parser, tree in_statement_expr)
          expr_hi = NULL_TREE;
 
        if (!parser->in_switch_statement_p)
-         error ("case label `%E' not within a switch statement", expr);
+         error ("case label %qE not within a switch statement", expr);
        else
          statement = finish_case_label (expr, expr_hi);
       }
@@ -6247,7 +6192,8 @@ cp_parser_condition (cp_parser* parser)
       /* Parse the declarator.  */
       declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        /*parenthesized_p=*/NULL);
+                                        /*parenthesized_p=*/NULL,
+                                        /*member_p=*/false);
       /* Parse the attributes.  */
       attributes = cp_parser_attributes_opt (parser);
       /* Parse the asm-specification.  */
@@ -6493,7 +6439,7 @@ cp_parser_jump_statement (cp_parser* parser)
        }
       else
        statement = finish_break_stmt ();
-      cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
       break;
 
     case RID_CONTINUE:
@@ -6504,7 +6450,7 @@ cp_parser_jump_statement (cp_parser* parser)
        }
       else
        statement = finish_continue_stmt ();
-      cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
       break;
 
     case RID_RETURN:
@@ -6520,7 +6466,7 @@ cp_parser_jump_statement (cp_parser* parser)
        /* Build the return-statement.  */
        statement = finish_return_stmt (expr);
        /* Look for the final `;'.  */
-       cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+       cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
       }
       break;
 
@@ -6539,7 +6485,7 @@ cp_parser_jump_statement (cp_parser* parser)
       else
        finish_goto_stmt (cp_parser_identifier (parser));
       /* Look for the final `;'.  */
-      cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+      cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
       break;
 
     default:
@@ -6660,7 +6606,7 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
        }
 
       /* If we're entering or exiting a region that's implicitly
-        extern "C", modify the lang context appropriately. */
+        extern "C", modify the lang context appropriately.  */
       if (!parser->implicit_extern_c && token->implicit_extern_c)
        {
          push_lang_context (lang_name_c);
@@ -6924,7 +6870,8 @@ cp_parser_simple_declaration (cp_parser* parser,
        T t;
 
      where "T" should name a type -- but does not.  */
-  if (cp_parser_parse_and_diagnose_invalid_type_name (parser))
+  if (!decl_specifiers.type
+      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     {
       /* If parsing tentatively, we should commit; we really are
         looking at a declaration.  */
@@ -6995,9 +6942,8 @@ 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_error (parser, "expected `,' or `;'");
+             || 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);
          /* If the next token is now a `;', consume it.  */
@@ -7105,7 +7051,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
               friend  */
        case RID_FRIEND:
          if (decl_specs->specs[(int) ds_friend]++)
-           error ("duplicate `friend'");
+           error ("duplicate %<friend%>");
          /* Consume the token.  */
          cp_lexer_consume_token (parser->lexer);
          break;
@@ -7679,7 +7625,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
   /* `typename' is not allowed in this context ([temp.res]).  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
     {
-      error ("keyword `typename' not allowed in this context (a qualified "
+      error ("keyword %<typename%> not allowed in this context (a qualified "
             "member initializer is implicitly a type)");
       cp_lexer_consume_token (parser->lexer);
     }
@@ -7715,7 +7661,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);
@@ -7725,7 +7671,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);
@@ -8041,7 +7987,7 @@ cp_parser_template_declaration (cp_parser* parser, bool member_p)
       /* Consume the `export' token.  */
       cp_lexer_consume_token (parser->lexer);
       /* Warn that we do not support `export'.  */
-      warning ("keyword `export' not implemented, and will be ignored");
+      warning ("keyword %<export%> not implemented, and will be ignored");
     }
 
   cp_parser_template_declaration_after_export (parser, member_p);
@@ -8242,9 +8188,15 @@ cp_parser_type_parameter (cp_parser* parser)
        if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
-         identifier = cp_parser_identifier (parser);
+         {
+           identifier = cp_parser_identifier (parser);
+           /* Treat invalid names as if the parameter were nameless.  */
+           if (identifier == error_mark_node)
+             identifier = NULL_TREE;
+         }
        else
          identifier = NULL_TREE;
+
        /* Create the template parameter.  */
        parameter = finish_template_template_parm (class_type_node,
                                                   identifier);
@@ -8273,11 +8225,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);
@@ -8287,15 +8239,13 @@ cp_parser_type_parameter (cp_parser* parser)
 
        /* Create the combined representation of the parameter and the
           default argument.  */
-       parameter =  build_tree_list (default_argument, parameter);
+       parameter = build_tree_list (default_argument, parameter);
       }
       break;
 
     default:
-      /* Anything else is an error.  */
-      cp_parser_error (parser,
-                      "expected `class', `typename', or `template'");
-      parameter = error_mark_node;
+      gcc_unreachable ();
+      break;
     }
 
   return parameter;
@@ -8324,7 +8274,7 @@ cp_parser_template_id (cp_parser *parser,
   tree template;
   tree arguments;
   tree template_id;
-  ptrdiff_t start_of_id;
+  cp_token_position start_of_id = 0;
   tree access_check = NULL_TREE;
   cp_token *next_token, *next_token_2;
   bool is_identifier;
@@ -8359,16 +8309,8 @@ 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))
-    {
-      next_token = cp_lexer_peek_token (parser->lexer);
-      start_of_id = cp_lexer_token_difference (parser->lexer,
-                                              parser->lexer->buffer,
-                                              next_token);
-    }
-  else
-    start_of_id = -1;
+  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);
 
@@ -8408,21 +8350,21 @@ cp_parser_template_id (cp_parser *parser,
             and return simply an error. Maybe this is not a template-id
             after all.  */
          next_token_2->type = CPP_COLON;
-         cp_parser_error (parser, "expected `<'");
+         cp_parser_error (parser, "expected %<<%>");
          pop_deferring_access_checks ();
          return error_mark_node;
        }
       /* Otherwise, emit an error about the invalid digraph, but continue
          parsing because we got our argument list.  */
-      pedwarn ("`<::' cannot begin a template-argument list");
-      inform ("`<:' is an alternate spelling for `['. Insert whitespace "
-             "between `<' and `::'");
+      pedwarn ("%<<::%> cannot begin a template-argument list");
+      inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
+             "between %<<%> and %<::%>");
       if (!flag_permissive)
        {
          static bool hint;
          if (!hint)
            {
-             inform ("(if you use `-fpermissive' G++ will accept your code)");
+             inform ("(if you use -fpermissive G++ will accept your code)");
              hint = true;
            }
        }
@@ -8468,23 +8410,19 @@ 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 >= 0)
+     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;
-
-      /* Find the token that corresponds to the start of the
-        template-id.  */
-      token = cp_lexer_advance_token (parser->lexer,
-                                     parser->lexer->buffer,
-                                     start_of_id);
-
+      cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
+      
       /* Reset the contents of the START_OF_ID token.  */
       token->type = CPP_TEMPLATE_ID;
       token->value = build_tree_list (access_check, template_id);
       token->keyword = RID_MAX;
+      
       /* Purge all subsequent tokens.  */
-      cp_lexer_purge_tokens_after (parser->lexer, token);
+      cp_lexer_purge_tokens_after (parser->lexer, start_of_id);
     }
 
   pop_deferring_access_checks ();
@@ -8594,26 +8532,15 @@ cp_parser_template_name (cp_parser* parser,
             need the template keyword before their name.  */
          && !constructor_name_p (identifier, parser->scope))
        {
-         ptrdiff_t start;
-         cp_token* token;
+         cp_token_position start = 0;
+         
          /* Explain what went wrong.  */
-         error ("non-template `%D' used as template", identifier);
-         inform ("use `%T::template %D' to indicate that it is a template",
+         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);
-             token = cp_lexer_peek_token (parser->lexer);
-             token = cp_lexer_prev_token (parser->lexer, token);
-             start = cp_lexer_token_difference (parser->lexer,
-                                                parser->lexer->buffer,
-                                                token);
-           }
-         else
-           start = -1;
+         /* 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);
@@ -8628,13 +8555,8 @@ cp_parser_template_name (cp_parser* parser,
             template argument list.  That will prevent duplicate
             error messages from being issued about the missing
             "template" keyword.  */
-         if (start >= 0)
-           {
-             token = cp_lexer_advance_token (parser->lexer,
-                                             parser->lexer->buffer,
-                                             start);
-             cp_lexer_purge_tokens_after (parser->lexer, token);
-           }
+         if (start)
+           cp_lexer_purge_tokens_after (parser->lexer, start);
          if (is_identifier)
            *is_identifier = true;
          return identifier;
@@ -8653,7 +8575,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,
@@ -8844,7 +8766,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,
@@ -8881,6 +8803,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);
@@ -8903,6 +8826,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,
@@ -8926,6 +8855,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);
 
@@ -8944,6 +8875,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,
@@ -9044,9 +8976,11 @@ cp_parser_explicit_instantiation (cp_parser* parser)
       declarator
        = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                /*ctor_dtor_or_conv_p=*/NULL,
-                               /*parenthesized_p=*/NULL);
-      cp_parser_check_for_definition_in_return_type (declarator,
-                                                    declares_class_or_enum);
+                               /*parenthesized_p=*/NULL,
+                               /*member_p=*/false);
+      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,
@@ -9188,7 +9122,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)
@@ -9534,7 +9476,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);
@@ -9625,7 +9567,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       tag_type = typename_type;
       /* The `typename' keyword is only allowed in templates.  */
       if (!processing_template_decl)
-       pedwarn ("using `typename' outside of template");
+       pedwarn ("using %<typename%> outside of template");
     }
   /* Otherwise it must be a class-key.  */
   else
@@ -9686,6 +9628,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);
@@ -9703,7 +9646,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.  */
@@ -9711,11 +9655,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,
@@ -9748,7 +9689,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;
            }
 
@@ -9805,15 +9748,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);
        }
     }
@@ -9832,6 +9783,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
    enum-specifier:
      enum identifier [opt] { enumerator-list [opt] }
 
+   GNU Extensions:
+     enum identifier [opt] { enumerator-list [opt] } attributes
+
    Returns an ENUM_TYPE representing the enumeration.  */
 
 static tree
@@ -9869,6 +9823,16 @@ cp_parser_enum_specifier (cp_parser* parser)
   /* Consume the final '}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
 
+  /* Look for trailing attributes to apply to this enumeration, and
+     apply them if appropriate.  */
+  if (cp_parser_allow_gnu_extensions_p (parser))
+    {
+      tree trailing_attr = cp_parser_attributes_opt (parser);
+      cplus_decl_attributes (&type,
+                            trailing_attr,
+                            (int) ATTR_FLAG_TYPE_IN_PLACE);
+    }
+
   /* Finish up the enumeration.  */
   finish_enum (type);
 
@@ -9982,7 +9946,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,7 +10089,6 @@ cp_parser_using_declaration (cp_parser* parser)
   bool global_scope_p;
   tree decl;
   tree identifier;
-  tree scope;
   tree qscope;
 
   /* Look for the `using' keyword.  */
@@ -10184,8 +10147,7 @@ cp_parser_using_declaration (cp_parser* parser)
     error ("a template-id may not appear in a using-declaration");
   else
     {
-      scope = current_scope ();
-      if (scope && TYPE_P (scope))
+      if (at_class_scope_p ())
        {
          /* Create the USING_DECL.  */
          decl = do_class_using_decl (build_nt (SCOPE_REF,
@@ -10199,7 +10161,7 @@ cp_parser_using_declaration (cp_parser* parser)
          decl = cp_parser_lookup_name_simple (parser, identifier);
          if (decl == error_mark_node)
            cp_parser_name_lookup_error (parser, identifier, decl, NULL);
-         else if (scope)
+         else if (!at_namespace_scope_p ())
            do_local_using_decl (decl, qscope, identifier);
          else
            do_toplevel_using_decl (decl, qscope, identifier);
@@ -10372,7 +10334,13 @@ cp_parser_asm_definition (cp_parser* parser)
                                  inputs, clobbers);
       /* If the extended syntax was not used, mark the ASM_EXPR.  */
       if (!extended_p)
-       ASM_INPUT_P (asm_stmt) = 1;
+       {
+         tree temp = asm_stmt;
+         if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
+           temp = TREE_OPERAND (temp, 0);
+         
+         ASM_INPUT_P (temp) = 1;
+       }
     }
   else
     assemble_asm (string);
@@ -10455,7 +10423,8 @@ cp_parser_init_declarator (cp_parser* parser,
   declarator
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                            &ctor_dtor_or_conv_p,
-                           /*parenthesized_p=*/NULL);
+                           /*parenthesized_p=*/NULL,
+                           /*member_p=*/false);
   /* Gather up the deferred checks.  */
   stop_deferring_access_checks ();
 
@@ -10464,8 +10433,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
@@ -10646,7 +10616,10 @@ cp_parser_init_declarator (cp_parser* parser,
   if (member_p)
     {
       if (pop_p)
-       pop_scope (scope);
+       {
+         pop_scope (scope);
+         pop_p = false;
+       }
       decl = grokfield (declarator, decl_specifiers,
                        initializer, /*asmspec=*/NULL_TREE,
                        /*attributes=*/NULL_TREE);
@@ -10715,13 +10688,16 @@ cp_parser_init_declarator (cp_parser* parser,
    expression, not a declaration.)
 
    If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
-   the declarator is a direct-declarator of the form "(...)".  */
+   the declarator is a direct-declarator of the form "(...)".  
+
+   MEMBER_P is true iff this declarator is a member-declarator.  */
 
 static cp_declarator *
 cp_parser_declarator (cp_parser* parser,
                       cp_parser_declarator_kind dcl_kind,
                       int* ctor_dtor_or_conv_p,
-                     bool* parenthesized_p)
+                     bool* parenthesized_p,
+                     bool member_p)
 {
   cp_token *token;
   cp_declarator *declarator;
@@ -10762,7 +10738,8 @@ cp_parser_declarator (cp_parser* parser,
       /* Parse the dependent declarator.  */
       declarator = cp_parser_declarator (parser, dcl_kind,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        /*parenthesized_p=*/NULL);
+                                        /*parenthesized_p=*/NULL,
+                                        /*member_p=*/false);
 
       /* If we are parsing an abstract-declarator, we must handle the
         case where the dependent declarator is absent.  */
@@ -10787,7 +10764,8 @@ cp_parser_declarator (cp_parser* parser,
        *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
                                                   CPP_OPEN_PAREN);
       declarator = cp_parser_direct_declarator (parser, dcl_kind,
-                                               ctor_dtor_or_conv_p);
+                                               ctor_dtor_or_conv_p,
+                                               member_p);
     }
 
   if (attributes && declarator != cp_error_declarator)
@@ -10820,13 +10798,14 @@ cp_parser_declarator (cp_parser* parser,
    we are parsing a direct-declarator.  It is
    CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
    of ambiguity we prefer an abstract declarator, as per
-   [dcl.ambig.res].  CTOR_DTOR_OR_CONV_P is as for
+   [dcl.ambig.res].  CTOR_DTOR_OR_CONV_P and MEMBER_P are as for
    cp_parser_declarator.  */
 
 static cp_declarator *
 cp_parser_direct_declarator (cp_parser* parser,
                              cp_parser_declarator_kind dcl_kind,
-                             int* ctor_dtor_or_conv_p)
+                             int* ctor_dtor_or_conv_p,
+                            bool member_p)
 {
   cp_token *token;
   cp_declarator *declarator = NULL;
@@ -10885,7 +10864,14 @@ cp_parser_direct_declarator (cp_parser* parser,
              cp_parameter_declarator *params;
              unsigned saved_num_template_parameter_lists;
 
-             cp_parser_parse_tentatively (parser);
+             /* In a member-declarator, the only valid interpretation
+                of a parenthesis is the start of a
+                parameter-declaration-clause.  (It is invalid to
+                initialize a static data member with a parenthesized
+                initializer; only the "=" form of initialization is
+                permitted.)  */
+             if (!member_p)
+               cp_parser_parse_tentatively (parser);
 
              /* Consume the `('.  */
              cp_lexer_consume_token (parser->lexer);
@@ -10911,7 +10897,7 @@ cp_parser_direct_declarator (cp_parser* parser,
 
              /* If all went well, parse the cv-qualifier-seq and the
                 exception-specification.  */
-             if (cp_parser_parse_definitely (parser))
+             if (member_p || cp_parser_parse_definitely (parser))
                {
                  cp_cv_quals cv_quals;
                  tree exception_specification;
@@ -10959,7 +10945,8 @@ cp_parser_direct_declarator (cp_parser* parser,
              parser->in_type_id_in_expr_p = true;
              declarator
                = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
-                                       /*parenthesized_p=*/NULL);
+                                       /*parenthesized_p=*/NULL,
+                                       member_p);
              parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
              first = false;
              /* Expect a `)'.  */
@@ -11002,6 +10989,11 @@ cp_parser_direct_declarator (cp_parser* parser,
                                                 &non_constant_p);
              if (!non_constant_p)
                bounds = fold_non_dependent_expr (bounds);
+             else if (!at_function_scope_p ())
+               {
+                 error ("array bound is not an integer constant");
+                 bounds = error_mark_node;
+               }
            }
          else
            bounds = NULL_TREE;
@@ -11039,7 +11031,7 @@ cp_parser_direct_declarator (cp_parser* parser,
              break;
            }
 
-         if (TREE_CODE (id) == SCOPE_REF && !current_scope ())
+         if (TREE_CODE (id) == SCOPE_REF && at_namespace_scope_p ())
            {
              tree scope = TREE_OPERAND (id, 0);
 
@@ -11068,7 +11060,7 @@ cp_parser_direct_declarator (cp_parser* parser,
                                                 /*only_current_p=*/false);
                  /* If that failed, the declarator is invalid.  */
                  if (type == error_mark_node)
-                   error ("`%T::%D' is not a type",
+                   error ("%<%T::%D%> is not a type",
                           TYPE_CONTEXT (scope),
                           TYPE_IDENTIFIER (scope));
                  /* Build a new DECLARATOR.  */
@@ -11114,8 +11106,9 @@ cp_parser_direct_declarator (cp_parser* parser,
                      && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
                    {
                      error ("invalid use of constructor as a template");
-                     inform ("use `%T::%D' instead of `%T::%T' to name the "
-                             "constructor in a qualified name", class_type,
+                     inform ("use %<%T::%D%> instead of %<%T::%T%> to name "
+                              "the constructor in a qualified name",
+                              class_type,
                              DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
                              class_type, class_type);
                    }
@@ -11385,7 +11378,8 @@ cp_parser_type_id (cp_parser* parser)
   /* Look for the declarator.  */
   abstract_declarator
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
-                           /*parenthesized_p=*/NULL);
+                           /*parenthesized_p=*/NULL,
+                           /*member_p=*/false);
   /* Check to see if there really was a declarator.  */
   if (!cp_parser_parse_definitely (parser))
     abstract_declarator = NULL;
@@ -11615,8 +11609,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
@@ -11626,9 +11619,8 @@ 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))
+         cp_parser_error (parser, "expected %<,%> or %<...%>");
+         if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
            cp_parser_skip_to_closing_parenthesis (parser,
                                                   /*recovering=*/true,
                                                   /*or_comma=*/false,
@@ -11731,15 +11723,15 @@ 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.  */
       declarator = cp_parser_declarator (parser,
                                         CP_PARSER_DECLARATOR_EITHER,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        parenthesized_p);
+                                        parenthesized_p,
+                                        /*member_p=*/false);
       parser->default_arg_ok_p = saved_default_arg_ok_p;
       /* After the declarator, allow more attributes.  */
       decl_specifiers.attributes
@@ -11768,7 +11760,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
          cp_token *token;
 
          /* Add tokens until we have processed the entire default
-            argument.  We add the range [first_token, token). */
+            argument.  We add the range [first_token, token).  */
          first_token = cp_lexer_peek_token (parser->lexer);
          while (true)
            {
@@ -12123,11 +12115,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.  */
 
@@ -12135,7 +12126,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)
@@ -12191,10 +12182,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,
@@ -12216,7 +12207,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);
     }
@@ -12235,9 +12226,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");
@@ -12263,7 +12255,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);
@@ -12302,7 +12294,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);
 
@@ -12327,8 +12319,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
@@ -12440,6 +12432,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.  */
@@ -12523,7 +12517,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);
@@ -12595,7 +12589,7 @@ cp_parser_class_head (cp_parser* parser,
      xref_tag, since that has irreversible side-effects.  */
   if (!cp_parser_next_token_starts_class_definition_p (parser))
     {
-      cp_parser_error (parser, "expected `{' or `:'");
+      cp_parser_error (parser, "expected %<{%> or %<:%>");
       return error_mark_node;
     }
 
@@ -12612,16 +12606,23 @@ 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 (!scope)
-       scope = current_namespace;
       /* If that scope does not contain the scope in which the
         class was originally declared, the program is invalid.  */
       if (scope && !is_ancestor (scope, nested_name_specifier))
        {
-         error ("declaration of `%D' in `%D' which does not "
-                "enclose `%D'", type, scope, nested_name_specifier);
+         error ("declaration of %qD in %qD which does not enclose %qD",
+                 type, scope, nested_name_specifier);
          type = NULL_TREE;
          goto done;
        }
@@ -12644,7 +12645,7 @@ cp_parser_class_head (cp_parser* parser,
       && parser->num_template_parameter_lists == 0
       && template_id_p)
     {
-      error ("an explicit specialization must be preceded by 'template <>'");
+      error ("an explicit specialization must be preceded by %<template <>%>");
       invalid_explicit_specialization_p = true;
       /* Take the same action that would have been taken by
         cp_parser_explicit_specialization.  */
@@ -12675,7 +12676,7 @@ cp_parser_class_head (cp_parser* parser,
       /* If the class was unnamed, create a dummy name.  */
       if (!id)
        id = make_anon_name ();
-      type = xref_tag (class_key, id, /*globalize=*/false,
+      type = xref_tag (class_key, id, /*tag_scope=*/ts_current,
                       parser->num_template_parameter_lists);
     }
   else
@@ -12713,7 +12714,15 @@ cp_parser_class_head (cp_parser* parser,
       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 = push_template_decl (type);
+         if (type == error_mark_node)
+           {
+             type = NULL_TREE;
+             goto done;
+           }
+       }
+      
       type = TREE_TYPE (type);
       if (nested_name_specifier)
        {
@@ -12826,6 +12835,13 @@ cp_parser_member_specification_opt (cp_parser* parser)
          break;
 
        default:
+         /* Accept #pragmas at class scope.  */
+         if (token->type == CPP_PRAGMA)
+           {
+             cp_lexer_handle_pragma (parser->lexer);
+             break;
+           }
+
          /* Otherwise, the next construction must be a
             member-declaration.  */
          cp_parser_member_declaration (parser);
@@ -12909,7 +12925,8 @@ cp_parser_member_declaration (cp_parser* parser)
   prefix_attributes = decl_specifiers.attributes;
   decl_specifiers.attributes = NULL_TREE;
   /* Check for an invalid type-name.  */
-  if (cp_parser_parse_and_diagnose_invalid_type_name (parser))
+  if (!decl_specifiers.type
+      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     return;
   /* If there is no declarator, then the decl-specifier-seq should
      specify a type.  */
@@ -13055,7 +13072,8 @@ cp_parser_member_declaration (cp_parser* parser)
              declarator
                = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                        &ctor_dtor_or_conv_p,
-                                       /*parenthesized_p=*/NULL);
+                                       /*parenthesized_p=*/NULL,
+                                       /*member_p=*/true);
 
              /* If something went wrong parsing the declarator, make sure
                 that we at least consume some tokens.  */
@@ -13074,8 +13092,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);
@@ -13120,7 +13139,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.  */
@@ -13179,7 +13198,7 @@ cp_parser_member_declaration (cp_parser* parser)
          else if (cp_lexer_next_token_is_not (parser->lexer,
                                               CPP_SEMICOLON))
            {
-             cp_parser_error (parser, "expected `;'");
+             cp_parser_error (parser, "expected %<;%>");
              /* Skip tokens until we find a `;'.  */
              cp_parser_skip_to_end_of_statement (parser);
 
@@ -13364,7 +13383,7 @@ cp_parser_base_specifier (cp_parser* parser)
          if (virtual_p && !duplicate_virtual_error_issued_p)
            {
              cp_parser_error (parser,
-                              "`virtual' specified more than once in base-specified");
+                              "%<virtual%> specified more than once in base-specified");
              duplicate_virtual_error_issued_p = true;
            }
 
@@ -13406,9 +13425,9 @@ cp_parser_base_specifier (cp_parser* parser)
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
     {
       if (!processing_template_decl)
-       error ("keyword `typename' not allowed outside of templates");
+       error ("keyword %<typename%> not allowed outside of templates");
       else
-       error ("keyword `typename' not allowed in this context "
+       error ("keyword %<typename%> not allowed in this context "
               "(the base class is implicitly a type)");
       cp_lexer_consume_token (parser->lexer);
     }
@@ -13430,7 +13449,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.  */
@@ -13441,7 +13460,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);
@@ -13672,7 +13691,8 @@ cp_parser_exception_declaration (cp_parser* parser)
   else
     declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
                                       /*ctor_dtor_or_conv_p=*/NULL,
-                                      /*parenthesized_p=*/NULL);
+                                      /*parenthesized_p=*/NULL,
+                                      /*member_p=*/false);
 
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
@@ -14064,8 +14084,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.
@@ -14081,7 +14102,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)
 {
@@ -14159,16 +14181,20 @@ 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,
+                                               name, NULL_TREE,
                                                /*complain=*/1);
          else
            decl = build_nt (SCOPE_REF, parser->scope, name);
@@ -14188,7 +14214,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
             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);
@@ -14208,9 +14235,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;
@@ -14220,7 +14249,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;
@@ -14243,7 +14273,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
         cp_parser_error, so we incorporate its actions directly.  */
       if (!cp_parser_simulate_error (parser))
        {
-         error ("reference to `%D' is ambiguous", name);
+         error ("reference to %qD is ambiguous", name);
          print_candidates (decl);
        }
       return error_mark_node;
@@ -14276,7 +14306,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,
@@ -14534,7 +14564,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);
@@ -14836,6 +14866,11 @@ cp_parser_single_declaration (cp_parser* parser,
   cp_decl_specifier_seq decl_specifiers;
   bool function_definition_p = false;
 
+  /* This function is only used when processing a template
+     declaration.  */
+  gcc_assert (innermost_scope_kind () == sk_template_parms
+             || innermost_scope_kind () == sk_template_spec);
+
   /* Defer access checks until we know what is being declared.  */
   push_deferring_access_checks (dk_deferred);
 
@@ -14847,6 +14882,14 @@ cp_parser_single_declaration (cp_parser* parser,
                                &declares_class_or_enum);
   if (friend_p)
     *friend_p = cp_parser_friend_p (&decl_specifiers);
+
+  /* There are no template typedefs.  */
+  if (decl_specifiers.specs[(int) ds_typedef])
+    {
+      error ("template declaration of %qs", "typedef");
+      decl = error_mark_node;
+    }
+
   /* Gather up the access checks that occurred the
      decl-specifier-seq.  */
   stop_deferring_access_checks ();
@@ -14857,14 +14900,27 @@ cp_parser_single_declaration (cp_parser* parser,
       if (cp_parser_declares_only_class_p (parser))
        {
          decl = shadow_tag (&decl_specifiers);
+
+         /* In this case:
+
+              struct C {
+                friend template <typename T> struct A<T>::B;
+              };
+
+            A<T>::B will be represented by a TYPENAME_TYPE, and
+            therefore not recognized by shadow_tag.  */
+         if (friend_p && *friend_p
+             && !decl
+             && decl_specifiers.type
+             && TYPE_P (decl_specifiers.type))
+           decl = decl_specifiers.type;
+
          if (decl && decl != error_mark_node)
            decl = TYPE_NAME (decl);
          else
            decl = error_mark_node;
        }
     }
-  else
-    decl = NULL_TREE;
   /* If it's not a template class, try for a template function.  If
      the next token is a `;', then this declaration does not declare
      anything.  But, if there were errors in the decl-specifiers, then
@@ -14889,7 +14945,8 @@ cp_parser_single_declaration (cp_parser* parser,
   parser->object_scope = NULL_TREE;
   /* Look for a trailing `;' after the declaration.  */
   if (!function_definition_p
-      && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+      && (decl == error_mark_node
+         || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
     cp_parser_skip_to_end_of_block_or_statement (parser);
 
   return decl;
@@ -15203,7 +15260,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
         there was extra junk after the end of the default
         argument.  */
       if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
-       cp_parser_error (parser, "expected `,'");
+       cp_parser_error (parser, "expected %<,%>");
 
       /* Revert to the main lexer.  */
       cp_parser_pop_lexer (parser);
@@ -15232,7 +15289,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
 
   /* Initialize FORMAT the first time we get here.  */
   if (!format)
-    format = "types may not be defined in `%s' expressions";
+    format = "types may not be defined in '%s' expressions";
 
   /* Types cannot be defined in a `sizeof' expression.  Save away the
      old message.  */
@@ -15270,7 +15327,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
       type = cp_parser_type_id (parser);
       parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
       /* Now, look for the trailing `)'.  */
-      cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+      cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
       /* If all went well, then we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
@@ -15339,12 +15396,14 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
 {
   decl_specs->any_specifiers_p = true;
 
-  /* If the user tries to redeclare a built-in type (with, for example,
-     in "typedef int wchar_t;") we remember that this is what
+  /* If the user tries to redeclare bool or wchar_t (with, for
+     example, in "typedef int wchar_t;") we remember that this is what
      happened.  In system headers, we ignore these declarations so
      that G++ can work with system headers that are not C++-safe.  */
   if (decl_specs->specs[(int) ds_typedef]
       && !user_defined_p
+      && (type_spec == boolean_type_node
+         || type_spec == wchar_type_node)
       && (decl_specs->type
          || decl_specs->specs[(int) ds_long]
          || decl_specs->specs[(int) ds_short]
@@ -15507,9 +15566,7 @@ cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
 }
 
 /* Returns TRUE iff the next token is the "," or ">" ending a
-   template-argument. ">>" is also accepted (after the full
-   argument was parsed) because it's probably a typo for "> >",
-   and there is a specific diagnostic for this.  */
+   template-argument.  */
 
 static bool
 cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
@@ -15517,8 +15574,7 @@ cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
   cp_token *token;
 
   token = cp_lexer_peek_token (parser->lexer);
-  return (token->type == CPP_COMMA || token->type == CPP_GREATER
-         || token->type == CPP_RSHIFT);
+  return (token->type == CPP_COMMA || token->type == CPP_GREATER);
 }
 
 /* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the
@@ -15572,7 +15628,7 @@ static void
 cp_parser_check_class_key (enum tag_types class_key, tree type)
 {
   if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
-    pedwarn ("`%s' tag used in naming `%#T'",
+    pedwarn ("%qs tag used in naming %q#T",
            class_key == union_type ? "union"
             : class_key == record_type ? "struct" : "class",
             type);
@@ -15583,7 +15639,8 @@ cp_parser_check_class_key (enum tag_types class_key, tree type)
    This applies to nested classes and nested class templates.
    [class.mem/1].  */
 
-static void cp_parser_check_access_in_redeclaration (tree decl)
+static void
+cp_parser_check_access_in_redeclaration (tree decl)
 {
   if (!CLASS_TYPE_P (TREE_TYPE (decl)))
     return;
@@ -15592,7 +15649,7 @@ static void cp_parser_check_access_in_redeclaration (tree decl)
        != (current_access_specifier == access_private_node))
       || (TREE_PROTECTED (decl)
          != (current_access_specifier == access_protected_node)))
-    error ("%D redeclared with different access", decl);
+    error ("%qD redeclared with different access", decl);
 }
 
 /* Look for the `template' keyword, as a syntactic disambiguator.
@@ -15609,7 +15666,7 @@ cp_parser_optional_template_keyword (cp_parser *parser)
         template and what is not.  */
       if (!processing_template_decl)
        {
-         error ("`template' (as a disambiguator) is only allowed "
+         error ("%<template%> (as a disambiguator) is only allowed "
                 "within templates");
          /* If this part of the token stream is rescanned, the same
             error message would be generated.  So, we purge the token
@@ -15648,7 +15705,7 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
   parser->object_scope = NULL_TREE;
 }
 
-/* Consume tokens up through a non-nested END token. */
+/* Consume tokens up through a non-nested END token.  */
 
 static void
 cp_parser_cache_group (cp_parser *parser,
@@ -15772,14 +15829,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