diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f466650bb011629978a67f6b653c2c7cc623848d..7ea088127acaa365fcc460e6c5bd2467a338d093 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-10  Joseph Myers  <joseph@codesourcery.com>
+
+	* c-lex.c (c_lex_with_flags): Expect cpp_hashnode in
+	tok->val.node.node.
+
 2009-05-10  Jan Hubicka  <jh@suse.cz>
 
 	PR middle-end/40084
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index fc89279a7d9e20468cf925baa3ccfc40b3fc467a..66df4c40f7bd1fd0b8733f1a2ce76b6642586604 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -313,7 +313,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
       goto retry;
 
     case CPP_NAME:
-      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
+      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
       break;
 
     case CPP_NUMBER:
@@ -369,7 +369,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 	      break;
 
 	    case CPP_NAME:
-	      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
+	      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
 	      if (objc_is_reserved_word (*value))
 		{
 		  type = CPP_AT_NAME;
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index a541b69211cbaebea1f411aa95b29bb20959784d..4e21b5811215e6a246aee2ba5d16e4f21c7c0600 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,25 @@
+2009-05-10  Joseph Myers  <joseph@codesourcery.com>
+
+	* include/cpplib.h (enum cpp_token_fld_kind): Add
+	CPP_TOKEN_FLD_TOKEN_NO.
+	(struct cpp_macro_arg, struct cpp_identifier): Define.
+	(union cpp_token_u): Use struct cpp_identifier for identifiers.
+	Use struct cpp_macro_arg for macro arguments.  Add token_no for
+	CPP_PASTE token numbers.
+	* directives.c (_cpp_handle_directive, lex_macro_node, do_pragma,
+	do_pragma_poison, parse_assertion): Use val.node.node in place of
+	val.node.
+	* expr.c (parse_defined, eval_token): Use val.node.node in place
+	of val.node.
+	* lex.c (cpp_ideq, _cpp_lex_direct, cpp_token_len,
+	cpp_spell_token, cpp_output_token, _cpp_equiv_tokens,
+	cpp_token_val_index): Use val.macro_arg.arg_no or val.token_no in
+	place of val.arg_no.  Use val.node.node in place of val.node.
+	* macro.c (replace_args, cpp_get_token, parse_params,
+	lex_expansion_token, create_iso_definition, cpp_macro_definition):
+	Use val.macro_arg.arg_no or val.token_no in place of val.arg_no.
+	Use val.node.node in place of val.node.
+
 2009-05-03  Joseph Myers  <joseph@codesourcery.com>
 
 	* charset.c (one_utf8_to_cppchar): Correct mask used for 5-byte
diff --git a/libcpp/directives.c b/libcpp/directives.c
index c2e71016f2417689ad27057d4b251a290e6bcb0b..e71efb2bd94e08dc67b716ddd28fd1fff571ec9f 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -408,8 +408,8 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
 
   if (dname->type == CPP_NAME)
     {
-      if (dname->val.node->is_directive)
-	dir = &dtable[dname->val.node->directive_index];
+      if (dname->val.node.node->is_directive)
+	dir = &dtable[dname->val.node.node->directive_index];
     }
   /* We do not recognize the # followed by a number extension in
      assembler code.  */
@@ -538,7 +538,7 @@ lex_macro_node (cpp_reader *pfile, bool is_def_or_undef)
 
   if (token->type == CPP_NAME)
     {
-      cpp_hashnode *node = token->val.node;
+      cpp_hashnode *node = token->val.node.node;
 
       if (is_def_or_undef && node == pfile->spec_nodes.n_defined)
 	cpp_error (pfile, CPP_DL_ERROR,
@@ -549,7 +549,7 @@ lex_macro_node (cpp_reader *pfile, bool is_def_or_undef)
   else if (token->flags & NAMED_OP)
     cpp_error (pfile, CPP_DL_ERROR,
        "\"%s\" cannot be used as a macro name as it is an operator in C++",
-	       NODE_NAME (token->val.node));
+	       NODE_NAME (token->val.node.node));
   else if (token->type == CPP_EOF)
     cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive",
 	       pfile->directive->name);
@@ -1329,7 +1329,7 @@ do_pragma (cpp_reader *pfile)
   ns_token = *token;
   if (token->type == CPP_NAME)
     {
-      p = lookup_pragma_entry (pfile->pragmas, token->val.node);
+      p = lookup_pragma_entry (pfile->pragmas, token->val.node.node);
       if (p && p->is_nspace)
 	{
 	  bool allow_name_expansion = p->allow_expansion;
@@ -1337,7 +1337,7 @@ do_pragma (cpp_reader *pfile)
 	    pfile->state.prevent_expansion--;
 	  token = cpp_get_token (pfile);
 	  if (token->type == CPP_NAME)
-	    p = lookup_pragma_entry (p->u.space, token->val.node);
+	    p = lookup_pragma_entry (p->u.space, token->val.node.node);
 	  else
 	    p = NULL;
 	  if (allow_name_expansion)
@@ -1429,7 +1429,7 @@ do_pragma_poison (cpp_reader *pfile)
 	  break;
 	}
 
-      hp = tok->val.node;
+      hp = tok->val.node.node;
       if (hp->flags & NODE_POISONED)
 	continue;
 
@@ -1986,12 +1986,12 @@ parse_assertion (cpp_reader *pfile, struct answer **answerp, int type)
     cpp_error (pfile, CPP_DL_ERROR, "predicate must be an identifier");
   else if (parse_answer (pfile, answerp, type) == 0)
     {
-      unsigned int len = NODE_LEN (predicate->val.node);
+      unsigned int len = NODE_LEN (predicate->val.node.node);
       unsigned char *sym = (unsigned char *) alloca (len + 1);
 
       /* Prefix '#' to get it out of macro namespace.  */
       sym[0] = '#';
-      memcpy (sym + 1, NODE_NAME (predicate->val.node), len);
+      memcpy (sym + 1, NODE_NAME (predicate->val.node.node), len);
       result = cpp_lookup (pfile, sym, len + 1);
     }
 
diff --git a/libcpp/expr.c b/libcpp/expr.c
index ecedb96c672d8697059d04e0f5a1627d7c3173a7..6887b1656904ace1fcd230ecd374d682743e7e13 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -651,7 +651,7 @@ parse_defined (cpp_reader *pfile)
 
   if (token->type == CPP_NAME)
     {
-      node = token->val.node;
+      node = token->val.node.node;
       if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
 	{
 	  cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\"");
@@ -771,14 +771,14 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
       break;
 
     case CPP_NAME:
-      if (token->val.node == pfile->spec_nodes.n_defined)
+      if (token->val.node.node == pfile->spec_nodes.n_defined)
 	return parse_defined (pfile);
       else if (CPP_OPTION (pfile, cplusplus)
-	       && (token->val.node == pfile->spec_nodes.n_true
-		   || token->val.node == pfile->spec_nodes.n_false))
+	       && (token->val.node.node == pfile->spec_nodes.n_true
+		   || token->val.node.node == pfile->spec_nodes.n_false))
 	{
 	  result.high = 0;
-	  result.low = (token->val.node == pfile->spec_nodes.n_true);
+	  result.low = (token->val.node.node == pfile->spec_nodes.n_true);
 	}
       else
 	{
@@ -786,7 +786,7 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
 	  result.low = 0;
 	  if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
 	    cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
-		       NODE_NAME (token->val.node));
+		       NODE_NAME (token->val.node.node));
 	}
       break;
 
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 80e905686fc67968d62cb472cef64fb7ebab609f..83439c7341f1853b5f0ea40740af8c0a956bde75 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -189,10 +189,27 @@ enum cpp_token_fld_kind {
   CPP_TOKEN_FLD_SOURCE,
   CPP_TOKEN_FLD_STR,
   CPP_TOKEN_FLD_ARG_NO,
+  CPP_TOKEN_FLD_TOKEN_NO,
   CPP_TOKEN_FLD_PRAGMA,
   CPP_TOKEN_FLD_NONE
 };
 
+/* A macro argument in the cpp_token union.  */
+struct GTY(()) cpp_macro_arg {
+  /* Argument number.  */
+  unsigned int arg_no;
+};
+
+/* An identifier in the cpp_token union.  */
+struct GTY(()) cpp_identifier {
+  /* The canonical (UTF-8) spelling of the identifier.  */
+  cpp_hashnode *
+    GTY ((nested_ptr (union tree_node,
+		"%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+			"%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL")))
+       node;
+};
+
 /* A preprocessing token.  This has been carefully packed and should
    occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
 struct GTY(()) cpp_token {
@@ -203,12 +220,7 @@ struct GTY(()) cpp_token {
   union cpp_token_u
   {
     /* An identifier.  */
-    cpp_hashnode *
-      GTY ((nested_ptr (union tree_node,
-		"%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
-			"%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
-	    tag ("CPP_TOKEN_FLD_NODE")))
-	 node;
+    struct cpp_identifier GTY ((tag ("CPP_TOKEN_FLD_NODE"))) node;
 	 
     /* Inherit padding from this token.  */
     cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source;
@@ -217,7 +229,11 @@ struct GTY(()) cpp_token {
     struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str;
 
     /* Argument no. for a CPP_MACRO_ARG.  */
-    unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no;
+    struct cpp_macro_arg GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) macro_arg;
+
+    /* Original token no. for a CPP_PASTE (from a sequence of
+       consecutive paste tokens in a macro expansion).  */
+    unsigned int GTY ((tag ("CPP_TOKEN_FLD_TOKEN_NO"))) token_no;
 
     /* Caller-supplied identifier for a CPP_PRAGMA.  */
     unsigned int GTY ((tag ("CPP_TOKEN_FLD_PRAGMA"))) pragma;
diff --git a/libcpp/lex.c b/libcpp/lex.c
index af5c06a7abcfb3f3ef9be2863f1dde2ad06c0b11..ca2f2ca06f17d5ed7239e354bd0ff8e5ef053870 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -76,7 +76,7 @@ cpp_ideq (const cpp_token *token, const char *string)
   if (token->type != CPP_NAME)
     return 0;
 
-  return !ustrcmp (NODE_NAME (token->val.node), (const uchar *) string);
+  return !ustrcmp (NODE_NAME (token->val.node.node), (const uchar *) string);
 }
 
 /* Record a note TYPE at byte POS into the current cleaned logical
@@ -1120,16 +1120,16 @@ _cpp_lex_direct (cpp_reader *pfile)
       result->type = CPP_NAME;
       {
 	struct normalize_state nst = INITIAL_NORMALIZE_STATE;
-	result->val.node = lex_identifier (pfile, buffer->cur - 1, false,
-					   &nst);
+	result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false,
+						&nst);
 	warn_about_normalization (pfile, result, &nst);
       }
 
       /* Convert named operators to their proper types.  */
-      if (result->val.node->flags & NODE_OPERATOR)
+      if (result->val.node.node->flags & NODE_OPERATOR)
 	{
 	  result->flags |= NAMED_OP;
-	  result->type = (enum cpp_ttype) result->val.node->directive_index;
+	  result->type = (enum cpp_ttype) result->val.node.node->directive_index;
 	}
       break;
 
@@ -1244,7 +1244,7 @@ _cpp_lex_direct (cpp_reader *pfile)
 	      result->flags |= DIGRAPH;
 	      result->type = CPP_HASH;
 	      if (*buffer->cur == '%' && buffer->cur[1] == ':')
-		buffer->cur += 2, result->type = CPP_PASTE, result->val.arg_no = 0;
+		buffer->cur += 2, result->type = CPP_PASTE, result->val.token_no = 0;
 	    }
 	  else if (*buffer->cur == '>')
 	    {
@@ -1325,7 +1325,7 @@ _cpp_lex_direct (cpp_reader *pfile)
     case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break;
     case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break;
     case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break;
-    case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); result->val.arg_no = 0; break;
+    case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); result->val.token_no = 0; break;
 
     case '?': result->type = CPP_QUERY; break;
     case '~': result->type = CPP_COMPL; break;
@@ -1350,7 +1350,7 @@ _cpp_lex_direct (cpp_reader *pfile)
 	if (forms_identifier_p (pfile, true, &nst))
 	  {
 	    result->type = CPP_NAME;
-	    result->val.node = lex_identifier (pfile, base, true, &nst);
+	    result->val.node.node = lex_identifier (pfile, base, true, &nst);
 	    warn_about_normalization (pfile, result, &nst);
 	    break;
 	  }
@@ -1376,7 +1376,7 @@ cpp_token_len (const cpp_token *token)
     {
     default:		len = 6;				break;
     case SPELL_LITERAL:	len = token->val.str.len;		break;
-    case SPELL_IDENT:	len = NODE_LEN (token->val.node) * 10;	break;
+    case SPELL_IDENT:	len = NODE_LEN (token->val.node.node) * 10;	break;
     }
 
   return len;
@@ -1457,23 +1457,23 @@ cpp_spell_token (cpp_reader *pfile, const cpp_token *token,
     case SPELL_IDENT:
       if (forstring)
 	{
-	  memcpy (buffer, NODE_NAME (token->val.node),
-		  NODE_LEN (token->val.node));
-	  buffer += NODE_LEN (token->val.node);
+	  memcpy (buffer, NODE_NAME (token->val.node.node),
+		  NODE_LEN (token->val.node.node));
+	  buffer += NODE_LEN (token->val.node.node);
 	}
       else
 	{
 	  size_t i;
-	  const unsigned char * name = NODE_NAME (token->val.node);
+	  const unsigned char * name = NODE_NAME (token->val.node.node);
 	  
-	  for (i = 0; i < NODE_LEN (token->val.node); i++)
+	  for (i = 0; i < NODE_LEN (token->val.node.node); i++)
 	    if (name[i] & ~0x7F)
 	      {
 		i += utf8_to_ucn (buffer, name + i) - 1;
 		buffer += 10;
 	      }
 	    else
-	      *buffer++ = NODE_NAME (token->val.node)[i];
+	      *buffer++ = NODE_NAME (token->val.node.node)[i];
 	}
       break;
 
@@ -1550,9 +1550,9 @@ cpp_output_token (const cpp_token *token, FILE *fp)
     case SPELL_IDENT:
       {
 	size_t i;
-	const unsigned char * name = NODE_NAME (token->val.node);
+	const unsigned char * name = NODE_NAME (token->val.node.node);
 	
-	for (i = 0; i < NODE_LEN (token->val.node); i++)
+	for (i = 0; i < NODE_LEN (token->val.node.node); i++)
 	  if (name[i] & ~0x7F)
 	    {
 	      unsigned char buffer[10];
@@ -1560,7 +1560,7 @@ cpp_output_token (const cpp_token *token, FILE *fp)
 	      fwrite (buffer, 1, 10, fp);
 	    }
 	  else
-	    fputc (NODE_NAME (token->val.node)[i], fp);
+	    fputc (NODE_NAME (token->val.node.node)[i], fp);
       }
       break;
 
@@ -1583,13 +1583,14 @@ _cpp_equiv_tokens (const cpp_token *a, const cpp_token *b)
       {
       default:			/* Keep compiler happy.  */
       case SPELL_OPERATOR:
-	/* arg_no is used to track where multiple consecutive ##
+	/* token_no is used to track where multiple consecutive ##
 	   tokens were originally located.  */
-	return (a->type != CPP_PASTE || a->val.arg_no == b->val.arg_no);
+	return (a->type != CPP_PASTE || a->val.token_no == b->val.token_no);
       case SPELL_NONE:
-	return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
+	return (a->type != CPP_MACRO_ARG
+		|| a->val.macro_arg.arg_no == b->val.macro_arg.arg_no);
       case SPELL_IDENT:
-	return a->val.node == b->val.node;
+	return a->val.node.node == b->val.node.node;
       case SPELL_LITERAL:
 	return (a->val.str.len == b->val.str.len
 		&& !memcmp (a->val.str.text, b->val.str.text,
@@ -1901,7 +1902,7 @@ cpp_token_val_index (cpp_token *tok)
       return CPP_TOKEN_FLD_STR;
     case SPELL_OPERATOR:
       if (tok->type == CPP_PASTE)
-	return CPP_TOKEN_FLD_ARG_NO;
+	return CPP_TOKEN_FLD_TOKEN_NO;
       else
 	return CPP_TOKEN_FLD_NONE;
     case SPELL_NONE:
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 36853971780a1ba0ea5d0dfb67737bc2c7f56cf8..e051fbc7757b7e1d36bd11ed00c029c8e1e3a987 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -946,7 +946,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
 
 	/* We have an argument.  If it is not being stringified or
 	   pasted it is macro-replaced before insertion.  */
-	arg = &args[src->val.arg_no - 1];
+	arg = &args[src->val.macro_arg.arg_no - 1];
 
 	if (src->flags & STRINGIFY_ARG)
 	  {
@@ -982,7 +982,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
 	}
 
       paste_flag = 0;
-      arg = &args[src->val.arg_no - 1];
+      arg = &args[src->val.macro_arg.arg_no - 1];
       if (src->flags & STRINGIFY_ARG)
 	count = 1, from = &arg->stringified;
       else if (src->flags & PASTE_LEFT)
@@ -994,7 +994,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
 	    {
 	      if (dest[-1]->type == CPP_COMMA
 		  && macro->variadic
-		  && src->val.arg_no == macro->paramc)
+		  && src->val.macro_arg.arg_no == macro->paramc)
 		{
 		  /* Swallow a pasted comma if from == NULL, otherwise
 		     drop the paste flag.  */
@@ -1035,7 +1035,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
 		     "empty macro arguments are undefined"
 		     " in ISO C90 and ISO C++98",
 		     NODE_NAME (node),
-		     src->val.arg_no);
+		     src->val.macro_arg.arg_no);
 	}
 
       /* Avoid paste on RHS (even case count == 0).  */
@@ -1261,7 +1261,7 @@ cpp_get_token (cpp_reader *pfile)
       if (result->type != CPP_NAME)
 	break;
 
-      node = result->val.node;
+      node = result->val.node.node;
 
       if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
 	break;
@@ -1553,7 +1553,7 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
 	    }
 	  prev_ident = 1;
 
-	  if (_cpp_save_parameter (pfile, macro, token->val.node))
+	  if (_cpp_save_parameter (pfile, macro, token->val.node.node))
 	    return false;
 	  continue;
 
@@ -1626,10 +1626,10 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
 
   /* Is this a parameter?  */
   if (token->type == CPP_NAME
-      && (token->val.node->flags & NODE_MACRO_ARG) != 0)
+      && (token->val.node.node->flags & NODE_MACRO_ARG) != 0)
     {
       token->type = CPP_MACRO_ARG;
-      token->val.arg_no = token->val.node->value.arg_index;
+      token->val.macro_arg.arg_no = token->val.node.node->value.arg_index;
     }
   else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
 	   && (token->type == CPP_STRING || token->type == CPP_CHAR))
@@ -1771,7 +1771,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
 	    {
 	      macro->extra_tokens = 1;
 	      num_extra_tokens++;
-	      token->val.arg_no = macro->count - 1;
+	      token->val.token_no = macro->count - 1;
 	    }
 	  else
 	    {
@@ -2007,7 +2007,7 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
 	  cpp_token *token = &macro->exp.tokens[i];
 
 	  if (token->type == CPP_MACRO_ARG)
-	    len += NODE_LEN (macro->params[token->val.arg_no - 1]);
+	    len += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
 	  else
 	    len += cpp_token_len (token);
 
@@ -2079,9 +2079,9 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
 	  if (token->type == CPP_MACRO_ARG)
 	    {
 	      memcpy (buffer,
-		      NODE_NAME (macro->params[token->val.arg_no - 1]),
-		      NODE_LEN (macro->params[token->val.arg_no - 1]));
-	      buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
+		      NODE_NAME (macro->params[token->val.macro_arg.arg_no - 1]),
+		      NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]));
+	      buffer += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
 	    }
 	  else
 	    buffer = cpp_spell_token (pfile, token, buffer, false);