- unsigned char flags;
- int digraph = 0;
- enum cpp_ttype type;
-
- type = cpp_can_paste (pfile, lhs, rhs, &digraph);
-
- if (type == CPP_EOF)
- {
- /* Mandatory warning for all apart from assembler. */
- if (CPP_OPTION (pfile, lang) != CLK_ASM)
- cpp_warning (pfile,
- "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
- cpp_token_as_text (pfile, lhs),
- cpp_token_as_text (pfile, rhs));
-
- /* The standard states that behaviour is undefined. By the
- principle of least surpise, we step back before the RHS, and
- mark it to prevent macro expansion. Tests in the testsuite
- rely on clearing PREV_WHITE here, though you could argue we
- should actually set it. Assembler can have '.' in labels and
- so requires that we don't insert spaces there. Maybe we should
- change this to put out a space unless it's assembler. */
- rhs->flags &= ~PREV_WHITE;
- rhs->flags |= NO_EXPAND;
- return 1;
- }
-
- flags = lhs->flags & ~DIGRAPH;
- if (digraph)
- flags |= DIGRAPH;
-
- /* Identifiers and numbers need spellings to be pasted. */
- if (type == CPP_NAME || type == CPP_NUMBER)
- {
- unsigned int total_len = cpp_token_len (lhs) + cpp_token_len (rhs);
- unsigned char *result, *end;
-
- result = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
-
- /* Paste the spellings and null terminate. */
- end = cpp_spell_token (pfile, rhs, cpp_spell_token (pfile, lhs, result));
- *end = '\0';
- total_len = end - result;
-
- if (type == CPP_NAME)
- {
- lhs->val.node = cpp_lookup (pfile, result, total_len);
- if (lhs->val.node->flags & NODE_OPERATOR)
- {
- flags |= NAMED_OP;
- lhs->type = lhs->val.node->value.operator;
- }
- }
- else
- {
- lhs->val.str.text = result;
- lhs->val.str.len = total_len;
- }
- }
- else if (type == CPP_WCHAR || type == CPP_WSTRING)
- lhs->val.str = rhs->val.str;
-
- /* Set type and flags after pasting spellings. */
- lhs->type = type;
- lhs->flags = flags;
-
- return 0;
+ unsigned char *buf, *end;
+ const cpp_token *lhs;
+ unsigned int len;
+ bool valid;
+
+ lhs = *plhs;
+ len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
+ buf = (unsigned char *) alloca (len);
+ end = cpp_spell_token (pfile, lhs, buf);
+
+ /* Avoid comment headers, since they are still processed in stage 3.
+ It is simpler to insert a space here, rather than modifying the
+ lexer to ignore comments in some circumstances. Simply returning
+ false doesn't work, since we want to clear the PASTE_LEFT flag. */
+ if (lhs->type == CPP_DIV
+ && (rhs->type == CPP_MULT || rhs->type == CPP_DIV))
+ *end++ = ' ';
+ end = cpp_spell_token (pfile, rhs, end);
+ *end = '\0';
+
+ cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1);
+
+ /* Tweak the column number the lexer will report. */
+ pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
+
+ /* We don't want a leading # to be interpreted as a directive. */
+ pfile->buffer->saved_flags = 0;
+
+ /* Set pfile->cur_token as required by _cpp_lex_direct. */
+ pfile->cur_token = _cpp_temp_token (pfile);
+ *plhs = _cpp_lex_direct (pfile);
+ valid = pfile->buffer->cur == pfile->buffer->rlimit;
+ _cpp_pop_buffer (pfile);
+
+ return valid;