Subject: [PATCH] libcpp: Handle extended characters in user-defined literal suffix [PR103902] The PR complains that we do not handle UTF-8 in the suffix for a user-defined literal, such as: bool operator ""_π (unsigned long long); In fact we don't handle any extended identifier characters there, whether UTF-8, UCNs, or the $ sign. We do handle it fine if the optional space after the "" tokens is included, since then the identifier is lexed in the "normal" way as its own token. But when it is lexed as part of the string token, this is handled in lex_string() with a one-off loop that is not aware of extended characters. This patch fixes it by adding a new function scan_cur_identifier() that can be used to lex an identifier while in the middle of lexing another token. It is somewhat duplicative of the code in lex_identifier(), which handles the normal case, but I think there's no good way to avoid that without pessimizing the usual case, since lex_identifier() takes advantage of the fact that the first character of the identifier has already been analyzed. The code duplication is somewhat offset by factoring out the identifier lexing diagnostics (e.g. for poisoned identifiers), which were formerly duplicated in two places, and have been factored into their own function that's used in (now) 3 places. BTW, the other place that was lexing identifiers is lex_identifier_intern(), which is used to implement #pragma push_macro and #pragma pop_macro. This does not support extended characters either. I will add that in a subsequent patch, because it can't directly reuse the new function, but rather needs to lex from a string instead of a cpp_buffer. With scan_cur_identifier(), we do also correctly warn about bidi and normalization issues in the extended identifiers comprising the suffix, and we check for poisoned identifiers there as well. PR preprocessor/103902 libcpp/ChangeLog: * lex.cc (identifier_diagnostics_on_lex): New function refactors common code from... (lex_identifier_intern): ...here, and... (lex_identifier): ...here. (struct scan_id_result): New struct to hold the result of... (scan_cur_identifier): ...new function. (create_literal2): New function. (is_macro): Removed function that is now handled directly in lex_string() and lex_raw_string(). (is_macro_not_literal_suffix): Likewise. (lit_accum::create_literal2): New function. (lex_raw_string): Make use of new function scan_cur_identifier(). (lex_string): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/udlit-extended-id-1.C: New test. * g++.dg/cpp0x/udlit-extended-id-2.C: New test. * g++.dg/cpp0x/udlit-extended-id-3.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C new file mode 100644 index 00000000000..411d4fdd0ba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-1.C @@ -0,0 +1,68 @@ +// { dg-do run { target c++11 } } +// { dg-additional-options "-Wno-error=normalized" } +#include +using namespace std; + +constexpr unsigned long long operator "" _π (unsigned long long x) +{ + return 3 * x; +} + +/* Historically we didn't parse properly as part of the "" token, so check that + as well. */ +constexpr unsigned long long operator ""_Π2 (unsigned long long x) +{ + return 4 * x; +} + +char x1[1_π]; +char x2[2_Π2]; + +static_assert (sizeof x1 == 3, "test1"); +static_assert (sizeof x2 == 8, "test2"); + +const char * operator "" _1σ (const char *s, unsigned long) +{ + return s + 1; +} + +const char * operator ""_Σ2 (const char *s, unsigned long) +{ + return s + 2; +} + +const char * operator "" _\U000000e61 (const char *s, unsigned long) +{ + return "ae"; +} + +const char* operator ""_\u01532 (const char *s, unsigned long) +{ + return "oe"; +} + +bool operator "" _\u0BC7\u0BBE (unsigned long long); // { dg-warning "not in NFC" } +bool operator ""_\u0B47\U00000B3E (unsigned long long); // { dg-warning "not in NFC" } + +#define xτy +const char * str = ""xτy; // { dg-warning "invalid suffix on literal" } + +int main() +{ + if (3_π != 9) + __builtin_abort (); + if (4_Π2 != 16) + __builtin_abort (); + if (strcmp ("abc"_1σ, "bc")) + __builtin_abort (); + if (strcmp ("abcd"_Σ2, "cd")) + __builtin_abort (); + if (strcmp (R"(abcdef)"_1σ, "bcdef")) + __builtin_abort (); + if (strcmp (R"(abcdef)"_Σ2, "cdef")) + __builtin_abort (); + if (strcmp ("xyz"_æ1, "ae")) + __builtin_abort (); + if (strcmp ("xyz"_œ2, "oe")) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C new file mode 100644 index 00000000000..05a2804a463 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-2.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wbidi-chars=any,ucn" } +bool operator ""_d\u202ae\u202cf (unsigned long long); // { dg-line line1 } +// { dg-error "universal character \\\\u202a is not valid in an identifier" "test1" { target *-*-* } line1 } +// { dg-error "universal character \\\\u202c is not valid in an identifier" "test2" { target *-*-* } line1 } +// { dg-warning "found problematic Unicode character" "test3" { target *-*-* } line1 } diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C new file mode 100644 index 00000000000..6db729c3432 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-extended-id-3.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } +int _ħ; +const char * operator ""_ħ (const char *, unsigned long); +bool operator ""_ħ (unsigned long long x); +#pragma GCC poison _ħ +bool b = 1_ħ; // This currently is allowed, is that intended? +const char *x = "hbar"_ħ; // { dg-error "attempt to use poisoned" } diff --git a/libcpp/lex.cc b/libcpp/lex.cc index f891d3e17df..481f01bc5c3 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -1854,8 +1854,11 @@ warn_about_normalization (cpp_reader *pfile, static const cppchar_t utf8_signifier = 0xC0; -/* Returns TRUE if the sequence starting at buffer->cur is valid in - an identifier. FIRST is TRUE if this starts an identifier. */ +/* Returns TRUE if the byte sequence starting at buffer->cur is a valid + extended character in an identifier. If FIRST is TRUE, then the character + must be valid at the beginning of an identifier as well. If the return + value is TRUE, then pfile->buffer->cur has been moved to point to the next + byte after the extended character. */ static bool forms_identifier_p (cpp_reader *pfile, int first, @@ -1941,6 +1944,122 @@ maybe_va_opt_error (cpp_reader *pfile) } } +/* Helper function to perform diagnostics that are needed (rarely) + when an identifier is lexed. */ +static void identifier_diagnostics_on_lex (cpp_reader *pfile, + cpp_hashnode *node) +{ + if (__builtin_expect (!(node->flags & NODE_DIAGNOSTIC) + || pfile->state.skipping, 1)) + return; + + /* It is allowed to poison the same identifier twice. */ + if ((node->flags & NODE_POISONED) && !pfile->state.poisoned_ok) + cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", + NODE_NAME (node)); + + /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the + replacement list of a variadic macro. */ + if (node == pfile->spec_nodes.n__VA_ARGS__ + && !pfile->state.va_args_ok) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C++11 variadic macro"); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); + } + + if (node == pfile->spec_nodes.n__VA_OPT__) + maybe_va_opt_error (pfile); + + /* For -Wc++-compat, warn about use of C++ named operators. */ + if (node->flags & NODE_WARN_OPERATOR) + cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, + "identifier \"%s\" is a special operator name in C++", + NODE_NAME (node)); +} + +/* Helper function to scan an entire identifier beginning at + pfile->buffer->cur, and possibly containing extended characters (UCNs + and/or UTF-8). Returns the cpp_hashnode for the identifier on success, or + else nullptr, as well as a normalize_state so that normalization warnings + may be issued once the token lexing is complete. */ + +struct scan_id_result +{ + cpp_hashnode *node; + normalize_state nst; + + scan_id_result () + : node (nullptr) + { + nst = INITIAL_NORMALIZE_STATE; + } + + explicit operator bool () const { return node; } +}; + +static scan_id_result +scan_cur_identifier (cpp_reader *pfile) +{ + cpp_buffer *const buffer = pfile->buffer; + const uchar *const begin = buffer->cur; + scan_id_result result; + bool need_extended; + unsigned int hash = 0; + if (ISIDST (*buffer->cur)) + { + hash = HT_HASHSTEP (0, *buffer->cur); + ++buffer->cur; + while (ISIDNUM (*buffer->cur)) + { + hash = HT_HASHSTEP (hash, *buffer->cur); + ++buffer->cur; + } + NORMALIZE_STATE_UPDATE_IDNUM (&result.nst, buffer->cur[-1]); + need_extended = forms_identifier_p (pfile, false, &result.nst); + } + else + { + if (!forms_identifier_p (pfile, true, &result.nst)) + return result; + need_extended = true; + } + + if (need_extended) + { + do { + while (ISIDNUM (*buffer->cur)) + { + NORMALIZE_STATE_UPDATE_IDNUM (&result.nst, *buffer->cur); + ++buffer->cur; + } + } while (forms_identifier_p (pfile, false, &result.nst)); + + if (pfile->warn_bidi_p ()) + maybe_warn_bidi_on_close (pfile, buffer->cur); + + result.node = _cpp_interpret_identifier (pfile, begin, + buffer->cur - begin); + } + else + { + const size_t len = buffer->cur - begin; + hash = HT_HASHFINISH (hash, len); + result.node = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + begin, len, + hash, HT_ALLOC)); + } + + identifier_diagnostics_on_lex (pfile, result.node); + return result; +} + + /* Helper function to get the cpp_hashnode of the identifier BASE. */ static cpp_hashnode * lex_identifier_intern (cpp_reader *pfile, const uchar *base) @@ -1960,41 +2079,7 @@ lex_identifier_intern (cpp_reader *pfile, const uchar *base) hash = HT_HASHFINISH (hash, len); result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, base, len, hash, HT_ALLOC)); - - /* Rarely, identifiers require diagnostics when lexed. */ - if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) - && !pfile->state.skipping, 0)) - { - /* It is allowed to poison the same identifier twice. */ - if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) - cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", - NODE_NAME (result)); - - /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the - replacement list of a variadic macro. */ - if (result == pfile->spec_nodes.n__VA_ARGS__ - && !pfile->state.va_args_ok) - { - if (CPP_OPTION (pfile, cplusplus)) - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C++11 variadic macro"); - else - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C99 variadic macro"); - } - - if (result == pfile->spec_nodes.n__VA_OPT__) - maybe_va_opt_error (pfile); - - /* For -Wc++-compat, warn about use of C++ named operators. */ - if (result->flags & NODE_WARN_OPERATOR) - cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, - "identifier \"%s\" is a special operator name in C++", - NODE_NAME (result)); - } - + identifier_diagnostics_on_lex (pfile, result); return result; } @@ -2057,42 +2142,7 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, *spelling = result; } - /* Rarely, identifiers require diagnostics when lexed. */ - if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) - && !pfile->state.skipping, 0)) - { - /* It is allowed to poison the same identifier twice. */ - if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) - cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", - NODE_NAME (result)); - - /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the - replacement list of a variadic macro. */ - if (result == pfile->spec_nodes.n__VA_ARGS__ - && !pfile->state.va_args_ok) - { - if (CPP_OPTION (pfile, cplusplus)) - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C++11 variadic macro"); - else - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C99 variadic macro"); - } - - /* __VA_OPT__ should only appear in the replacement list of a - variadic macro. */ - if (result == pfile->spec_nodes.n__VA_OPT__) - maybe_va_opt_error (pfile); - - /* For -Wc++-compat, warn about use of C++ named operators. */ - if (result->flags & NODE_WARN_OPERATOR) - cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, - "identifier \"%s\" is a special operator name in C++", - NODE_NAME (result)); - } - + identifier_diagnostics_on_lex (pfile, result); return result; } @@ -2152,6 +2202,24 @@ create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, token->val.str.text = cpp_alloc_token_string (pfile, base, len); } +/* Like create_literal(), but construct it from two separate strings + which are concatenated. LEN2 may be 0 if no second string is + required. */ +static void +create_literal2 (cpp_reader *pfile, cpp_token *token, const uchar *base1, + unsigned int len1, const uchar *base2, unsigned int len2, + enum cpp_ttype type) +{ + token->type = type; + token->val.str.len = len1 + len2; + uchar *const dest = _cpp_unaligned_alloc (pfile, len1 + len2 + 1); + memcpy (dest, base1, len1); + if (len2) + memcpy (dest+len1, base2, len2); + dest[len1 + len2] = 0; + token->val.str.text = dest; +} + const uchar * cpp_alloc_token_string (cpp_reader *pfile, const unsigned char *ptr, unsigned len) @@ -2190,6 +2258,11 @@ struct lit_accum { rpos = NULL; return c; } + + void create_literal2 (cpp_reader *pfile, cpp_token *token, + const uchar *base1, unsigned int len1, + const uchar *base2, unsigned int len2, + enum cpp_ttype type); }; /* Subroutine of lex_raw_string: Append LEN chars from BASE to the buffer @@ -2232,45 +2305,31 @@ lit_accum::read_begin (cpp_reader *pfile) rpos = BUFF_FRONT (last); } -/* Returns true if a macro has been defined. - This might not work if compile with -save-temps, - or preprocess separately from compilation. */ - -static bool -is_macro(cpp_reader *pfile, const uchar *base) +/* Like create_literal2(), but also prepend all the accumulated data from + the lit_accum struct. */ +void +lit_accum::create_literal2 (cpp_reader *pfile, cpp_token *token, + const uchar *base1, unsigned int len1, + const uchar *base2, unsigned int len2, + enum cpp_ttype type) { - const uchar *cur = base; - if (! ISIDST (*cur)) - return false; - unsigned int hash = HT_HASHSTEP (0, *cur); - ++cur; - while (ISIDNUM (*cur)) + const unsigned int tot_len = accum + len1 + len2; + uchar *dest = _cpp_unaligned_alloc (pfile, tot_len + 1); + token->type = type; + token->val.str.len = tot_len; + token->val.str.text = dest; + for (_cpp_buff *buf = first; buf; buf = buf->next) { - hash = HT_HASHSTEP (hash, *cur); - ++cur; + size_t len = BUFF_FRONT (buf) - buf->base; + memcpy (dest, buf->base, len); + dest += len; } - hash = HT_HASHFINISH (hash, cur - base); - - cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, - base, cur - base, hash, HT_NO_INSERT)); - - return result && cpp_macro_p (result); -} - -/* Returns true if a literal suffix does not have the expected form - and is defined as a macro. */ - -static bool -is_macro_not_literal_suffix(cpp_reader *pfile, const uchar *base) -{ - /* User-defined literals outside of namespace std must start with a single - underscore, so assume anything of that form really is a UDL suffix. - We don't need to worry about UDLs defined inside namespace std because - their names are reserved, so cannot be used as macro names in valid - programs. */ - if (base[0] == '_' && base[1] != '_') - return false; - return is_macro (pfile, base); + memcpy (dest, base1, len1); + dest += len1; + if (len2) + memcpy (dest, base2, len2); + dest += len2; + *dest = '\0'; } /* Lexes a raw string. The stored string contains the spelling, @@ -2540,26 +2599,53 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) if (CPP_OPTION (pfile, user_literals)) { - /* If a string format macro, say from inttypes.h, is placed touching - a string literal it could be parsed as a C++11 user-defined string - literal thus breaking the program. */ - if (is_macro_not_literal_suffix (pfile, pos)) - { - /* Raise a warning, but do not consume subsequent tokens. */ - if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) - cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX, - token->src_loc, 0, - "invalid suffix on literal; C++11 requires " - "a space between literal and string macro"); - } - /* Grab user defined literal suffix. */ - else if (ISIDST (*pos)) - { - type = cpp_userdef_string_add_type (type); - ++pos; + const uchar *const suffix_begin = pos; + pfile->buffer->cur = pos; - while (ISIDNUM (*pos)) - ++pos; + if (const auto sr = scan_cur_identifier (pfile)) + { + /* If a string format macro, say from inttypes.h, is placed touching + a string literal it could be parsed as a C++11 user-defined + string literal thus breaking the program. User-defined literals + outside of namespace std must start with a single underscore, so + assume anything of that form really is a UDL suffix. We don't + need to worry about UDLs defined inside namespace std because + their names are reserved, so cannot be used as macro names in + valid programs. */ + if ((suffix_begin[0] != '_' || suffix_begin[1] == '_') + && cpp_macro_p (sr.node)) + { + /* Maybe raise a warning, but do not consume the tokens. */ + pfile->buffer->cur = suffix_begin; + if (CPP_OPTION (pfile, warn_literal_suffix) + && !pfile->state.skipping) + cpp_warning_with_line + (pfile, CPP_W_LITERAL_SUFFIX, + token->src_loc, 0, + "invalid suffix on literal; C++11 requires " + "a space between literal and string macro"); + } + else + { + type = cpp_userdef_string_add_type (type); + if (!accum.accum) + create_literal2 (pfile, token, base, + suffix_begin - base, + NODE_NAME (sr.node), + NODE_LEN (sr.node), + type); + else + { + accum.create_literal2 (pfile, token, base, + suffix_begin - base, + NODE_NAME (sr.node), + NODE_LEN (sr.node), + type); + _cpp_release_buff (pfile, accum.first); + } + warn_about_normalization (pfile, token, &sr.nst); + return; + } } } @@ -2569,21 +2655,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) create_literal (pfile, token, base, pos - base, type); else { - size_t extra_len = pos - base; - uchar *dest = _cpp_unaligned_alloc (pfile, accum.accum + extra_len + 1); - - token->type = type; - token->val.str.len = accum.accum + extra_len; - token->val.str.text = dest; - for (_cpp_buff *buf = accum.first; buf; buf = buf->next) - { - size_t len = BUFF_FRONT (buf) - buf->base; - memcpy (dest, buf->base, len); - dest += len; - } + accum.create_literal2 (pfile, token, base, pos - base, nullptr, 0, type); _cpp_release_buff (pfile, accum.first); - memcpy (dest, base, extra_len); - dest[extra_len] = '\0'; } } @@ -2687,39 +2760,57 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", (int) terminator); + pfile->buffer->cur = cur; + if (CPP_OPTION (pfile, user_literals)) { - /* If a string format macro, say from inttypes.h, is placed touching - a string literal it could be parsed as a C++11 user-defined string - literal thus breaking the program. */ - if (is_macro_not_literal_suffix (pfile, cur)) - { - /* Raise a warning, but do not consume subsequent tokens. */ - if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) - cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX, - token->src_loc, 0, - "invalid suffix on literal; C++11 requires " - "a space between literal and string macro"); - } - /* Grab user defined literal suffix. */ - else if (ISIDST (*cur)) - { - type = cpp_userdef_char_add_type (type); - type = cpp_userdef_string_add_type (type); - ++cur; + const uchar *const suffix_begin = cur; - while (ISIDNUM (*cur)) - ++cur; + if (const auto sr = scan_cur_identifier (pfile)) + { + /* If a string format macro, say from inttypes.h, is placed touching + a string literal it could be parsed as a C++11 user-defined + string literal thus breaking the program. User-defined literals + outside of namespace std must start with a single underscore, so + assume anything of that form really is a UDL suffix. We don't + need to worry about UDLs defined inside namespace std because + their names are reserved, so cannot be used as macro names in + valid programs. */ + if ((suffix_begin[0] != '_' || suffix_begin[1] == '_') + && cpp_macro_p (sr.node)) + { + /* Maybe raise a warning, but do not consume the tokens. */ + pfile->buffer->cur = suffix_begin; + if (CPP_OPTION (pfile, warn_literal_suffix) + && !pfile->state.skipping) + cpp_warning_with_line + (pfile, CPP_W_LITERAL_SUFFIX, + token->src_loc, 0, + "invalid suffix on literal; C++11 requires " + "a space between literal and string macro"); + } + else + { + /* Grab user defined literal suffix. */ + type = cpp_userdef_char_add_type (type); + type = cpp_userdef_string_add_type (type); + create_literal2 (pfile, token, base, suffix_begin - base, + NODE_NAME (sr.node), NODE_LEN (sr.node), type); + warn_about_normalization (pfile, token, &sr.nst); + return; + } } } else if (CPP_OPTION (pfile, cpp_warn_cxx11_compat) - && is_macro (pfile, cur) && !pfile->state.skipping) - cpp_warning_with_line (pfile, CPP_W_CXX11_COMPAT, - token->src_loc, 0, "C++11 requires a space " - "between string literal and macro"); + { + const auto sr = scan_cur_identifier (pfile); + if (sr && cpp_macro_p (sr.node)) + cpp_warning_with_line (pfile, CPP_W_CXX11_COMPAT, + token->src_loc, 0, "C++11 requires a space " + "between string literal and macro"); + } - pfile->buffer->cur = cur; create_literal (pfile, token, base, cur - base, type); } @@ -4091,7 +4182,7 @@ cpp_digraph2name (enum cpp_ttype type) } /* Write the spelling of an identifier IDENT, using UCNs, to BUFFER. - The buffer must already contain the enough space to hold the + The buffer must already contain enough space to hold the token's spelling. Returns a pointer to the character after the last character written. */ unsigned char * @@ -4113,7 +4204,7 @@ _cpp_spell_ident_ucns (unsigned char *buffer, cpp_hashnode *ident) } /* Write the spelling of a token TOKEN to BUFFER. The buffer must - already contain the enough space to hold the token's spelling. + already contain enough space to hold the token's spelling. Returns a pointer to the character after the last character written. FORSTRING is true if this is to be the spelling after translation phase 1 (with the original spelling of extended identifiers), false