/* CPP Library - lexical analysis.
   Copyright (C) 2000-2026 Free Software Foundation, Inc.
   Contributed by Per Bothner, 1994-95.
   Based on CCCP program by Paul Rubin, June 1986
   Adapted to ANSI C, Richard Stallman, Jan 1987
   Broken out to separate file, Zack Weinberg, Mar 2000

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"

enum spell_type
{
  SPELL_OPERATOR = 0,
  SPELL_IDENT,
  SPELL_LITERAL,
  SPELL_NONE
};

struct token_spelling
{
  enum spell_type category;
  const unsigned char *name;
};

static const unsigned char *const digraph_spellings[] =
{ UC"%:", UC"%:%:", UC"<:", UC":>", UC"<%", UC"%>" };

#define OP(e, s) { SPELL_OPERATOR, UC s  },
#define TK(e, s) { SPELL_ ## s,    UC #e },
static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE };
#undef OP
#undef TK

#define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
#define TOKEN_NAME(token) (token_spellings[(token)->type].name)

/* ISO 10646 defines the UCS codespace as the range 0-0x10FFFF inclusive.  */
#define UCS_LIMIT 0x10FFFF

static void add_line_note (cpp_buffer *, const uchar *, unsigned int);
static int skip_line_comment (cpp_reader *);
static void skip_whitespace (cpp_reader *, cppchar_t);
static void lex_string (cpp_reader *, cpp_token *, const uchar *);
static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t);
static void store_comment (cpp_reader *, cpp_token *);
static void create_literal (cpp_reader *, cpp_token *, const uchar *,
			    unsigned int, enum cpp_ttype);
static bool warn_in_comment (cpp_reader *, _cpp_line_note *);
static int name_p (cpp_reader *, const cpp_string *);
static tokenrun *next_tokenrun (tokenrun *);

static _cpp_buff *new_buff (size_t);


/* Utility routine:

   Compares, the token TOKEN to the NUL-terminated string STRING.
   TOKEN must be a CPP_NAME.  Returns 1 for equal, 0 for unequal.  */
int
cpp_ideq (const cpp_token *token, const char *string)
{
  if (token->type != CPP_NAME)
    return 0;

  return !ustrcmp (NODE_NAME (token->val.node.node), (const uchar *) string);
}

/* Record a note TYPE at byte POS into the current cleaned logical
   line.  */
static void
add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)
{
  if (buffer->notes_used == buffer->notes_cap)
    {
      buffer->notes_cap = buffer->notes_cap * 2 + 200;
      buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes,
                                  buffer->notes_cap);
    }

  buffer->notes[buffer->notes_used].pos = pos;
  buffer->notes[buffer->notes_used].type = type;
  buffer->notes_used++;
}


/* Fast path to find line special characters using optimized character
   scanning algorithms.  Anything complicated falls back to the slow
   path below.  Since this loop is very hot it's worth doing these kinds
   of optimizations.

   One of the paths through the ifdefs should provide

     const uchar *search_line_fast (const uchar *s, const uchar *end);

   Between S and END, search for \n, \r, \\, ?.  Return a pointer to
   the found character.

   Note that the last character of the buffer is *always* a newline,
   as forced by _cpp_convert_input.  This fact can be used to avoid
   explicitly looking for the end of the buffer.  */

/* Configure gives us an ifdef test.  */
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif

/* We'd like the largest integer that fits into a register.  There's nothing
   in <stdint.h> that gives us that.  For most hosts this is unsigned long,
   but MS decided on an LLP64 model.  Thankfully when building with GCC we
   can get the "real" word size.  */
#ifdef __GNUC__
typedef unsigned int word_type __attribute__((__mode__(__word__)));
#else
typedef unsigned long word_type;
#endif

/* The code below is only expecting sizes 4 or 8.
   Die at compile-time if this expectation is violated.  */
typedef char check_word_type_size
  [(sizeof(word_type) == 8 || sizeof(word_type) == 4) * 2 - 1];

/* Return X with the first N bytes forced to values that won't match one
   of the interesting characters.  Note that NUL is not interesting.  */

static inline word_type
acc_char_mask_misalign (word_type val, unsigned int n)
{
  word_type mask = -1;
  if (WORDS_BIGENDIAN)
    mask >>= n * 8;
  else
    mask <<= n * 8;
  return val & mask;
}

/* Return X replicated to all byte positions within WORD_TYPE.  */

static inline word_type
acc_char_replicate (uchar x)
{
  word_type ret;

  ret = (x << 24) | (x << 16) | (x << 8) | x;
  if (sizeof(word_type) == 8)
    ret = (ret << 16 << 16) | ret;
  return ret;
}

/* Return non-zero if some byte of VAL is (probably) C.  */

static inline word_type
acc_char_cmp (word_type val, word_type c)
{
#if defined(__GNUC__) && defined(__alpha__)
  /* We can get exact results using a compare-bytes instruction.
     Get (val == c) via (0 >= (val ^ c)).  */
  return __builtin_alpha_cmpbge (0, val ^ c);
#else
  word_type magic = 0x7efefefeU;
  if (sizeof(word_type) == 8)
    magic = (magic << 16 << 16) | 0xfefefefeU;
  magic |= 1;

  val ^= c;
  return ((val + magic) ^ ~val) & ~magic;
#endif
}

/* Given the result of acc_char_cmp is non-zero, return the index of
   the found character.  If this was a false positive, return -1.  */

static inline int
acc_char_index (word_type cmp ATTRIBUTE_UNUSED,
		word_type val ATTRIBUTE_UNUSED)
{
#if defined(__GNUC__) && defined(__alpha__) && !WORDS_BIGENDIAN
  /* The cmpbge instruction sets *bits* of the result corresponding to
     matches in the bytes with no false positives.  */
  return __builtin_ctzl (cmp);
#else
  unsigned int i;

  /* ??? It would be nice to force unrolling here,
     and have all of these constants folded.  */
  for (i = 0; i < sizeof(word_type); ++i)
    {
      uchar c;
      if (WORDS_BIGENDIAN)
	c = (val >> (sizeof(word_type) - i - 1) * 8) & 0xff;
      else
	c = (val >> i * 8) & 0xff;

      if (c == '\n' || c == '\r' || c == '\\' || c == '?')
	return i;
    }

  return -1;
#endif
}

/* A version of the fast scanner using bit fiddling techniques.

   For 32-bit words, one would normally perform 16 comparisons and
   16 branches.  With this algorithm one performs 24 arithmetic
   operations and one branch.  Whether this is faster with a 32-bit
   word size is going to be somewhat system dependent.

   For 64-bit words, we eliminate twice the number of comparisons
   and branches without increasing the number of arithmetic operations.
   It's almost certainly going to be a win with 64-bit word size.  */

static inline const uchar *
search_line_acc_char (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  const word_type repl_nl = acc_char_replicate ('\n');
  const word_type repl_cr = acc_char_replicate ('\r');
  const word_type repl_bs = acc_char_replicate ('\\');
  const word_type repl_qm = acc_char_replicate ('?');

  unsigned int misalign;
  const word_type *p;
  word_type val, t;

  /* Align the buffer.  Mask out any bytes from before the beginning.  */
  p = (word_type *)((uintptr_t)s & -sizeof(word_type));
  val = *p;
  misalign = (uintptr_t)s & (sizeof(word_type) - 1);
  if (misalign)
    val = acc_char_mask_misalign (val, misalign);

  /* Main loop.  */
  while (1)
    {
      t  = acc_char_cmp (val, repl_nl);
      t |= acc_char_cmp (val, repl_cr);
      t |= acc_char_cmp (val, repl_bs);
      t |= acc_char_cmp (val, repl_qm);

      if (__builtin_expect (t != 0, 0))
	{
	  int i = acc_char_index (t, val);
	  if (i >= 0)
	    return (const uchar *)p + i;
	}

      val = *++p;
    }
}

/* Disable on Solaris 2/x86 until the following problem can be properly
   autoconfed:

   The Solaris 10+ assembler tags objects with the instruction set
   extensions used, so SSE4.2 executables cannot run on machines that
   don't support that extension.  */

#if (GCC_VERSION >= 4005) && (__GNUC__ >= 5 || !defined(__PIC__)) && (defined(__i386__) || defined(__x86_64__)) && !(defined(__sun__) && defined(__svr4__))

/* Replicated character data to be shared between implementations.
   Recall that outside of a context with vector support we can't
   define compatible vector types, therefore these are all defined
   in terms of raw characters.  */
static const char repl_chars[4][16] __attribute__((aligned(16))) = {
  { '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
    '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' },
  { '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r',
    '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r' },
  { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\',
    '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' },
  { '?', '?', '?', '?', '?', '?', '?', '?',
    '?', '?', '?', '?', '?', '?', '?', '?' },
};


/* A version of the fast scanner using SSE2 vectorized byte compare insns.  */

static inline const uchar *
#ifndef __SSE2__
__attribute__((__target__("sse2")))
#endif
search_line_sse2 (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  typedef char v16qi __attribute__ ((__vector_size__ (16)));

  const v16qi repl_nl = *(const v16qi *)repl_chars[0];
  const v16qi repl_cr = *(const v16qi *)repl_chars[1];
  const v16qi repl_bs = *(const v16qi *)repl_chars[2];
  const v16qi repl_qm = *(const v16qi *)repl_chars[3];

  unsigned int misalign, found, mask;
  const v16qi *p;
  v16qi data, t;

  /* Align the source pointer.  */
  misalign = (uintptr_t)s & 15;
  p = (const v16qi *)((uintptr_t)s & -16);
  data = *p;

  /* Create a mask for the bytes that are valid within the first
     16-byte block.  The Idea here is that the AND with the mask
     within the loop is "free", since we need some AND or TEST
     insn in order to set the flags for the branch anyway.  */
  mask = -1u << misalign;

  /* Main loop processing 16 bytes at a time.  */
  goto start;
  do
    {
      data = *++p;
      mask = -1;

    start:
      t  = data == repl_nl;
      t |= data == repl_cr;
      t |= data == repl_bs;
      t |= data == repl_qm;
      found = __builtin_ia32_pmovmskb128 (t);
      found &= mask;
    }
  while (!found);

  /* FOUND contains 1 in bits for which we matched a relevant
     character.  Conversion to the byte index is trivial.  */
  found = __builtin_ctz(found);
  return (const uchar *)p + found;
}

#ifdef HAVE_SSSE3
/* A version of the fast scanner using SSSE3 shuffle (PSHUFB) insns.  */

static inline const uchar *
#ifndef __SSSE3__
__attribute__((__target__("ssse3")))
#endif
search_line_ssse3 (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  typedef char v16qi __attribute__ ((__vector_size__ (16)));
  typedef v16qi v16qi_u __attribute__ ((__aligned__ (1)));
  /* Helper vector for pshufb-based matching:
     each character C we're searching for is at position (C % 16).  */
  v16qi lut = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, '\\', '\r', 0, '?' };
  static_assert('\n' == 10 && '\r' == 13 && '\\' == 92 && '?' == 63,
                "host character encoding is ASCII");

  v16qi d1, d2, t1, t2;
  /* Unaligned loads, potentially using padding after the final newline.  */
  static_assert (CPP_BUFFER_PADDING >= 64, "");
  d1 = *(const v16qi_u *)s;
  d2 = *(const v16qi_u *)(s + 16);
  unsigned m1, m2, found;
  /* Process two 16-byte chunks per iteration.  */
  do
    {
      t1 = __builtin_ia32_pshufb128 (lut, d1);
      t2 = __builtin_ia32_pshufb128 (lut, d2);
      m1 = __builtin_ia32_pmovmskb128 (t1 == d1);
      m2 = __builtin_ia32_pmovmskb128 (t2 == d2);
      s += 32;
      d1 = *(const v16qi_u *)s;
      d2 = *(const v16qi_u *)(s + 16);
      found = m1 + (m2 << 16);
    }
  while (!found);
  /* Prefer to compute 's - 32' here, not spend an extra instruction
     to make a copy of the previous value of 's' in the loop.  */
  __asm__ ("" : "+r"(s));
  return s - 32 + __builtin_ctz (found);
}

#else
/* Work around out-dated assemblers without SSSE3 support.  */
#define search_line_ssse3 search_line_sse2
#endif

#ifdef __SSSE3__
/* No need for CPU probing, just use the best available variant.  */
#define search_line_fast search_line_ssse3
#else
/* Check the CPU capabilities.  */

#include "../gcc/config/i386/cpuid.h"

typedef const uchar * (*search_line_fast_type) (const uchar *, const uchar *);
static search_line_fast_type search_line_fast
#if defined(__SSE2__)
 = search_line_sse2;
#else
 = search_line_acc_char;
#endif

#define HAVE_init_vectorized_lexer 1
static inline void
init_vectorized_lexer (void)
{
  unsigned ax, bx, cx, dx;

  if (!__get_cpuid (1, &ax, &bx, &cx, &dx))
    return;

  if (cx & bit_SSSE3)
    search_line_fast = search_line_ssse3;
  else if (dx & bit_SSE2)
    search_line_fast = search_line_sse2;
}
#endif

#elif (GCC_VERSION >= 4005) && defined(_ARCH_PWR8) && defined(__ALTIVEC__)

/* A vection of the fast scanner using AltiVec vectorized byte compares
   and VSX unaligned loads (when VSX is available).  This is otherwise
   the same as the AltiVec version.  */

ATTRIBUTE_NO_SANITIZE_UNDEFINED
static const uchar *
search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  typedef __attribute__((altivec(vector))) unsigned char vc;

  const vc repl_nl = {
    '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
    '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'
  };
  const vc repl_cr = {
    '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r',
    '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r'
  };
  const vc repl_bs = {
    '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\',
    '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\'
  };
  const vc repl_qm = {
    '?', '?', '?', '?', '?', '?', '?', '?',
    '?', '?', '?', '?', '?', '?', '?', '?',
  };
  const vc zero = { 0 };

  vc data, t;

  /* Main loop processing 16 bytes at a time.  */
  do
    {
      vc m_nl, m_cr, m_bs, m_qm;

      data = __builtin_vec_vsx_ld (0, s);
      s += 16;

      m_nl = (vc) __builtin_vec_cmpeq(data, repl_nl);
      m_cr = (vc) __builtin_vec_cmpeq(data, repl_cr);
      m_bs = (vc) __builtin_vec_cmpeq(data, repl_bs);
      m_qm = (vc) __builtin_vec_cmpeq(data, repl_qm);
      t = (m_nl | m_cr) | (m_bs | m_qm);

      /* T now contains 0xff in bytes for which we matched one of the relevant
	 characters.  We want to exit the loop if any byte in T is non-zero.
	 Below is the expansion of vec_any_ne(t, zero).  */
    }
  while (!__builtin_vec_vcmpeq_p(/*__CR6_LT_REV*/3, t, zero));

  /* Restore s to to point to the 16 bytes we just processed.  */
  s -= 16;

  {
#define N  (sizeof(vc) / sizeof(long))

    union {
      vc v;
      /* Statically assert that N is 2 or 4.  */
      unsigned long l[(N == 2 || N == 4) ? N : -1];
    } u;
    unsigned long l, i = 0;

    u.v = t;

    /* Find the first word of T that is non-zero.  */
    switch (N)
      {
      case 4:
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	/* FALLTHRU */
      case 2:
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	l = u.l[i];
      }

    /* L now contains 0xff in bytes for which we matched one of the
       relevant characters.  We can find the byte index by finding
       its bit index and dividing by 8.  */
#ifdef __BIG_ENDIAN__
    l = __builtin_clzl(l) >> 3;
#else
    l = __builtin_ctzl(l) >> 3;
#endif
    return s + l;

#undef N
  }
}

#elif (GCC_VERSION >= 4005) && defined(__ALTIVEC__) && defined (__BIG_ENDIAN__)

/* A vection of the fast scanner using AltiVec vectorized byte compares.
   This cannot be used for little endian because vec_lvsl/lvsr are
   deprecated for little endian and the code won't work properly.  */
/* ??? Unfortunately, attribute(target("altivec")) is not yet supported,
   so we can't compile this function without -maltivec on the command line
   (or implied by some other switch).  */

static const uchar *
search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  typedef __attribute__((altivec(vector))) unsigned char vc;

  const vc repl_nl = {
    '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
    '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'
  };
  const vc repl_cr = {
    '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r',
    '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r'
  };
  const vc repl_bs = {
    '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\',
    '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\'
  };
  const vc repl_qm = {
    '?', '?', '?', '?', '?', '?', '?', '?',
    '?', '?', '?', '?', '?', '?', '?', '?',
  };
  const vc ones = {
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1,
  };
  const vc zero = { 0 };

  vc data, mask, t;

  /* Altivec loads automatically mask addresses with -16.  This lets us
     issue the first load as early as possible.  */
  data = __builtin_vec_ld(0, (const vc *)s);

  /* Discard bytes before the beginning of the buffer.  Do this by
     beginning with all ones and shifting in zeros according to the
     mis-alignment.  The LVSR instruction pulls the exact shift we
     want from the address.  */
  mask = __builtin_vec_lvsr(0, s);
  mask = __builtin_vec_perm(zero, ones, mask);
  data &= mask;

  /* While altivec loads mask addresses, we still need to align S so
     that the offset we compute at the end is correct.  */
  s = (const uchar *)((uintptr_t)s & -16);

  /* Main loop processing 16 bytes at a time.  */
  goto start;
  do
    {
      vc m_nl, m_cr, m_bs, m_qm;

      s += 16;
      data = __builtin_vec_ld(0, (const vc *)s);

    start:
      m_nl = (vc) __builtin_vec_cmpeq(data, repl_nl);
      m_cr = (vc) __builtin_vec_cmpeq(data, repl_cr);
      m_bs = (vc) __builtin_vec_cmpeq(data, repl_bs);
      m_qm = (vc) __builtin_vec_cmpeq(data, repl_qm);
      t = (m_nl | m_cr) | (m_bs | m_qm);

      /* T now contains 0xff in bytes for which we matched one of the relevant
	 characters.  We want to exit the loop if any byte in T is non-zero.
	 Below is the expansion of vec_any_ne(t, zero).  */
    }
  while (!__builtin_vec_vcmpeq_p(/*__CR6_LT_REV*/3, t, zero));

  {
#define N  (sizeof(vc) / sizeof(long))

    union {
      vc v;
      /* Statically assert that N is 2 or 4.  */
      unsigned long l[(N == 2 || N == 4) ? N : -1];
    } u;
    unsigned long l, i = 0;

    u.v = t;

    /* Find the first word of T that is non-zero.  */
    switch (N)
      {
      case 4:
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	/* FALLTHROUGH */
      case 2:
	l = u.l[i++];
	if (l != 0)
	  break;
	s += sizeof(unsigned long);
	l = u.l[i];
      }

    /* L now contains 0xff in bytes for which we matched one of the
       relevant characters.  We can find the byte index by finding
       its bit index and dividing by 8.  */
    l = __builtin_clzl(l) >> 3;
    return s + l;

#undef N
  }
}

#elif defined (__ARM_NEON) && defined (__ARM_64BIT_STATE)
#include "arm_neon.h"

/* This doesn't have to be the exact page size, but no system may use
   a size smaller than this.  ARMv8 requires a minimum page size of
   4k.  The impact of being conservative here is a small number of
   cases will take the slightly slower entry path into the main
   loop.  */

#define AARCH64_MIN_PAGE_SIZE 4096

static const uchar *
search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  const uint8x16_t repl_nl = vdupq_n_u8 ('\n');
  const uint8x16_t repl_cr = vdupq_n_u8 ('\r');
  const uint8x16_t repl_bs = vdupq_n_u8 ('\\');
  const uint8x16_t repl_qm = vdupq_n_u8 ('?');
  const uint8x16_t xmask = (uint8x16_t) vdupq_n_u64 (0x8040201008040201ULL);

#ifdef __ARM_BIG_ENDIAN
  const int16x8_t shift = {8, 8, 8, 8, 0, 0, 0, 0};
#else
  const int16x8_t shift = {0, 0, 0, 0, 8, 8, 8, 8};
#endif

  unsigned int found;
  const uint8_t *p;
  uint8x16_t data;
  uint8x16_t t;
  uint16x8_t m;
  uint8x16_t u, v, w;

  /* Align the source pointer.  */
  p = (const uint8_t *)((uintptr_t)s & -16);

  /* Assuming random string start positions, with a 4k page size we'll take
     the slow path about 0.37% of the time.  */
  if (__builtin_expect ((AARCH64_MIN_PAGE_SIZE
			 - (((uintptr_t) s) & (AARCH64_MIN_PAGE_SIZE - 1)))
			< 16, 0))
    {
      /* Slow path: the string starts near a possible page boundary.  */
      uint32_t misalign, mask;

      misalign = (uintptr_t)s & 15;
      mask = (-1u << misalign) & 0xffff;
      data = vld1q_u8 (p);
      t = vceqq_u8 (data, repl_nl);
      u = vceqq_u8 (data, repl_cr);
      v = vorrq_u8 (t, vceqq_u8 (data, repl_bs));
      w = vorrq_u8 (u, vceqq_u8 (data, repl_qm));
      t = vorrq_u8 (v, w);
      t = vandq_u8 (t, xmask);
      m = vpaddlq_u8 (t);
      m = vshlq_u16 (m, shift);
      found = vaddvq_u16 (m);
      found &= mask;
      if (found)
	return (const uchar*)p + __builtin_ctz (found);
    }
  else
    {
      data = vld1q_u8 ((const uint8_t *) s);
      t = vceqq_u8 (data, repl_nl);
      u = vceqq_u8 (data, repl_cr);
      v = vorrq_u8 (t, vceqq_u8 (data, repl_bs));
      w = vorrq_u8 (u, vceqq_u8 (data, repl_qm));
      t = vorrq_u8 (v, w);
      if (__builtin_expect (vpaddd_u64 ((uint64x2_t)t) != 0, 0))
	goto done;
    }

  do
    {
      p += 16;
      data = vld1q_u8 (p);
      t = vceqq_u8 (data, repl_nl);
      u = vceqq_u8 (data, repl_cr);
      v = vorrq_u8 (t, vceqq_u8 (data, repl_bs));
      w = vorrq_u8 (u, vceqq_u8 (data, repl_qm));
      t = vorrq_u8 (v, w);
    } while (!vpaddd_u64 ((uint64x2_t)t));

done:
  /* Now that we've found the terminating substring, work out precisely where
     we need to stop.  */
  t = vandq_u8 (t, xmask);
  m = vpaddlq_u8 (t);
  m = vshlq_u16 (m, shift);
  found = vaddvq_u16 (m);
  return (((((uintptr_t) p) < (uintptr_t) s) ? s : (const uchar *)p)
	  + __builtin_ctz (found));
}

#elif defined (__ARM_NEON)
#include "arm_neon.h"

static const uchar *
search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
{
  const uint8x16_t repl_nl = vdupq_n_u8 ('\n');
  const uint8x16_t repl_cr = vdupq_n_u8 ('\r');
  const uint8x16_t repl_bs = vdupq_n_u8 ('\\');
  const uint8x16_t repl_qm = vdupq_n_u8 ('?');
  const uint8x16_t xmask = (uint8x16_t) vdupq_n_u64 (0x8040201008040201ULL);

  unsigned int misalign, found, mask;
  const uint8_t *p;
  uint8x16_t data;

  /* Align the source pointer.  */
  misalign = (uintptr_t)s & 15;
  p = (const uint8_t *)((uintptr_t)s & -16);
  data = vld1q_u8 (p);

  /* Create a mask for the bytes that are valid within the first
     16-byte block.  The Idea here is that the AND with the mask
     within the loop is "free", since we need some AND or TEST
     insn in order to set the flags for the branch anyway.  */
  mask = (-1u << misalign) & 0xffff;

  /* Main loop, processing 16 bytes at a time.  */
  goto start;

  do
    {
      uint8x8_t l;
      uint16x4_t m;
      uint32x2_t n;
      uint8x16_t t, u, v, w;

      p += 16;
      data = vld1q_u8 (p);
      mask = 0xffff;

    start:
      t = vceqq_u8 (data, repl_nl);
      u = vceqq_u8 (data, repl_cr);
      v = vorrq_u8 (t, vceqq_u8 (data, repl_bs));
      w = vorrq_u8 (u, vceqq_u8 (data, repl_qm));
      t = vandq_u8 (vorrq_u8 (v, w), xmask);
      l = vpadd_u8 (vget_low_u8 (t), vget_high_u8 (t));
      m = vpaddl_u8 (l);
      n = vpaddl_u16 (m);

      found = vget_lane_u32 ((uint32x2_t) vorr_u64 ((uint64x1_t) n,
	      vshr_n_u64 ((uint64x1_t) n, 24)), 0);
      found &= mask;
    }
  while (!found);

  /* FOUND contains 1 in bits for which we matched a relevant
     character.  Conversion to the byte index is trivial.  */
  found = __builtin_ctz (found);
  return (const uchar *)p + found;
}

#else

/* We only have one accelerated alternative.  Use a direct call so that
   we encourage inlining.  */

#define search_line_fast  search_line_acc_char

#endif

/* Initialize the lexer if needed.  */

void
_cpp_init_lexer (void)
{
#ifdef HAVE_init_vectorized_lexer
  init_vectorized_lexer ();
#endif
}

/* Look for leading whitespace style issues on lines which don't contain
   just whitespace.
   For -Wleading-whitespace=spaces report if such lines contain leading
   whitespace other than spaces.
   For -Wleading-whitespace=tabs report if such lines contain leading
   whitespace other than tabs.
   For -Wleading-whitespace=blanks report if such lines contain leading
   whitespace other than spaces+tabs, or contain in it tab after space,
   or -ftabstop= or more consecutive spaces.  */

static void
find_leading_whitespace_issues (cpp_reader *pfile, const uchar *s)
{
  const unsigned char *p = NULL;
  uchar type = 'L';
  switch (CPP_OPTION (pfile, cpp_warn_leading_whitespace))
    {
    case 1: /* spaces */
      while (*s == ' ')
	++s;
      break;
    case 2: /* tabs */
      while (*s == '\t')
	++s;
      break;
    case 3: /* blanks */
      while (*s == '\t')
	++s;
      int n;
      n = CPP_OPTION (pfile, cpp_tabstop);
      while (*s == ' ')
	{
	  if (--n == 0)
	    break;
	  ++s;
	}
      if (*s == '\t')
	type = 'T'; /* Tab after space.  */
      else if (*s == ' ')
	type = 'S'; /* Too many spaces.  */
      break;
    default:
      abort ();
    }
  if (!IS_NVSPACE (*s))
    return;
  p = s++;
  while (IS_NVSPACE (*s))
    ++s;
  if (*s != '\n' && *s != '\r')
    add_line_note (pfile->buffer, p, type);
}

/* Returns with a logical line that contains no escaped newlines or
   trigraphs.  This is a time-critical inner loop.  */
void
_cpp_clean_line (cpp_reader *pfile)
{
  cpp_buffer *buffer;
  const uchar *s;
  uchar c, *d, *p;

  buffer = pfile->buffer;
  buffer->cur_note = buffer->notes_used = 0;
  buffer->cur = buffer->line_base = buffer->next_line;
  buffer->need_line = false;
  s = buffer->next_line;

  if (!buffer->from_stage3)
    {
      const uchar *pbackslash = NULL;
      bool leading_ws_done = true;

      if (CPP_OPTION (pfile, cpp_warn_leading_whitespace))
	find_leading_whitespace_issues (pfile, s);

      /* Fast path.  This is the common case of an un-escaped line with
	 no trigraphs.  The primary win here is by not writing any
	 data back to memory until we have to.  */
      while (1)
	{
	  /* Perform an optimized search for \n, \r, \\, ?.  */
	  s = search_line_fast (s, buffer->rlimit);

	  c = *s;
	  if (c == '\\')
	    {
	      /* Record the location of the backslash and continue.  */
	      pbackslash = s++;
	    }
	  else if (__builtin_expect (c == '?', 0))
	    {
	      if (__builtin_expect (s[1] == '?', false)
		   && _cpp_trigraph_map[s[2]])
		{
		  /* Have a trigraph.  We may or may not have to convert
		     it.  Add a line note regardless, for -Wtrigraphs.  */
		  add_line_note (buffer, s, s[2]);
		  if (CPP_OPTION (pfile, trigraphs))
		    {
		      /* We do, and that means we have to switch to the
		         slow path.  */
		      d = (uchar *) s;
		      *d = _cpp_trigraph_map[s[2]];
		      s += 2;
		      goto slow_path;
		    }
		}
	      /* Not a trigraph.  Continue on fast-path.  */
	      s++;
	    }
	  else
	    break;
	}

      /* This must be \r or \n.  We're either done, or we'll be forced
	 to write back to the buffer and continue on the slow path.  */
      d = (uchar *) s;

      if (__builtin_expect (s == buffer->rlimit, false))
	goto done;

      /* DOS line ending? */
      if (__builtin_expect (c == '\r', false) && s[1] == '\n')
	{
	  s++;
	  if (s == buffer->rlimit)
	    goto done;
	}

      if (__builtin_expect (pbackslash == NULL, true))
	goto done;

      /* Check for escaped newline.  */
      p = d;
      while (is_nvspace (p[-1]))
	p--;
      if (p - 1 != pbackslash)
	goto done;

      /* Have an escaped newline; process it and proceed to
	 the slow path.  */
      add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
      d = p - 2;
      buffer->next_line = p - 1;
      leading_ws_done = false;

    slow_path:
      while (1)
	{
	  c = *++s;
	  *++d = c;

	  if (c == '\n' || c == '\r')
	    {
	      if (CPP_OPTION (pfile, cpp_warn_leading_whitespace)
		  && !leading_ws_done)
		find_leading_whitespace_issues (pfile, buffer->next_line);

	      /* Handle DOS line endings.  */
	      if (c == '\r' && s != buffer->rlimit && s[1] == '\n')
		s++;
	      if (s == buffer->rlimit)
		break;

	      /* Escaped?  */
	      p = d;
	      while (p != buffer->next_line && is_nvspace (p[-1]))
		p--;
	      if (p == buffer->next_line || p[-1] != '\\')
		break;

	      add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
	      d = p - 2;
	      buffer->next_line = p - 1;
	      leading_ws_done = false;
	    }
	  else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
	    {
	      if (CPP_OPTION (pfile, cpp_warn_leading_whitespace)
		  && !leading_ws_done)
		{
		  find_leading_whitespace_issues (pfile, buffer->next_line);
		  leading_ws_done = true;
		}

	      /* Add a note regardless, for the benefit of -Wtrigraphs.  */
	      add_line_note (buffer, d, s[2]);
	      if (CPP_OPTION (pfile, trigraphs))
		{
		  *d = _cpp_trigraph_map[s[2]];
		  s += 2;
		}
	    }
	}
     done:
      if (d > buffer->next_line
	  && CPP_OPTION (pfile, cpp_warn_trailing_whitespace))
	switch (CPP_OPTION (pfile, cpp_warn_trailing_whitespace))
	  {
	  case 1:
	    if (ISBLANK (d[-1]))
	      add_line_note (buffer, d - 1, 'W');
	    break;
	  case 2:
	    if (IS_NVSPACE (d[-1]) && d[-1])
	      add_line_note (buffer, d - 1, 'W');
	    break;
	  }
    }
  else
    {
      while (*s != '\n' && *s != '\r')
	s++;
      d = (uchar *) s;

      /* Handle DOS line endings.  */
      if (*s == '\r' && s + 1 != buffer->rlimit && s[1] == '\n')
	s++;
    }

  *d = '\n';
  /* A sentinel note that should never be processed.  */
  add_line_note (buffer, d + 1, '\n');
  buffer->next_line = s + 1;
}

template <bool lexing_raw_string>
static bool get_fresh_line_impl (cpp_reader *pfile);

/* Return true if the trigraph indicated by NOTE should be warned
   about in a comment.  */
static bool
warn_in_comment (cpp_reader *pfile, _cpp_line_note *note)
{
  const uchar *p;

  /* Within comments we don't warn about trigraphs, unless the
     trigraph forms an escaped newline, as that may change
     behavior.  */
  if (note->type != '/')
    return false;

  /* If -trigraphs, then this was an escaped newline iff the next note
     is coincident.  */
  if (CPP_OPTION (pfile, trigraphs))
    return note[1].pos == note->pos;

  /* Otherwise, see if this forms an escaped newline.  */
  p = note->pos + 3;
  while (is_nvspace (*p))
    p++;

  /* There might have been escaped newlines between the trigraph and the
     newline we found.  Hence the position test.  */
  return (*p == '\n' && p < note[1].pos);
}

/* Process the notes created by add_line_note as far as the current
   location.  */
void
_cpp_process_line_notes (cpp_reader *pfile, int in_comment)
{
  cpp_buffer *buffer = pfile->buffer;

  for (;;)
    {
      _cpp_line_note *note = &buffer->notes[buffer->cur_note];
      unsigned int col;

      if (note->pos > buffer->cur)
	break;

      buffer->cur_note++;
      col = CPP_BUF_COLUMN (buffer, note->pos + 1);

      if (note->type == '\\' || note->type == ' ')
	{
	  if (note->type == ' ')
	    {
	      if (!in_comment)
		cpp_error_with_line (pfile, CPP_DL_WARNING,
				     pfile->line_table->highest_line, col,
				     "backslash and newline separated by "
				     "space");
	      else if (CPP_OPTION (pfile, cpp_warn_trailing_whitespace))
		cpp_warning_with_line (pfile, CPP_W_TRAILING_WHITESPACE,
				       pfile->line_table->highest_line, col,
				       "trailing whitespace");
	    }

	  if (buffer->next_line > buffer->rlimit)
	    {
	      cpp_error_with_line (pfile, CPP_DL_PEDWARN,
				   pfile->line_table->highest_line, col,
				   "backslash-newline at end of file");
	      /* Prevent "no newline at end of file" warning.  */
	      buffer->next_line = buffer->rlimit;
	    }

	  buffer->line_base = note->pos;
	  CPP_INCREMENT_LINE (pfile, 0);
	}
      else if (_cpp_trigraph_map[note->type])
	{
	  if (CPP_OPTION (pfile, warn_trigraphs)
	      && (!in_comment || warn_in_comment (pfile, note)))
	    {
	      if (CPP_OPTION (pfile, trigraphs))
		cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS,
                                       pfile->line_table->highest_line, col,
				       "trigraph %<??%c%> converted to %<%c%>",
				       note->type,
				       (int) _cpp_trigraph_map[note->type]);
	      else
		cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS,
				       pfile->line_table->highest_line, col,
				       "trigraph %<??%c%> ignored, use "
				       "%<-trigraphs%> to enable", note->type);
	    }
	}
      else if (note->type == 'W')
	cpp_warning_with_line (pfile, CPP_W_TRAILING_WHITESPACE,
			       pfile->line_table->highest_line, col,
			       "trailing whitespace");
      else if (note->type == 'S')
	cpp_warning_with_line (pfile, CPP_W_LEADING_WHITESPACE,
			       pfile->line_table->highest_line, col,
			       "too many consecutive spaces in leading "
			       "whitespace");
      else if (note->type == 'T')
	cpp_warning_with_line (pfile, CPP_W_LEADING_WHITESPACE,
			       pfile->line_table->highest_line, col,
			       "tab after space in leading whitespace");
      else if (note->type == 'L')
	switch (CPP_OPTION (pfile, cpp_warn_leading_whitespace))
	  {
	  case 1:
	    cpp_warning_with_line (pfile, CPP_W_LEADING_WHITESPACE,
				   pfile->line_table->highest_line, col,
				   "whitespace other than spaces in leading "
				   "whitespace");
	    break;
	  case 2:
	    cpp_warning_with_line (pfile, CPP_W_LEADING_WHITESPACE,
				   pfile->line_table->highest_line, col,
				   "whitespace other than tabs in leading "
				   "whitespace");
	    break;
	  case 3:
	    cpp_warning_with_line (pfile, CPP_W_LEADING_WHITESPACE,
				   pfile->line_table->highest_line, col,
				   "whitespace other than spaces and tabs in "
				   "leading whitespace");
	    break;
	  default:
	    abort ();
	  }
      else if (note->type == 0)
	/* Already processed in lex_raw_string.  */;
      else
	abort ();
    }
}

namespace bidi {
  enum class kind {
    NONE, LRE, RLE, LRO, RLO, LRI, RLI, FSI, PDF, PDI, LTR, RTL
  };

  /* All the UTF-8 encodings of bidi characters start with E2.  */
  constexpr uchar utf8_start = 0xe2;

  struct context
  {
    context () {}
    context (location_t loc, kind k, bool pdf, bool ucn)
    : m_loc (loc), m_kind (k), m_pdf (pdf), m_ucn (ucn)
    {
    }

    kind get_pop_kind () const
    {
      return m_pdf ? kind::PDF : kind::PDI;
    }
    bool ucn_p () const
    {
      return m_ucn;
    }

    location_t m_loc;
    kind m_kind;
    unsigned m_pdf : 1;
    unsigned m_ucn : 1;
  };

  /* A vector holding currently open bidi contexts.  We use a char for
     each context, its LSB is 1 if it represents a PDF context, 0 if it
     represents a PDI context.  The next bit is 1 if this context was open
     by a bidi character written as a UCN, and 0 when it was UTF-8.  */
  semi_embedded_vec <context, 16> vec;

  /* Close the whole comment/identifier/string literal/character constant
     context.  */
  void on_close ()
  {
    vec.truncate (0);
  }

  /* Pop the last element in the vector.  */
  void pop ()
  {
    unsigned int len = vec.count ();
    gcc_checking_assert (len > 0);
    vec.truncate (len - 1);
  }

  /* Return the pop kind of the context of the Ith element.  */
  kind pop_kind_at (unsigned int i)
  {
    return vec[i].get_pop_kind ();
  }

  /* Return the pop kind of the context that is currently opened.  */
  kind current_ctx ()
  {
    unsigned int len = vec.count ();
    if (len == 0)
      return kind::NONE;
    return vec[len - 1].get_pop_kind ();
  }

  /* Return true if the current context comes from a UCN origin, that is,
     the bidi char which started this bidi context was written as a UCN.  */
  bool current_ctx_ucn_p ()
  {
    unsigned int len = vec.count ();
    gcc_checking_assert (len > 0);
    return vec[len - 1].m_ucn;
  }

  location_t current_ctx_loc ()
  {
    unsigned int len = vec.count ();
    gcc_checking_assert (len > 0);
    return vec[len - 1].m_loc;
  }

  /* We've read a bidi char, update the current vector as necessary.
     LOC is only valid when K is not kind::NONE.  */
  void on_char (kind k, bool ucn_p, location_t loc)
  {
    switch (k)
      {
      case kind::LRE:
      case kind::RLE:
      case kind::LRO:
      case kind::RLO:
	vec.push (context (loc, k, true, ucn_p));
	break;
      case kind::LRI:
      case kind::RLI:
      case kind::FSI:
	vec.push (context (loc, k, false, ucn_p));
	break;
      /* PDF terminates the scope of the last LRE, RLE, LRO, or RLO
	 whose scope has not yet been terminated.  */
      case kind::PDF:
	if (current_ctx () == kind::PDF)
	  pop ();
	break;
      /* PDI terminates the scope of the last LRI, RLI, or FSI whose
	 scope has not yet been terminated, as well as the scopes of
	 any subsequent LREs, RLEs, LROs, or RLOs whose scopes have not
	 yet been terminated.  */
      case kind::PDI:
	for (int i = vec.count () - 1; i >= 0; --i)
	  if (pop_kind_at (i) == kind::PDI)
	    {
	      vec.truncate (i);
	      break;
	    }
	break;
      case kind::LTR:
      case kind::RTL:
	/* These aren't popped by a PDF/PDI.  */
	break;
      ATTR_LIKELY case kind::NONE:
	break;
      default:
	abort ();
      }
  }

  /* Return a descriptive string for K.  */
  const char *to_str (kind k)
  {
    switch (k)
      {
      case kind::LRE:
	return "U+202A (LEFT-TO-RIGHT EMBEDDING)";
      case kind::RLE:
	return "U+202B (RIGHT-TO-LEFT EMBEDDING)";
      case kind::LRO:
	return "U+202D (LEFT-TO-RIGHT OVERRIDE)";
      case kind::RLO:
	return "U+202E (RIGHT-TO-LEFT OVERRIDE)";
      case kind::LRI:
	return "U+2066 (LEFT-TO-RIGHT ISOLATE)";
      case kind::RLI:
	return "U+2067 (RIGHT-TO-LEFT ISOLATE)";
      case kind::FSI:
	return "U+2068 (FIRST STRONG ISOLATE)";
      case kind::PDF:
	return "U+202C (POP DIRECTIONAL FORMATTING)";
      case kind::PDI:
	return "U+2069 (POP DIRECTIONAL ISOLATE)";
      case kind::LTR:
	return "U+200E (LEFT-TO-RIGHT MARK)";
      case kind::RTL:
	return "U+200F (RIGHT-TO-LEFT MARK)";
      default:
	abort ();
      }
  }
}

/* Get location_t for the range of bytes [START, START + NUM_BYTES)
   within the current line in FILE, with the caret at START.  */

static location_t
get_location_for_byte_range_in_cur_line (cpp_reader *pfile,
					 const unsigned char *const start,
					 size_t num_bytes)
{
  if (pfile->forced_token_location)
    return pfile->forced_token_location;
  gcc_checking_assert (num_bytes > 0);

  /* CPP_BUF_COLUMN and linemap_position_for_column both refer
     to offsets in bytes, but CPP_BUF_COLUMN is 0-based,
     whereas linemap_position_for_column is 1-based.  */

  /* Get 0-based offsets within the line.  */
  size_t start_offset = CPP_BUF_COLUMN (pfile->buffer, start);
  size_t end_offset = start_offset + num_bytes - 1;

  /* Now convert to location_t, where "columns" are 1-based byte offsets.  */
  location_t start_loc = linemap_position_for_column (pfile->line_table,
						      start_offset + 1);
  location_t end_loc = linemap_position_for_column (pfile->line_table,
						     end_offset + 1);

  if (start_loc == end_loc)
    return start_loc;

  source_range src_range;
  src_range.m_start = start_loc;
  src_range.m_finish = end_loc;
  location_t combined_loc
    = pfile->line_table->get_or_create_combined_loc (start_loc,
						     src_range,
						     nullptr,
						     0);
  return combined_loc;
}

/* Parse a sequence of 3 bytes starting with P and return its bidi code.  */

static bidi::kind
get_bidi_utf8_1 (const unsigned char *const p)
{
  gcc_checking_assert (p[0] == bidi::utf8_start);

  if (p[1] == 0x80)
    switch (p[2])
      {
      case 0xaa:
	return bidi::kind::LRE;
      case 0xab:
	return bidi::kind::RLE;
      case 0xac:
	return bidi::kind::PDF;
      case 0xad:
	return bidi::kind::LRO;
      case 0xae:
	return bidi::kind::RLO;
      case 0x8e:
	return bidi::kind::LTR;
      case 0x8f:
	return bidi::kind::RTL;
      default:
	break;
      }
  else if (p[1] == 0x81)
    switch (p[2])
      {
      case 0xa6:
	return bidi::kind::LRI;
      case 0xa7:
	return bidi::kind::RLI;
      case 0xa8:
	return bidi::kind::FSI;
      case 0xa9:
	return bidi::kind::PDI;
      default:
	break;
      }

  return bidi::kind::NONE;
}

/* Parse a sequence of 3 bytes starting with P and return its bidi code.
   If the kind is not NONE, write the location to *OUT.*/

static bidi::kind
get_bidi_utf8 (cpp_reader *pfile, const unsigned char *const p, location_t *out)
{
  bidi::kind result = get_bidi_utf8_1 (p);
  if (result != bidi::kind::NONE)
    {
      /* We have a sequence of 3 bytes starting at P.  */
      *out = get_location_for_byte_range_in_cur_line (pfile, p, 3);
    }
  return result;
}

/* Parse a UCN where P points just past \u or \U and return its bidi code.  */

static bidi::kind
get_bidi_ucn_1 (const unsigned char *p, bool is_U, const unsigned char **end)
{
  /* 6.4.3 Universal Character Names
      \u hex-quad
      \U hex-quad hex-quad
      \u { simple-hexadecimal-digit-sequence }
     where \unnnn means \U0000nnnn.  */

  *end = p + 4;
  if (is_U)
    {
      if (p[0] != '0' || p[1] != '0' || p[2] != '0' || p[3] != '0')
	return bidi::kind::NONE;
      /* Skip 4B so we can treat \u and \U the same below.  */
      p += 4;
      *end += 4;
    }
  else if (p[0] == '{')
    {
      p++;
      while (*p == '0')
	p++;
      if (p[0] != '2'
	  || p[1] != '0'
	  || !ISXDIGIT (p[2])
	  || !ISXDIGIT (p[3])
	  || p[4] != '}')
	return bidi::kind::NONE;
      *end = p + 5;
    }

  /* All code points we are looking for start with 20xx.  */
  if (p[0] != '2' || p[1] != '0')
    return bidi::kind::NONE;
  else if (p[2] == '2')
    switch (p[3])
      {
      case 'a':
      case 'A':
	return bidi::kind::LRE;
      case 'b':
      case 'B':
	return bidi::kind::RLE;
      case 'c':
      case 'C':
	return bidi::kind::PDF;
      case 'd':
      case 'D':
	return bidi::kind::LRO;
      case 'e':
      case 'E':
	return bidi::kind::RLO;
      default:
	break;
      }
  else if (p[2] == '6')
    switch (p[3])
      {
      case '6':
	return bidi::kind::LRI;
      case '7':
	return bidi::kind::RLI;
      case '8':
	return bidi::kind::FSI;
      case '9':
	return bidi::kind::PDI;
      default:
	break;
      }
  else if (p[2] == '0')
    switch (p[3])
      {
      case 'e':
      case 'E':
	return bidi::kind::LTR;
      case 'f':
      case 'F':
	return bidi::kind::RTL;
      default:
	break;
      }

  return bidi::kind::NONE;
}

/* Parse a UCN where P points just past \u or \U and return its bidi code.
   If the kind is not NONE, write the location to *OUT.  */

static bidi::kind
get_bidi_ucn (cpp_reader *pfile, const unsigned char *p, bool is_U,
	      location_t *out)
{
  const unsigned char *end;
  bidi::kind result = get_bidi_ucn_1 (p, is_U, &end);
  if (result != bidi::kind::NONE)
    {
      const unsigned char *start = p - 2;
      size_t num_bytes = end - start;
      *out = get_location_for_byte_range_in_cur_line (pfile, start, num_bytes);
    }
  return result;
}

/* Parse a named universal character escape where P points just past \N and
   return its bidi code.  If the kind is not NONE, write the location to
   *OUT.  */

static bidi::kind
get_bidi_named (cpp_reader *pfile, const unsigned char *p, location_t *out)
{
  bidi::kind result = bidi::kind::NONE;
  if (*p != '{')
    return bidi::kind::NONE;
  if (strncmp ((const char *) (p + 1), "LEFT-TO-RIGHT ", 14) == 0)
    {
      if (strncmp ((const char *) (p + 15), "MARK}", 5) == 0)
	result = bidi::kind::LTR;
      else if (strncmp ((const char *) (p + 15), "EMBEDDING}", 10) == 0)
	result = bidi::kind::LRE;
      else if (strncmp ((const char *) (p + 15), "OVERRIDE}", 9) == 0)
	result = bidi::kind::LRO;
      else if (strncmp ((const char *) (p + 15), "ISOLATE}", 8) == 0)
	result = bidi::kind::LRI;
    }
  else if (strncmp ((const char *) (p + 1), "RIGHT-TO-LEFT ", 14) == 0)
    {
      if (strncmp ((const char *) (p + 15), "MARK}", 5) == 0)
	result = bidi::kind::RTL;
      else if (strncmp ((const char *) (p + 15), "EMBEDDING}", 10) == 0)
	result = bidi::kind::RLE;
      else if (strncmp ((const char *) (p + 15), "OVERRIDE}", 9) == 0)
	result = bidi::kind::RLO;
      else if (strncmp ((const char *) (p + 15), "ISOLATE}", 8) == 0)
	result = bidi::kind::RLI;
    }
  else if (strncmp ((const char *) (p + 1), "POP DIRECTIONAL ", 16) == 0)
    {
      if (strncmp ((const char *) (p + 16), "FORMATTING}", 11) == 0)
	result = bidi::kind::PDF;
      else if (strncmp ((const char *) (p + 16), "ISOLATE}", 8) == 0)
	result = bidi::kind::PDI;
    }
  else if (strncmp ((const char *) (p + 1), "FIRST STRONG ISOLATE}", 21) == 0)
    result = bidi::kind::FSI;
  if (result != bidi::kind::NONE)
    *out = get_location_for_byte_range_in_cur_line (pfile, p - 2,
						    (strchr ((const char *)
							     (p + 1), '}')
						     - (const char *) p)
						    + 3);
  return result;
}

/* Subclass of rich_location for reporting on unpaired UTF-8
   bidirectional control character(s).
   Escape the source lines on output, and show all unclosed
   bidi context, labelling everything.  */

class unpaired_bidi_rich_location : public rich_location
{
 public:
  class custom_range_label : public range_label
  {
   public:
     label_text get_text (unsigned range_idx) const final override
     {
       /* range 0 is the primary location; each subsequent range i + 1
	  is for bidi::vec[i].  */
       if (range_idx > 0)
	 {
	   const bidi::context &ctxt (bidi::vec[range_idx - 1]);
	   return label_text::borrow (bidi::to_str (ctxt.m_kind));
	 }
       else
	 return label_text::borrow (_("end of bidirectional context"));
     }
  };

  unpaired_bidi_rich_location (cpp_reader *pfile, location_t loc)
  : rich_location (pfile->line_table, loc, &m_custom_label)
  {
    set_escape_on_output (true);
    for (unsigned i = 0; i < bidi::vec.count (); i++)
      add_range (bidi::vec[i].m_loc,
		 SHOW_RANGE_WITHOUT_CARET,
		 &m_custom_label);
  }

 private:
   custom_range_label m_custom_label;
};

/* We're closing a bidi context, that is, we've encountered a newline,
   are closing a C-style comment, or are at the end of a string literal,
   character constant, or identifier.  Warn if this context was not
   properly terminated by a PDI or PDF.  P points to the last character
   in this context.  */

static void
maybe_warn_bidi_on_close (cpp_reader *pfile, const uchar *p)
{
  const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional);
  if (bidi::vec.count () > 0
      && (warn_bidi & bidirectional_unpaired
	  && (!bidi::current_ctx_ucn_p ()
	      || (warn_bidi & bidirectional_ucn))))
    {
      const location_t loc
	= linemap_position_for_column (pfile->line_table,
				       CPP_BUF_COLUMN (pfile->buffer, p));
      unpaired_bidi_rich_location rich_loc (pfile, loc);
      /* cpp_callbacks doesn't yet have a way to handle singular vs plural
	 forms of a diagnostic, so fake it for now.  */
      if (bidi::vec.count () > 1)
	cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,
			"unpaired UTF-8 bidirectional control characters "
			"detected");
      else
	cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,
			"unpaired UTF-8 bidirectional control character "
			"detected");
    }
  /* We're done with this context.  */
  bidi::on_close ();
}

/* We're at the beginning or in the middle of an identifier/comment/string
   literal/character constant.  Warn if we've encountered a bidi character.
   KIND says which bidi control character it was; UCN_P is true iff this bidi
   control character was written as a UCN.  LOC is the location of the
   character, but is only valid if KIND != bidi::kind::NONE.  */

static void
maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind,
			 bool ucn_p, location_t loc)
{
  if (__builtin_expect (kind == bidi::kind::NONE, 1))
    return;

  const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional);

  if (warn_bidi & (bidirectional_unpaired|bidirectional_any))
    {
      rich_location rich_loc (pfile->line_table, loc);
      rich_loc.set_escape_on_output (true);

      /* It seems excessive to warn about a PDI/PDF that is closing
	 an opened context because we've already warned about the
	 opening character.  Except warn when we have a UCN x UTF-8
	 mismatch, if UCN checking is enabled.  */
      if (kind == bidi::current_ctx ())
	{
	  if (warn_bidi == (bidirectional_unpaired|bidirectional_ucn)
	      && bidi::current_ctx_ucn_p () != ucn_p)
	    {
	      rich_loc.add_range (bidi::current_ctx_loc ());
	      cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,
			      "UTF-8 vs UCN mismatch when closing "
			      "a context by %qs", bidi::to_str (kind));
	    }
	}
      else if (warn_bidi & bidirectional_any
	       && (!ucn_p || (warn_bidi & bidirectional_ucn)))
	{
	  if (kind == bidi::kind::PDF || kind == bidi::kind::PDI)
	    cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,
			    "%qs is closing an unopened context",
			    bidi::to_str (kind));
	  else
	    cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc,
			    "found problematic Unicode character %qs",
			    bidi::to_str (kind));
	}
    }
  /* We're done with this context.  */
  bidi::on_char (kind, ucn_p, loc);
}

static const cppchar_t utf8_continuation = 0x80;
static const cppchar_t utf8_signifier = 0xC0;

/* Emit -Winvalid-utf8 warning on invalid UTF-8 character starting
   at PFILE->buffer->cur.  Return a pointer after the diagnosed
   invalid character.  */

static const uchar *
_cpp_warn_invalid_utf8 (cpp_reader *pfile)
{
  cpp_buffer *buffer = pfile->buffer;
  const uchar *cur = buffer->cur;
  bool pedantic = (CPP_PEDANTIC (pfile)
		   && CPP_OPTION (pfile, cpp_warn_invalid_utf8) == 2);

  if (cur[0] < utf8_signifier
      || cur[1] < utf8_continuation || cur[1] >= utf8_signifier)
    {
      if (pedantic)
	cpp_error_with_line (pfile, CPP_DL_PEDWARN,
			     pfile->line_table->highest_line,
			     CPP_BUF_COL (buffer),
			     "invalid UTF-8 character %<<%x>%>",
			     cur[0]);
      else
	cpp_warning_with_line (pfile, CPP_W_INVALID_UTF8,
			       pfile->line_table->highest_line,
			       CPP_BUF_COL (buffer),
			       "invalid UTF-8 character %<<%x>%>",
			       cur[0]);
      return cur + 1;
    }
  else if (cur[2] < utf8_continuation || cur[2] >= utf8_signifier)
    {
      if (pedantic)
	cpp_error_with_line (pfile, CPP_DL_PEDWARN,
			     pfile->line_table->highest_line,
			     CPP_BUF_COL (buffer),
			     "invalid UTF-8 character %<<%x><%x>%>",
			     cur[0], cur[1]);
      else
	cpp_warning_with_line (pfile, CPP_W_INVALID_UTF8,
			       pfile->line_table->highest_line,
			       CPP_BUF_COL (buffer),
			       "invalid UTF-8 character %<<%x><%x>%>",
			       cur[0], cur[1]);
      return cur + 2;
    }
  else if (cur[3] < utf8_continuation || cur[3] >= utf8_signifier)
    {
      if (pedantic)
	cpp_error_with_line (pfile, CPP_DL_PEDWARN,
			     pfile->line_table->highest_line,
			     CPP_BUF_COL (buffer),
			     "invalid UTF-8 character %<<%x><%x><%x>%>",
			     cur[0], cur[1], cur[2]);
      else
	cpp_warning_with_line (pfile, CPP_W_INVALID_UTF8,
			       pfile->line_table->highest_line,
			       CPP_BUF_COL (buffer),
			       "invalid UTF-8 character %<<%x><%x><%x>%>",
			       cur[0], cur[1], cur[2]);
      return cur + 3;
    }
  else
    {
      if (pedantic)
	cpp_error_with_line (pfile, CPP_DL_PEDWARN,
			     pfile->line_table->highest_line,
			     CPP_BUF_COL (buffer),
			     "invalid UTF-8 character %<<%x><%x><%x><%x>%>",
			     cur[0], cur[1], cur[2], cur[3]);
      else
	cpp_warning_with_line (pfile, CPP_W_INVALID_UTF8,
			       pfile->line_table->highest_line,
			       CPP_BUF_COL (buffer),
			       "invalid UTF-8 character %<<%x><%x><%x><%x>%>",
			       cur[0], cur[1], cur[2], cur[3]);
      return cur + 4;
    }
}

/* Helper function of *skip_*_comment and lex*_string.  For C,
   character at CUR[-1] with MSB set handle -Wbidi-chars* and
   -Winvalid-utf8 diagnostics and return pointer to first character
   that should be processed next.  */

static inline const uchar *
_cpp_handle_multibyte_utf8 (cpp_reader *pfile, uchar c,
			    const uchar *cur, bool warn_bidi_p,
			    bool warn_invalid_utf8_p)
{
  /* If this is a beginning of a UTF-8 encoding, it might be
     a bidirectional control character.  */
  if (c == bidi::utf8_start && warn_bidi_p)
    {
      location_t loc;
      bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc);
      maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc);
    }
  if (!warn_invalid_utf8_p)
    return cur;
  if (c >= utf8_signifier)
    {
      cppchar_t s;
      const uchar *pstr = cur - 1;
      if (_cpp_valid_utf8 (pfile, &pstr, pfile->buffer->rlimit, 0, NULL, &s)
	  && s <= UCS_LIMIT)
	return pstr;
    }
  pfile->buffer->cur = cur - 1;
  return _cpp_warn_invalid_utf8 (pfile);
}

/* Skip a C-style block comment.  We find the end of the comment by
   seeing if an asterisk is before every '/' we encounter.  Returns
   nonzero if comment terminated by EOF, zero otherwise.

   Buffer->cur points to the initial asterisk of the comment.  */
bool
_cpp_skip_block_comment (cpp_reader *pfile)
{
  cpp_buffer *buffer = pfile->buffer;
  const uchar *cur = buffer->cur;
  uchar c;
  const bool warn_bidi_p = pfile->warn_bidi_p ();
  const bool warn_invalid_utf8_p = CPP_OPTION (pfile, cpp_warn_invalid_utf8);
  const bool warn_bidi_or_invalid_utf8_p = warn_bidi_p | warn_invalid_utf8_p;

  cur++;
  if (*cur == '/')
    cur++;

  for (;;)
    {
      /* People like decorating comments with '*', so check for '/'
	 instead for efficiency.  */
      c = *cur++;

      if (c == '/')
	{
	  if (cur[-2] == '*')
	    {
	      if (warn_bidi_p)
		maybe_warn_bidi_on_close (pfile, cur);
	      break;
	    }

	  /* Warn about potential nested comments, but not if the '/'
	     comes immediately before the true comment delimiter.
	     Don't bother to get it right across escaped newlines.  */
	  if (CPP_OPTION (pfile, warn_comments)
	      && cur[0] == '*' && cur[1] != '/')
	    {
	      buffer->cur = cur;
	      cpp_warning_with_line (pfile, CPP_W_COMMENTS,
				     pfile->line_table->highest_line,
				     CPP_BUF_COL (buffer),
				     "%</*%> within comment");
	    }
	}
      else if (c == '\n')
	{
	  unsigned int cols;
	  buffer->cur = cur - 1;
	  if (warn_bidi_p)
	    maybe_warn_bidi_on_close (pfile, cur);
	  _cpp_process_line_notes (pfile, true);
	  if (buffer->next_line >= buffer->rlimit)
	    return true;
	  _cpp_clean_line (pfile);

	  cols = buffer->next_line - buffer->line_base;
	  CPP_INCREMENT_LINE (pfile, cols);

	  cur = buffer->cur;
	}
      else if (__builtin_expect (c >= utf8_continuation, 0)
	       && warn_bidi_or_invalid_utf8_p)
	cur = _cpp_handle_multibyte_utf8 (pfile, c, cur, warn_bidi_p,
					  warn_invalid_utf8_p);
    }

  buffer->cur = cur;
  _cpp_process_line_notes (pfile, true);
  return false;
}

/* Skip a C++ line comment, leaving buffer->cur pointing to the
   terminating newline.  Handles escaped newlines.  Returns nonzero
   if a multiline comment.  */
static int
skip_line_comment (cpp_reader *pfile)
{
  cpp_buffer *buffer = pfile->buffer;
  location_t orig_line = pfile->line_table->highest_line;
  const bool warn_bidi_p = pfile->warn_bidi_p ();
  const bool warn_invalid_utf8_p = CPP_OPTION (pfile, cpp_warn_invalid_utf8);
  const bool warn_bidi_or_invalid_utf8_p = warn_bidi_p | warn_invalid_utf8_p;

  if (!warn_bidi_or_invalid_utf8_p)
    while (*buffer->cur != '\n')
      buffer->cur++;
  else if (!warn_invalid_utf8_p)
    {
      while (*buffer->cur != '\n'
	     && *buffer->cur != bidi::utf8_start)
	buffer->cur++;
      if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0))
	{
	  while (*buffer->cur != '\n')
	    {
	      if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0))
		{
		  location_t loc;
		  bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc);
		  maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc);
		}
	      buffer->cur++;
	    }
	  maybe_warn_bidi_on_close (pfile, buffer->cur);
	}
    }
  else
    {
      while (*buffer->cur != '\n')
	{
	  if (*buffer->cur < utf8_continuation)
	    {
	      buffer->cur++;
	      continue;
	    }
	  buffer->cur
	    = _cpp_handle_multibyte_utf8 (pfile, *buffer->cur, buffer->cur + 1,
					  warn_bidi_p, warn_invalid_utf8_p);
	}
      if (warn_bidi_p)
	maybe_warn_bidi_on_close (pfile, buffer->cur);
    }

  _cpp_process_line_notes (pfile, true);
  return orig_line != pfile->line_table->highest_line;
}

/* Skips whitespace, saving the next non-whitespace character.  */
static void
skip_whitespace (cpp_reader *pfile, cppchar_t c)
{
  cpp_buffer *buffer = pfile->buffer;
  bool saw_NUL = false;

  do
    {
      /* Horizontal space always OK.  */
      if (c == ' ' || c == '\t')
	;
      /* Just \f \v or \0 left.  */
      else if (c == '\0')
	saw_NUL = true;
      else if (pfile->state.in_directive)
	cpp_pedwarning_with_line (pfile, CPP_W_PEDANTIC,
				  pfile->line_table->highest_line,
				  CPP_BUF_COL (buffer),
				  "%s in preprocessing directive",
				  c == '\f' ? "form feed" : "vertical tab");

      c = *buffer->cur++;
    }
  /* We only want non-vertical space, i.e. ' ' \t \f \v \0.  */
  while (is_nvspace (c));

  if (saw_NUL)
    {
      encoding_rich_location rich_loc (pfile);
      cpp_error_at (pfile, CPP_DL_WARNING, &rich_loc,
		    "null character(s) ignored");
    }

  buffer->cur--;
}

/* See if the characters of a number token are valid in a name (no
   '.', '+' or '-').  */
static int
name_p (cpp_reader *pfile, const cpp_string *string)
{
  unsigned int i;

  for (i = 0; i < string->len; i++)
    if (!is_idchar (string->text[i]))
      return 0;

  return 1;
}

/* After parsing an identifier or other sequence, produce a warning about
   sequences not in NFC/NFKC.  */
static void
warn_about_normalization (cpp_reader *pfile,
			  const cpp_token *token,
			  const struct normalize_state *s,
			  bool identifier)
{
  if (CPP_OPTION (pfile, warn_normalize) < NORMALIZE_STATE_RESULT (s)
      && !pfile->state.skipping)
    {
      location_t loc = token->src_loc;

      /* If possible, create a location range for the token.  */
      if (loc >= RESERVED_LOCATION_COUNT
	  && token->type != CPP_EOF
	  && !pfile->forced_token_location
	  /* There must be no line notes to process.  */
	  && (!(pfile->buffer->cur
		>= pfile->buffer->notes[pfile->buffer->cur_note].pos
		&& !pfile->overlaid_buffer)))
	{
	  source_range tok_range;
	  tok_range.m_start = loc;
	  tok_range.m_finish
	    = linemap_position_for_column (pfile->line_table,
					   CPP_BUF_COLUMN (pfile->buffer,
							   pfile->buffer->cur));
	  loc = pfile->line_table->get_or_create_combined_loc (loc, tok_range,
							       nullptr, 0);
	}

      encoding_rich_location rich_loc (pfile, loc);

      /* Make sure that the token is printed using UCNs, even
	 if we'd otherwise happily print UTF-8.  */
      unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token));
      size_t sz;

      sz = cpp_spell_token (pfile, token, buf, false) - buf;
      if (NORMALIZE_STATE_RESULT (s) == normalized_C)
	cpp_warning_at (pfile, CPP_W_NORMALIZE, &rich_loc,
			"%<%.*s%> is not in NFKC", (int) sz, buf);
      else if (identifier && CPP_OPTION (pfile, xid_identifiers))
	cpp_pedwarning_at (pfile, CPP_W_NORMALIZE, &rich_loc,
				  "%<%.*s%> is not in NFC", (int) sz, buf);
      else
	cpp_warning_at (pfile, CPP_W_NORMALIZE, &rich_loc,
			"%<%.*s%> is not in NFC", (int) sz, buf);
      free (buf);
    }
}

/* 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,
		    struct normalize_state *state)
{
  cpp_buffer *buffer = pfile->buffer;
  const bool warn_bidi_p = pfile->warn_bidi_p ();

  if (*buffer->cur == '$')
    {
      if (!CPP_OPTION (pfile, dollars_in_ident))
	return false;

      buffer->cur++;
      if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping)
	{
	  CPP_OPTION (pfile, warn_dollars) = 0;
	  cpp_error (pfile, CPP_DL_PEDWARN, "%<$%> in identifier or number");
	}

      return true;
    }

  /* Is this a syntactically valid UCN or a valid UTF-8 char?  */
  if (CPP_OPTION (pfile, extended_identifiers))
    {
      cppchar_t s;
      if (*buffer->cur >= utf8_signifier)
	{
	  if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)
	      && warn_bidi_p)
	    {
	      location_t loc;
	      bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc);
	      maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc);
	    }
	  if (_cpp_valid_utf8 (pfile, &buffer->cur, buffer->rlimit, 1 + !first,
			       state, &s))
	    return true;
	}
      else if (*buffer->cur == '\\'
	       && (buffer->cur[1] == 'u'
		   || buffer->cur[1] == 'U'
		   || buffer->cur[1] == 'N'))
	{
	  buffer->cur += 2;
	  if (warn_bidi_p)
	    {
	      location_t loc;
	      bidi::kind kind;
	      if (buffer->cur[-1] == 'N')
		kind = get_bidi_named (pfile, buffer->cur, &loc);
	      else
		kind = get_bidi_ucn (pfile, buffer->cur,
				     buffer->cur[-1] == 'U', &loc);
	      maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc);
	    }
	  if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first,
			      state, &s, NULL, NULL))
	    return true;
	  buffer->cur -= 2;
	}
    }

  return false;
}

/* Helper function to issue error about improper __VA_OPT__ use.  */
static void
maybe_va_opt_error (cpp_reader *pfile)
{
  if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, va_opt))
    {
      /* __VA_OPT__ should not be accepted at all, but allow it in
	 system headers.  */
      if (!_cpp_in_system_header (pfile))
	{
	  if (CPP_OPTION (pfile, cplusplus))
	    cpp_pedwarning (pfile, CPP_W_CXX20_EXTENSIONS,
			    "%<__VA_OPT__%> is not available until C++20");
	  else
	    cpp_pedwarning (pfile, CPP_W_PEDANTIC,
			    "%<__VA_OPT__%> is not available until C23");
	}
    }
  else if (!pfile->state.va_args_ok)
    {
      /* __VA_OPT__ should only appear in the replacement list of a
	 variadic macro.  */
      cpp_error (pfile, CPP_DL_PEDWARN,
		 "%<__VA_OPT__%> can only appear in the expansion"
		 " of a C++20 variadic macro");
    }
}

/* 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 %qs",
		 NODE_NAME (node));
      const auto data = (cpp_hashnode_extra *)
	ht_lookup (pfile->extra_hash_table, node->ident, HT_NO_INSERT);
      if (data && data->poisoned_loc)
	cpp_error_at (pfile, CPP_DL_NOTE, data->poisoned_loc, "poisoned here");
    }

  /* 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");
    }

  /* __VA_OPT__ should only appear in the replacement list of a
     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 %qs is a special operator name in C++",
		 NODE_NAME (node));
}

/* Lex an identifier starting at BASE.  BUFFER->CUR is expected to point
   one past the first character at BASE, which may be a (possibly multi-byte)
   character if STARTS_UCN is true.  */
static cpp_hashnode *
lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
		struct normalize_state *nst, cpp_hashnode **spelling)
{
  cpp_hashnode *result;
  const uchar *cur;
  unsigned int len;
  unsigned int hash = HT_HASHSTEP (0, *base);
  const bool warn_bidi_p = pfile->warn_bidi_p ();

  cur = pfile->buffer->cur;
  if (! starts_ucn)
    {
      while (ISIDNUM (*cur))
	{
	  hash = HT_HASHSTEP (hash, *cur);
	  cur++;
	}
      NORMALIZE_STATE_UPDATE_IDNUM (nst, *(cur - 1));
    }
  pfile->buffer->cur = cur;
  if (starts_ucn || forms_identifier_p (pfile, false, nst))
    {
      /* Slower version for identifiers containing UCNs
	 or extended chars (including $).  */
      do {
	while (ISIDNUM (*pfile->buffer->cur))
	  {
	    NORMALIZE_STATE_UPDATE_IDNUM (nst, *pfile->buffer->cur);
	    pfile->buffer->cur++;
	  }
      } while (forms_identifier_p (pfile, false, nst));
      if (warn_bidi_p)
	maybe_warn_bidi_on_close (pfile, pfile->buffer->cur);
      result = _cpp_interpret_identifier (pfile, base,
					  pfile->buffer->cur - base);
      *spelling = cpp_lookup (pfile, base, pfile->buffer->cur - base);
    }
  else
    {
      len = cur - base;
      hash = HT_HASHFINISH (hash, len);

      result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table,
						  base, len, hash, HT_ALLOC));
      *spelling = result;
    }

  return result;
}

/* Struct to hold the return value of the scan_cur_identifier () helper
   function below.  */

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; }
};

/* 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.  */

static scan_id_result
scan_cur_identifier (cpp_reader *pfile)
{
  const auto buffer = pfile->buffer;
  const auto begin = buffer->cur;
  scan_id_result result;
  if (ISIDST (*buffer->cur))
    {
      ++buffer->cur;
      cpp_hashnode *ignore;
      result.node = lex_identifier (pfile, begin, false, &result.nst, &ignore);
    }
  else if (forms_identifier_p (pfile, true, &result.nst))
    {
      /* buffer->cur has been moved already by the call
	 to forms_identifier_p.  */
      cpp_hashnode *ignore;
      result.node = lex_identifier (pfile, begin, true, &result.nst, &ignore);
    }
  return result;
}

/* Lex a number to NUMBER starting at BUFFER->CUR - 1.  */
static void
lex_number (cpp_reader *pfile, cpp_string *number,
	    struct normalize_state *nst)
{
  const uchar *cur;
  const uchar *base;
  uchar *dest;

  base = pfile->buffer->cur - 1;
  do
    {
      const uchar *adj_digit_sep = NULL;
      cur = pfile->buffer->cur;

      /* N.B. ISIDNUM does not include $.  */
      while (ISIDNUM (*cur)
	     || (*cur == '.' && !DIGIT_SEP (cur[-1]))
	     || DIGIT_SEP (*cur)
	     || (VALID_SIGN (*cur, cur[-1]) && !DIGIT_SEP (cur[-2])))
	{
	  NORMALIZE_STATE_UPDATE_IDNUM (nst, *cur);
	  /* Adjacent digit separators do not form part of the pp-number syntax.
	     However, they can safely be diagnosed here as an error, since '' is
	     not a valid preprocessing token.  */
	  if (DIGIT_SEP (*cur) && DIGIT_SEP (cur[-1]) && !adj_digit_sep)
	    adj_digit_sep = cur;
	  cur++;
	}
      /* A number can't end with a digit separator.  */
      while (cur > pfile->buffer->cur && DIGIT_SEP (cur[-1]))
	--cur;
      if (adj_digit_sep && adj_digit_sep < cur)
	cpp_error (pfile, CPP_DL_ERROR, "adjacent digit separators");

      pfile->buffer->cur = cur;
    }
  while (forms_identifier_p (pfile, false, nst));

  number->len = cur - base;
  dest = _cpp_unaligned_alloc (pfile, number->len + 1);
  memcpy (dest, base, number->len);
  dest[number->len] = '\0';
  number->text = dest;
}

/* Create a token of type TYPE with a literal spelling.  */
static void
create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base,
		unsigned int len, enum cpp_ttype type)
{
  token->type = type;
  token->val.str.len = len;
  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)
{
  uchar *dest = _cpp_unaligned_alloc (pfile, len + 1);

  dest[len] = 0;
  memcpy (dest, ptr, len);
  return dest;
}

/* A pair of raw buffer pointers.  The currently open one is [1], the
   first one is [0].  Used for string literal lexing.  */
struct lit_accum {
  _cpp_buff *first;
  _cpp_buff *last;
  const uchar *rpos;
  size_t accum;

  lit_accum ()
    : first (NULL), last (NULL), rpos (0), accum (0)
  {
  }

  void append (cpp_reader *, const uchar *, size_t);

  void read_begin (cpp_reader *);
  bool reading_p () const
  {
    return rpos != NULL;
  }
  char read_char ()
  {
    char c = *rpos++;
    if (rpos == BUFF_FRONT (last))
      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
   sequence from *FIRST_BUFF_P to LAST_BUFF_P.  */

void
lit_accum::append (cpp_reader *pfile, const uchar *base, size_t len)
{
  if (!last)
    /* Starting.  */
    first = last = _cpp_get_buff (pfile, len);
  else if (len > BUFF_ROOM (last))
    {
      /* There is insufficient room in the buffer.  Copy what we can,
	 and then either extend or create a new one.  */
      size_t room = BUFF_ROOM (last);
      memcpy (BUFF_FRONT (last), base, room);
      BUFF_FRONT (last) += room;
      base += room;
      len -= room;
      accum += room;

      gcc_checking_assert (!rpos);

      last = _cpp_append_extend_buff (pfile, last, len);
    }

  memcpy (BUFF_FRONT (last), base, len);
  BUFF_FRONT (last) += len;
  accum += len;
}

void
lit_accum::read_begin (cpp_reader *pfile)
{
  /* We never accumulate more than 4 chars to read.  */
  if (BUFF_ROOM (last) < 4)

    last = _cpp_append_extend_buff (pfile, last, 4);
  rpos = BUFF_FRONT (last);
}

/* Helper function to check if a string format macro, say from inttypes.h, is
   placed touching a string literal, in which case it could be parsed as a C++11
   user-defined string literal thus breaking the program.  Return TRUE if the
   UDL should be ignored for now and preserved for potential macro
   expansion.  */

static bool
maybe_ignore_udl_macro_suffix (cpp_reader *pfile, location_t src_loc,
			       const uchar *suffix_begin, cpp_hashnode *node)
{
  /* 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 (node))
    return false;

  /* Maybe raise a warning here; caller should arrange not to consume
     the tokens.  */
  if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping)
    cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX, src_loc, 0,
			   "invalid suffix on literal; C++11 requires a space "
			   "between literal and string macro");
  return true;
}

/* 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 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)
    {
      size_t len = BUFF_FRONT (buf) - buf->base;
      memcpy (dest, buf->base, len);
      dest += len;
    }
  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,
   including double quotes, delimiter string, '(' and ')', any leading
   'L', 'u', 'U' or 'u8' and 'R' modifier.  The created token contains
   the type of the literal, or CPP_OTHER if it was not properly
   terminated.

   BASE is the start of the token.  Updates pfile->buffer->cur to just
   after the lexed string.

   The spelling is NUL-terminated, but it is not guaranteed that this
   is the first NUL since embedded NULs are preserved.  */

static void
lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
{
  const uchar *pos = base;
  const bool warn_bidi_p = pfile->warn_bidi_p ();
  const bool warn_invalid_utf8_p = CPP_OPTION (pfile, cpp_warn_invalid_utf8);
  const bool warn_bidi_or_invalid_utf8_p = warn_bidi_p | warn_invalid_utf8_p;

  /* 'tis a pity this information isn't passed down from the lexer's
     initial categorization of the token.  */
  enum cpp_ttype type = CPP_STRING;

  if (*pos == 'L')
    {
      type = CPP_WSTRING;
      pos++;
    }
  else if (*pos == 'U')
    {
      type = CPP_STRING32;
      pos++;
    }
  else if (*pos == 'u')
    {
      if (pos[1] == '8')
	{
	  type = CPP_UTF8STRING;
	  pos++;
	}
      else
	type = CPP_STRING16;
      pos++;
    }

  gcc_checking_assert (pos[0] == 'R' && pos[1] == '"');
  pos += 2;

  _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note];

  /* Skip notes before the ".  */
  while (note->pos < pos)
    ++note;

  lit_accum accum;

  uchar prefix[17];
  unsigned prefix_len = 0;
  enum Phase
  {
   PHASE_PREFIX = -2,
   PHASE_NONE = -1,
   PHASE_SUFFIX = 0
  } phase = PHASE_PREFIX;

  for (;;)
    {
      gcc_checking_assert (note->pos >= pos);

      /* Undo any escaped newlines and trigraphs.  */
      if (!accum.reading_p () && note->pos == pos)
	switch (note->type)
	  {
	  case '\\':
	  case ' ':
	    /* Restore backslash followed by newline.  */
	    accum.append (pfile, base, pos - base);
	    base = pos;
	    accum.read_begin (pfile);
	    accum.append (pfile, UC"\\", 1);

	  after_backslash:
	    if (note->type == ' ')
	      /* GNU backslash whitespace newline extension.  FIXME
		 could be any sequence of non-vertical space.  When we
		 can properly restore any such sequence, we should
		 mark this note as handled so _cpp_process_line_notes
		 doesn't warn.  */
	      accum.append (pfile, UC" ", 1);

	    accum.append (pfile, UC"\n", 1);
	    note++;
	    break;

	  case '\n':
	    /* This can happen for ??/<NEWLINE> when trigraphs are not
	       being interpretted.  */
	    gcc_checking_assert (!CPP_OPTION (pfile, trigraphs));
	    note->type = 0;
	    note++;
	    break;

	  case 'W':
	  case 'L':
	  case 'S':
	  case 'T':
	    /* Don't warn about leading or trailing whitespace in raw string
	       literals.  */
	    note->type = 0;
	    note++;
	    break;

	  default:
	    gcc_checking_assert (_cpp_trigraph_map[note->type]);

	    /* Don't warn about this trigraph in
	       _cpp_process_line_notes, since trigraphs show up as
	       trigraphs in raw strings.  */
	    uchar type = note->type;
	    note->type = 0;

	    if (CPP_OPTION (pfile, trigraphs))
	      {
		accum.append (pfile, base, pos - base);
		base = pos;
		accum.read_begin (pfile);
		accum.append (pfile, UC"??", 2);
		accum.append (pfile, &type, 1);

		/* ??/ followed by newline gets two line notes, one for
		   the trigraph and one for the backslash/newline.  */
		if (type == '/' && note[1].pos == pos)
		  {
		    note++;
		    gcc_assert (note->type == '\\' || note->type == ' ');
		    goto after_backslash;
		  }
		/* Skip the replacement character.  */
		base = ++pos;
	      }

	    note++;
	    break;
	  }

      /* Now get a char to process.  Either from an expanded note, or
	 from the line buffer.  */
      bool read_note = accum.reading_p ();
      char c = read_note ? accum.read_char () : *pos++;

      if (phase == PHASE_PREFIX)
	{
	  if (c == '(')
	    {
	      /* Done.  */
	      phase = PHASE_NONE;
	      prefix[prefix_len++] = '"';
	    }
	  else if (prefix_len < 16
		   /* Prefix chars are any of the basic character set,
		      [lex.charset] except for '
		      ()\\\t\v\f\n'. Optimized for a contiguous
		      alphabet.  */
		   /* Unlike a switch, this collapses down to one or
		      two shift and bitmask operations on an ASCII
		      system, with an outlier or two.   */
		   && (('Z' - 'A' == 25
			? ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
			: ISIDST (c))
		       || (c >= '0' && c <= '9')
		       || c == '_' || c == '{' || c == '}'
		       || c == '[' || c == ']' || c == '#'
		       || c == '<' || c == '>' || c == '%'
		       || c == ':' || c == ';' || c == '.' || c == '?'
		       || c == '*' || c == '+' || c == '-' || c == '/'
		       || c == '^' || c == '&' || c == '|' || c == '~'
		       || c == '!' || c == '=' || c == ','
		       || c == '"' || c == '\''
		       || ((c == '$' || c == '@' || c == '`')
			   && (CPP_OPTION (pfile, cplusplus)
			       ? CPP_OPTION (pfile, lang) > CLK_CXX23
			       : CPP_OPTION (pfile, low_ucns)))))
	    prefix[prefix_len++] = c;
	  else
	    {
	      /* Something is wrong.  */
	      int col = CPP_BUF_COLUMN (pfile->buffer, pos) + read_note;
	      if (prefix_len == 16)
		cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
				     col, "raw string delimiter longer "
				     "than 16 characters");
	      else if (c == '\n')
		cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
				     col, "invalid new-line in raw "
				     "string delimiter");
	      else
		cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
				     col, "invalid character '%c' in "
				     "raw string delimiter", c);
	      type = CPP_OTHER;
	      phase = PHASE_NONE;
	      /* Continue until we get a close quote, that's probably
		 the best failure mode.  */
	      prefix_len = 0;
	    }
	  if (c != '\n')
	    continue;
	}

      if (phase != PHASE_NONE)
	{
	  if (prefix[phase] != c)
	    phase = PHASE_NONE;
	  else if (unsigned (phase + 1) == prefix_len)
	    break;
	  else
	    {
	      phase = Phase (phase + 1);
	      continue;
	    }
	}

      if (!prefix_len && c == '"')
	/* Failure mode lexing.  */
	goto out;
      else if (prefix_len && c == ')')
	phase = PHASE_SUFFIX;
      else if (!read_note && c == '\n')
	{
	  pos--;
	  pfile->buffer->cur = pos;
	  if ((pfile->state.in_directive || pfile->state.parsing_args
	       || pfile->state.in_deferred_pragma)
	      && pfile->buffer->next_line >= pfile->buffer->rlimit)
	    {
	      cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0,
				   "unterminated raw string");
	      type = CPP_OTHER;
	      goto out;
	    }

	  accum.append (pfile, base, pos - base + 1);
	  _cpp_process_line_notes (pfile, false);

	  if (pfile->buffer->next_line < pfile->buffer->rlimit)
	    CPP_INCREMENT_LINE (pfile, 0);
	  pfile->buffer->need_line = true;

	  if (!get_fresh_line_impl<true> (pfile))
	    {
	      /* We ran out of file and failed to get a line.  */
	      location_t src_loc = token->src_loc;
	      token->type = CPP_EOF;
	      /* Tell the compiler the line number of the EOF token.  */
	      token->src_loc = pfile->line_table->highest_line;
	      token->flags = BOL;
	      if (accum.first)
		_cpp_release_buff (pfile, accum.first);
	      cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0,
				   "unterminated raw string");

	      /* Now pop the buffer that get_fresh_line_impl() did not.  Popping
		 is not safe if processing a directive, however this cannot
		 happen as we already checked above that a line would be
		 available, and get_fresh_line_impl() can't fail in this
		 case.  */
	      gcc_assert (!pfile->state.in_directive);
	      _cpp_pop_buffer (pfile);

	      return;
	    }

	  pos = base = pfile->buffer->cur;
	  note = &pfile->buffer->notes[pfile->buffer->cur_note];
	}
      else if (__builtin_expect ((unsigned char) c >= utf8_continuation, 0)
	       && warn_bidi_or_invalid_utf8_p)
	pos = _cpp_handle_multibyte_utf8 (pfile, c, pos, warn_bidi_p,
					  warn_invalid_utf8_p);
    }

  if (warn_bidi_p)
    maybe_warn_bidi_on_close (pfile, pos);

  if (CPP_OPTION (pfile, user_literals))
    {
      const uchar *const suffix_begin = pos;
      pfile->buffer->cur = pos;

      if (const auto sr = scan_cur_identifier (pfile))
	{
	  if (maybe_ignore_udl_macro_suffix (pfile, token->src_loc,
					     suffix_begin, sr.node))
	      pfile->buffer->cur = suffix_begin;
	  else
	    {
	      type = cpp_userdef_string_add_type (type);
	      accum.create_literal2 (pfile, token, base, suffix_begin - base,
				     NODE_NAME (sr.node), NODE_LEN (sr.node),
				     type);
	      if (accum.first)
		_cpp_release_buff (pfile, accum.first);
	      warn_about_normalization (pfile, token, &sr.nst, true);
	      return;
	    }
	}
    }

 out:
  pfile->buffer->cur = pos;
  if (!accum.accum)
    create_literal (pfile, token, base, pos - base, type);
  else
    {
      accum.create_literal2 (pfile, token, base, pos - base, nullptr, 0, type);
      _cpp_release_buff (pfile, accum.first);
    }
}

/* Lexes a string, character constant, or angle-bracketed header file
   name.  The stored string contains the spelling, including opening
   quote and any leading 'L', 'u', 'U' or 'u8' and optional
   'R' modifier.  It returns the type of the literal, or CPP_OTHER
   if it was not properly terminated, or CPP_LESS for an unterminated
   header name which must be relexed as normal tokens.

   The spelling is NUL-terminated, but it is not guaranteed that this
   is the first NUL since embedded NULs are preserved.  */
static void
lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
{
  bool saw_NUL = false;
  const uchar *cur;
  cppchar_t terminator;
  enum cpp_ttype type;

  cur = base;
  terminator = *cur++;
  if (terminator == 'L' || terminator == 'U')
    terminator = *cur++;
  else if (terminator == 'u')
    {
      terminator = *cur++;
      if (terminator == '8')
	terminator = *cur++;
    }
  if (terminator == 'R')
    {
      lex_raw_string (pfile, token, base);
      return;
    }
  if (terminator == '"')
    type = (*base == 'L' ? CPP_WSTRING :
	    *base == 'U' ? CPP_STRING32 :
	    *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16)
			 : CPP_STRING);
  else if (terminator == '\'')
    type = (*base == 'L' ? CPP_WCHAR :
	    *base == 'U' ? CPP_CHAR32 :
	    *base == 'u' ? (base[1] == '8' ? CPP_UTF8CHAR : CPP_CHAR16)
			 : CPP_CHAR);
  else
    terminator = '>', type = CPP_HEADER_NAME;

  const bool warn_bidi_p = pfile->warn_bidi_p ();
  const bool warn_invalid_utf8_p = CPP_OPTION (pfile, cpp_warn_invalid_utf8);
  const bool warn_bidi_or_invalid_utf8_p = warn_bidi_p | warn_invalid_utf8_p;
  for (;;)
    {
      cppchar_t c = *cur++;

      /* In #include-style directives, terminators are not escapable.  */
      if (c == '\\' && !pfile->state.angled_headers && *cur != '\n')
	{
	  if ((cur[0] == 'u' || cur[0] == 'U' || cur[0] == 'N') && warn_bidi_p)
	    {
	      location_t loc;
	      bidi::kind kind;
	      if (cur[0] == 'N')
		kind = get_bidi_named (pfile, cur + 1, &loc);
	      else
		kind = get_bidi_ucn (pfile, cur + 1, cur[0] == 'U', &loc);
	      maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc);
	    }
	  cur++;
	}
      else if (c == terminator)
	{
	  if (warn_bidi_p)
	    maybe_warn_bidi_on_close (pfile, cur - 1);
	  break;
	}
      else if (c == '\n')
	{
	  cur--;
	  /* Unmatched quotes always yield undefined behavior, but
	     greedy lexing means that what appears to be an unterminated
	     header name may actually be a legitimate sequence of tokens.  */
	  if (terminator == '>')
	    {
	      token->type = CPP_LESS;
	      return;
	    }
	  type = CPP_OTHER;
	  break;
	}
      else if (c == '\0')
	saw_NUL = true;
      else if (__builtin_expect (c >= utf8_continuation, 0)
	       && warn_bidi_or_invalid_utf8_p)
	cur = _cpp_handle_multibyte_utf8 (pfile, c, cur, warn_bidi_p,
					  warn_invalid_utf8_p);
    }

  if (saw_NUL && !pfile->state.skipping)
    cpp_error (pfile, CPP_DL_WARNING,
	       "null character(s) preserved in literal");

  if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM)
    cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character",
	       (int) terminator);

  pfile->buffer->cur = cur;
  const uchar *const suffix_begin = cur;

  if (CPP_OPTION (pfile, user_literals))
    {
      if (const auto sr = scan_cur_identifier (pfile))
	{
	  if (maybe_ignore_udl_macro_suffix (pfile, token->src_loc,
					     suffix_begin, sr.node))
	    pfile->buffer->cur = suffix_begin;
	  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, true);
	      return;
	    }
	}
    }
  else if (CPP_OPTION (pfile, cpp_warn_cxx11_compat)
	   && !pfile->state.skipping)
    {
      const auto sr = scan_cur_identifier (pfile);
      /* Maybe raise a warning, but do not consume the tokens.  */
      pfile->buffer->cur = suffix_begin;
      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");
    }

  create_literal (pfile, token, base, cur - base, type);
}

/* Return the comment table. The client may not make any assumption
   about the ordering of the table.  */
cpp_comment_table *
cpp_get_comments (cpp_reader *pfile)
{
  return &pfile->comments;
}

/* Append a comment to the end of the comment table. */
static void
store_comment (cpp_reader *pfile, cpp_token *token)
{
  int len;

  if (pfile->comments.allocated == 0)
    {
      pfile->comments.allocated = 256;
      pfile->comments.entries = (cpp_comment *) xmalloc
	(pfile->comments.allocated * sizeof (cpp_comment));
    }

  if (pfile->comments.count == pfile->comments.allocated)
    {
      pfile->comments.allocated *= 2;
      pfile->comments.entries = (cpp_comment *) xrealloc
	(pfile->comments.entries,
	 pfile->comments.allocated * sizeof (cpp_comment));
    }

  len = token->val.str.len;

  /* Copy comment. Note, token may not be NULL terminated. */
  pfile->comments.entries[pfile->comments.count].comment =
    (char *) xmalloc (sizeof (char) * (len + 1));
  memcpy (pfile->comments.entries[pfile->comments.count].comment,
	  token->val.str.text, len);
  pfile->comments.entries[pfile->comments.count].comment[len] = '\0';

  /* Set source location. */
  pfile->comments.entries[pfile->comments.count].sloc = token->src_loc;

  /* Increment the count of entries in the comment table. */
  pfile->comments.count++;
}

/* The stored comment includes the comment start and any terminator.  */
static void
save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from,
	      cppchar_t type)
{
  unsigned char *buffer;
  unsigned int len, clen, i;

  len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'.  */

  /* C++ comments probably (not definitely) have moved past a new
     line, which we don't want to save in the comment.  */
  if (is_vspace (pfile->buffer->cur[-1]))
    len--;

  /* If we are currently in a directive or in argument parsing, then
     we need to store all C++ comments as C comments internally, and
     so we need to allocate a little extra space in that case.

     Note that the only time we encounter a directive here is
     when we are saving comments in a "#define".  */
  clen = ((pfile->state.in_directive || pfile->state.parsing_args)
	  && type == '/') ? len + 2 : len;

  buffer = _cpp_unaligned_alloc (pfile, clen);

  token->type = CPP_COMMENT;
  token->val.str.len = clen;
  token->val.str.text = buffer;

  buffer[0] = '/';
  memcpy (buffer + 1, from, len - 1);

  /* Finish conversion to a C comment, if necessary.  */
  if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/')
    {
      buffer[1] = '*';
      buffer[clen - 2] = '*';
      buffer[clen - 1] = '/';
      /* As there can be in a C++ comments illegal sequences for C comments
         we need to filter them out.  */
      for (i = 2; i < (clen - 2); i++)
        if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*'))
          buffer[i] = '|';
    }

  /* Finally store this comment for use by clients of libcpp. */
  store_comment (pfile, token);
}

/* Returns true if comment at COMMENT_START is a recognized FALLTHROUGH
   comment.  */

static bool
fallthrough_comment_p (cpp_reader *pfile, const unsigned char *comment_start)
{
  const unsigned char *from = comment_start + 1;

  switch (CPP_OPTION (pfile, cpp_warn_implicit_fallthrough))
    {
      /* For both -Wimplicit-fallthrough=0 and -Wimplicit-fallthrough=5 we
	 don't recognize any comments.  The latter only checks attributes,
	 the former doesn't warn.  */
    case 0:
    default:
      return false;
      /* -Wimplicit-fallthrough=1 considers any comment, no matter what
	 content it has.  */
    case 1:
      return true;
    case 2:
      /* -Wimplicit-fallthrough=2 looks for (case insensitive)
	 .*falls?[ \t-]*thr(u|ough).* regex.  */
      for (; (size_t) (pfile->buffer->cur - from) >= sizeof "fallthru" - 1;
	   from++)
	{
	  /* Is there anything like strpbrk with upper boundary, or
	     memchr looking for 2 characters rather than just one?  */
	  if (from[0] != 'f' && from[0] != 'F')
	    continue;
	  if (from[1] != 'a' && from[1] != 'A')
	    continue;
	  if (from[2] != 'l' && from[2] != 'L')
	    continue;
	  if (from[3] != 'l' && from[3] != 'L')
	    continue;
	  from += sizeof "fall" - 1;
	  if (from[0] == 's' || from[0] == 'S')
	    from++;
	  while (*from == ' ' || *from == '\t' || *from == '-')
	    from++;
	  if (from[0] != 't' && from[0] != 'T')
	    continue;
	  if (from[1] != 'h' && from[1] != 'H')
	    continue;
	  if (from[2] != 'r' && from[2] != 'R')
	    continue;
	  if (from[3] == 'u' || from[3] == 'U')
	    return true;
	  if (from[3] != 'o' && from[3] != 'O')
	    continue;
	  if (from[4] != 'u' && from[4] != 'U')
	    continue;
	  if (from[5] != 'g' && from[5] != 'G')
	    continue;
	  if (from[6] != 'h' && from[6] != 'H')
	    continue;
	  return true;
	}
      return false;
    case 3:
    case 4:
      break;
    }

  /* Whole comment contents:
     -fallthrough
     @fallthrough@
   */
  if (*from == '-' || *from == '@')
    {
      size_t len = sizeof "fallthrough" - 1;
      if ((size_t) (pfile->buffer->cur - from - 1) < len)
	return false;
      if (memcmp (from + 1, "fallthrough", len))
	return false;
      if (*from == '@')
	{
	  if (from[len + 1] != '@')
	    return false;
	  len++;
	}
      from += 1 + len;
    }
  /* Whole comment contents (regex):
     lint -fallthrough[ \t]*
   */
  else if (*from == 'l')
    {
      size_t len = sizeof "int -fallthrough" - 1;
      if ((size_t) (pfile->buffer->cur - from - 1) < len)
	return false;
      if (memcmp (from + 1, "int -fallthrough", len))
	return false;
      from += 1 + len;
      while (*from == ' ' || *from == '\t')
	from++;
    }
  /* Whole comment contents (regex):
     [ \t]*FALLTHR(U|OUGH)[ \t]*
   */
  else if (CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) == 4)
    {
      while (*from == ' ' || *from == '\t')
	from++;
      if ((size_t) (pfile->buffer->cur - from)  < sizeof "FALLTHRU" - 1)
	return false;
      if (memcmp (from, "FALLTHR", sizeof "FALLTHR" - 1))
	return false;
      from += sizeof "FALLTHR" - 1;
      if (*from == 'U')
	from++;
      else if ((size_t) (pfile->buffer->cur - from)  < sizeof "OUGH" - 1)
	return false;
      else if (memcmp (from, "OUGH", sizeof "OUGH" - 1))
	return false;
      else
	from += sizeof "OUGH" - 1;
      while (*from == ' ' || *from == '\t')
	from++;
    }
  /* Whole comment contents (regex):
     [ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?
     [ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?
     [ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?
   */
  else
    {
      while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!')
	from++;
      unsigned char f = *from;
      bool all_upper = false;
      if (f == 'E' || f == 'e')
	{
	  if ((size_t) (pfile->buffer->cur - from)
	      < sizeof "else fallthru" - 1)
	    return false;
	  if (f == 'E' && memcmp (from + 1, "LSE", sizeof "LSE" - 1) == 0)
	    all_upper = true;
	  else if (memcmp (from + 1, "lse", sizeof "lse" - 1))
	    return false;
	  from += sizeof "else" - 1;
	  if (*from == ',')
	    from++;
	  if (*from != ' ')
	    return false;
	  from++;
	  if (all_upper && *from == 'f')
	    return false;
	  if (f == 'e' && *from == 'F')
	    return false;
	  f = *from;
	}
      else if (f == 'I' || f == 'i')
	{
	  if ((size_t) (pfile->buffer->cur - from)
	      < sizeof "intentional fallthru" - 1)
	    return false;
	  if (f == 'I' && memcmp (from + 1, "NTENTIONAL",
				  sizeof "NTENTIONAL" - 1) == 0)
	    all_upper = true;
	  else if (memcmp (from + 1, "ntentional",
			   sizeof "ntentional" - 1))
	    return false;
	  from += sizeof "intentional" - 1;
	  if (*from == ' ')
	    {
	      from++;
	      if (all_upper && *from == 'f')
		return false;
	    }
	  else if (all_upper)
	    {
	      if (memcmp (from, "LY F", sizeof "LY F" - 1))
		return false;
	      from += sizeof "LY " - 1;
	    }
	  else
	    {
	      if (memcmp (from, "ly ", sizeof "ly " - 1))
		return false;
	      from += sizeof "ly " - 1;
	    }
	  if (f == 'i' && *from == 'F')
	    return false;
	  f = *from;
	}
      if (f != 'F' && f != 'f')
	return false;
      if ((size_t) (pfile->buffer->cur - from) < sizeof "fallthru" - 1)
	return false;
      if (f == 'F' && memcmp (from + 1, "ALL", sizeof "ALL" - 1) == 0)
	all_upper = true;
      else if (all_upper)
	return false;
      else if (memcmp (from + 1, "all", sizeof "all" - 1))
	return false;
      from += sizeof "fall" - 1;
      if (*from == (all_upper ? 'S' : 's') && from[1] == ' ')
	from += 2;
      else if (*from == ' ' || *from == '-')
	from++;
      else if (*from != (all_upper ? 'T' : 't'))
	return false;
      if ((f == 'f' || *from != 'T') && (all_upper || *from != 't'))
	return false;
      if ((size_t) (pfile->buffer->cur - from) < sizeof "thru" - 1)
	return false;
      if (memcmp (from + 1, all_upper ? "HRU" : "hru", sizeof "hru" - 1))
	{
	  if ((size_t) (pfile->buffer->cur - from) < sizeof "through" - 1)
	    return false;
	  if (memcmp (from + 1, all_upper ? "HROUGH" : "hrough",
		      sizeof "hrough" - 1))
	    return false;
	  from += sizeof "through" - 1;
	}
      else
	from += sizeof "thru" - 1;
      while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!')
	from++;
      if (*from == '-')
	{
	  from++;
	  if (*comment_start == '*')
	    {
	      do
		{
		  while (*from && *from != '*'
			 && *from != '\n' && *from != '\r')
		    from++;
		  if (*from != '*' || from[1] == '/')
		    break;
		  from++;
		}
	      while (1);
	    }
	  else
	    while (*from && *from != '\n' && *from != '\r')
	      from++;
	}
    }
  /* C block comment.  */
  if (*comment_start == '*')
    {
      if (*from != '*' || from[1] != '/')
	return false;
    }
  /* C++ line comment.  */
  else if (*from != '\n')
    return false;

  return true;
}

/* Allocate COUNT tokens for RUN.  */
void
_cpp_init_tokenrun (tokenrun *run, unsigned int count)
{
  run->base = XNEWVEC (cpp_token, count);
  run->limit = run->base + count;
  run->next = NULL;
}

/* Returns the next tokenrun, or creates one if there is none.  */
static tokenrun *
next_tokenrun (tokenrun *run)
{
  if (run->next == NULL)
    {
      run->next = XNEW (tokenrun);
      run->next->prev = run;
      _cpp_init_tokenrun (run->next, 250);
    }

  return run->next;
}

/* Return the number of not yet processed token in a given
   context.  */
int
_cpp_remaining_tokens_num_in_context (cpp_context *context)
{
  if (context->tokens_kind == TOKENS_KIND_DIRECT)
    return (LAST (context).token - FIRST (context).token);
  else if (context->tokens_kind == TOKENS_KIND_INDIRECT
	   || context->tokens_kind == TOKENS_KIND_EXTENDED)
    return (LAST (context).ptoken - FIRST (context).ptoken);
  else
      abort ();
}

/* Returns the token present at index INDEX in a given context.  If
   INDEX is zero, the next token to be processed is returned.  */
static const cpp_token*
_cpp_token_from_context_at (cpp_context *context, int index)
{
  if (context->tokens_kind == TOKENS_KIND_DIRECT)
    return &(FIRST (context).token[index]);
  else if (context->tokens_kind == TOKENS_KIND_INDIRECT
	   || context->tokens_kind == TOKENS_KIND_EXTENDED)
    return FIRST (context).ptoken[index];
 else
   abort ();
}

/* Look ahead in the input stream.  */
const cpp_token *
cpp_peek_token (cpp_reader *pfile, int index)
{
  cpp_context *context = pfile->context;
  const cpp_token *peektok;
  int count;

  /* First, scan through any pending cpp_context objects.  */
  while (context->prev)
    {
      ptrdiff_t sz = _cpp_remaining_tokens_num_in_context (context);

      if (index < (int) sz)
        return _cpp_token_from_context_at (context, index);
      index -= (int) sz;
      context = context->prev;
    }

  /* We will have to read some new tokens after all (and do so
     without invalidating preceding tokens).  */
  count = index;
  pfile->keep_tokens++;

  /* For peeked tokens temporarily disable line_change reporting,
     until the tokens are parsed for real.  */
  void (*line_change) (cpp_reader *, const cpp_token *, int)
    = pfile->cb.line_change;
  pfile->cb.line_change = NULL;

  do
    {
      peektok = _cpp_lex_token (pfile);
      if (peektok->type == CPP_EOF)
	{
	  index--;
	  break;
	}
      else if (peektok->type == CPP_PRAGMA)
	{
	  /* Don't peek past a pragma.  */
	  if (peektok == &pfile->directive_result)
	    /* Save the pragma in the buffer.  */
	    *pfile->cur_token++ = *peektok;
	  index--;
	  break;
	}
    }
  while (index--);

  _cpp_backup_tokens_direct (pfile, count - index);
  pfile->keep_tokens--;
  pfile->cb.line_change = line_change;

  return peektok;
}

/* Allocate a single token that is invalidated at the same time as the
   rest of the tokens on the line.  Has its line and col set to the
   same as the last lexed token, so that diagnostics appear in the
   right place.  */
cpp_token *
_cpp_temp_token (cpp_reader *pfile)
{
  cpp_token *old, *result;
  ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token;
  ptrdiff_t la = (ptrdiff_t) pfile->lookaheads;

  old = pfile->cur_token - 1;
  /* Any pre-existing lookaheads must not be clobbered.  */
  if (la)
    {
      if (sz <= la)
        {
          tokenrun *next = next_tokenrun (pfile->cur_run);

          if (sz < la)
            memmove (next->base + 1, next->base,
                     (la - sz) * sizeof (cpp_token));

          next->base[0] = pfile->cur_run->limit[-1];
        }

      if (sz > 1)
        memmove (pfile->cur_token + 1, pfile->cur_token,
                 MIN (la, sz - 1) * sizeof (cpp_token));
    }

  if (!sz && pfile->cur_token == pfile->cur_run->limit)
    {
      pfile->cur_run = next_tokenrun (pfile->cur_run);
      pfile->cur_token = pfile->cur_run->base;
    }

  result = pfile->cur_token++;
  result->src_loc = old->src_loc;
  return result;
}

/* We're at the beginning of a logical line (so not in
  directives-mode) and RESULT is a CPP_NAME with NODE_MODULE set.  See
  if we should enter deferred_pragma mode to tokenize the rest of the
  line as a module control-line.  */

static void
cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result)
{
  unsigned backup = 0; /* Tokens we peeked.  */
  cpp_hashnode *node = result->val.node.node;
  cpp_token *peek = result;
  cpp_token *keyword = peek;
  cpp_hashnode *(&n_modules)[spec_nodes::M_HWM][2] = pfile->spec_nodes.n_modules;
  int header_count = 0;
  bool eol = false;

  /* Make sure the incoming state is as we expect it.  This way we
     can restore it using constants.  */
  gcc_checking_assert (!pfile->state.in_deferred_pragma
		       && !pfile->state.skipping
		       && !pfile->state.parsing_args
		       && !pfile->state.angled_headers
		       && (pfile->state.save_comments
			   == !CPP_OPTION (pfile, discard_comments)));

  /* Enter directives mode sufficiently for peeking.  We don't have
     to actually set in_directive.  */
  pfile->state.in_deferred_pragma = true;

  /* These two fields are needed to process tokenization in deferred
     pragma mode.  They are not used outside deferred pragma mode or
     directives mode.  */
  pfile->state.pragma_allow_expansion = true;
  pfile->directive_line = result->src_loc;

  /* Saving comments is incompatible with directives mode.   */
  pfile->state.save_comments = 0;

  if (node == n_modules[spec_nodes::M_EXPORT][0])
    {
      peek = _cpp_lex_direct (pfile);
      keyword = peek;
      backup++;
      if (keyword->type != CPP_NAME)
	goto not_module;
      node = keyword->val.node.node;
      if (!(node->flags & NODE_MODULE))
	goto not_module;
    }

  if (node == n_modules[spec_nodes::M__IMPORT][0])
    /* __import  */
    header_count = backup + 2 + 16;
  else if (node == n_modules[spec_nodes::M_IMPORT][0])
    /* import  */
    header_count = backup + 2 + (CPP_OPTION (pfile, preprocessed) ? 16 : 0);
  else if (node == n_modules[spec_nodes::M_MODULE][0])
    ; /* module  */
  else
    goto not_module;

  /* We've seen [export] {module|import|__import}.  Check the next token.  */
  if (header_count)
    /* After '{,__}import' a header name may appear.  */
    pfile->state.angled_headers = true;
  peek = _cpp_lex_direct (pfile);
  backup++;

  /* ... import followed by identifier, ':', '<' or
     header-name preprocessing tokens, or module
     followed by cpp-identifier, ':' or ';' preprocessing
     tokens.  C++ keywords are not yet relevant.  */
  if (peek->type == CPP_NAME
      || peek->type == CPP_COLON
      || (header_count
	  ? (peek->type == CPP_LESS
	     || (peek->type == CPP_STRING && peek->val.str.text[0] != 'R')
	     || peek->type == CPP_HEADER_NAME)
	   : peek->type == CPP_SEMICOLON))
    {
      pfile->state.pragma_allow_expansion = !CPP_OPTION (pfile, preprocessed);
      if (!pfile->state.pragma_allow_expansion)
	pfile->state.prevent_expansion++;

      if (!header_count && linemap_included_from
	  (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table)))
	cpp_error_with_line (pfile, CPP_DL_ERROR, keyword->src_loc, 0,
			     "module control-line cannot be in included file");

      /* The first one or two tokens cannot be macro names.  */
      for (int ix = backup; ix--;)
	{
	  cpp_token *tok = ix ? keyword : result;
	  cpp_hashnode *node = tok->val.node.node;

	  /* Don't attempt to expand the token.  */
	  tok->flags |= NO_EXPAND;
	  if (_cpp_defined_macro_p (node)
	      && _cpp_maybe_notify_macro_use (pfile, node, tok->src_loc)
	      && !cpp_fun_like_macro_p (node))
	    cpp_error_with_line (pfile, CPP_DL_ERROR, tok->src_loc, 0,
				 "module control-line %qs cannot be"
				 " an object-like macro",
				 NODE_NAME (node));
	}

      /* Map to underbar variants.  */
      keyword->val.node.node = n_modules[header_count
					 ? spec_nodes::M_IMPORT
					 : spec_nodes::M_MODULE][1];
      if (backup != 1)
	result->val.node.node = n_modules[spec_nodes::M_EXPORT][1];

      /* Maybe tell the tokenizer we expect a header-name down the
	 road.  */
      pfile->state.directive_file_token = header_count;

      /* According to P3034R1, pp-module-name and pp-module-partition tokens
	 if any shouldn't be macro expanded and identifiers shouldn't be
	 defined as object-like macro.  */
      if (!header_count && peek->type == CPP_NAME)
	{
	  int state = 0;
	  do
	    {
	      cpp_token *tok = peek;
	      if (tok->type == CPP_NAME)
		{
		  cpp_hashnode *node = tok->val.node.node;
		  /* Don't attempt to expand the token.  */
		  tok->flags |= NO_EXPAND;
		  if (_cpp_defined_macro_p (node)
		      && _cpp_maybe_notify_macro_use (pfile, node,
						      tok->src_loc)
		      && !cpp_fun_like_macro_p (node))
		    {
		      if (state == 0)
			cpp_error_with_line (pfile, CPP_DL_ERROR,
					     tok->src_loc, 0,
					     "module name %qs cannot "
					     "be an object-like macro",
					     NODE_NAME (node));
		      else
			cpp_error_with_line (pfile, CPP_DL_ERROR,
					     tok->src_loc, 0,
					     "module partition %qs cannot "
					     "be an object-like macro",
					     NODE_NAME (node));
		    }
		}
	      peek = _cpp_lex_direct (pfile);
	      backup++;
	      if (tok->type == CPP_NAME)
		{
		  if (peek->type == CPP_DOT)
		    continue;
		  else if (peek->type == CPP_COLON && state == 0)
		    {
		      ++state;
		      continue;
		    }
		  else if (peek->type == CPP_OPEN_PAREN)
		    {
		      if (state == 0)
			cpp_error_with_line (pfile, CPP_DL_ERROR,
					     peek->src_loc, 0,
					     "module name followed by %<(%>");
		      else
			cpp_error_with_line (pfile, CPP_DL_ERROR,
					     peek->src_loc, 0,
					     "module partition followed by "
					     "%<(%>");
		      break;
		    }
		  else if (peek->type == CPP_NAME
			   && _cpp_defined_macro_p (peek->val.node.node))
		    {
		      peek->flags |= NO_DOT_COLON;
		      break;
		    }
		  else
		    break;
		}
	      else if (peek->type != CPP_NAME)
		break;
	    }
	  while (true);
	}
    }
  else
    {
    not_module:
      /* Drop out of directive mode.  */
      /* We aaserted save_comments had this value upon entry.  */
      pfile->state.save_comments
	= !CPP_OPTION (pfile, discard_comments);
      pfile->state.in_deferred_pragma = false;
      /* Do not let this remain on.  */
      pfile->state.angled_headers = false;
      /* If we saw EOL, we should drop it, because this isn't a module
	 control-line after all.  */
      eol = peek->type == CPP_PRAGMA_EOL;
    }

  /* In either case we want to backup the peeked tokens.  */
  if (backup && (!eol || backup > 1))
    {
      /* Put the peeked tokens back.  */
      _cpp_backup_tokens_direct (pfile, backup);
      /* But if the last one was an EOL in the not_module case, forget it.  */
      if (eol)
	pfile->lookaheads--;
    }
}

/* Lex a token into RESULT (external interface).  Takes care of issues
   like directive handling, token lookahead, multiple include
   optimization and skipping.  */
const cpp_token *
_cpp_lex_token (cpp_reader *pfile)
{
  cpp_token *result;

  for (;;)
    {
      if (pfile->cur_token == pfile->cur_run->limit)
	{
	  pfile->cur_run = next_tokenrun (pfile->cur_run);
	  pfile->cur_token = pfile->cur_run->base;
	}
      /* We assume that the current token is somewhere in the current
	 run.  */
      if (pfile->cur_token < pfile->cur_run->base
	  || pfile->cur_token >= pfile->cur_run->limit)
	abort ();

      if (pfile->lookaheads)
	{
	  pfile->lookaheads--;
	  result = pfile->cur_token++;
	}
      else
	result = _cpp_lex_direct (pfile);

      if (result->flags & BOL)
	{
	  /* Is this a directive.  If _cpp_handle_directive returns
	     false, it is an assembler #.  */
	  if (result->type == CPP_HASH
	      /* 6.10.3 p 11: Directives in a list of macro arguments
		 gives undefined behavior.  This implementation
		 handles the directive as normal.  */
	      && pfile->state.parsing_args != 1)
	    {
	      if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
		{
		  if (pfile->directive_result.type == CPP_PADDING)
		    continue;
		  result = &pfile->directive_result;
		}
	    }
	  else if (pfile->state.in_deferred_pragma)
	    result = &pfile->directive_result;
	  else if (result->type == CPP_NAME
		   && (result->val.node.node->flags & NODE_MODULE)
		   && !pfile->state.skipping
		   /* Unlike regular directives, we do not deal with
		      tokenizing module directives as macro arguments.
		      That's not permitted.  */
		   && !pfile->state.parsing_args)
	    {
	      /* P1857.  Before macro expansion, At start of logical
		 line ... */
	      /* We don't have to consider lookaheads at this point.  */
	      gcc_checking_assert (!pfile->lookaheads);

	      cpp_maybe_module_directive (pfile, result);
	    }

	  if (pfile->cb.line_change && !pfile->state.skipping)
	    pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
	}

      /* We don't skip tokens in directives.  */
      if (pfile->state.in_directive || pfile->state.in_deferred_pragma)
	break;

      /* Outside a directive, invalidate controlling macros.  At file
	 EOF, _cpp_lex_direct takes care of popping the buffer, so we never
	 get here and MI optimization works.  */
      pfile->mi_valid = false;

      if (!pfile->state.skipping || result->type == CPP_EOF)
	break;
    }

  return result;
}

/* Returns true if a fresh line has been loaded.  */
template <bool lexing_raw_string>
static bool
get_fresh_line_impl (cpp_reader *pfile)
{
  /* We can't get a new line until we leave the current directive, unless we
     are lexing a raw string, in which case it will be OK as long as we don't
     pop the current buffer.  */
  if (!lexing_raw_string && pfile->state.in_directive)
    return false;

  for (;;)
    {
      cpp_buffer *buffer = pfile->buffer;

      if (!buffer->need_line)
	return true;

      if (buffer->next_line < buffer->rlimit)
	{
	  _cpp_clean_line (pfile);
	  return true;
	}

      /* We can't change buffers until we leave the current directive.  */
      if (lexing_raw_string && pfile->state.in_directive)
	return false;

      /* First, get out of parsing arguments state.  */
      if (pfile->state.parsing_args)
	return false;

      /* End of buffer.  Non-empty files should end in a newline.  */
      if (buffer->buf != buffer->rlimit
	  && buffer->next_line > buffer->rlimit
	  && !buffer->from_stage3)
	{
	  /* Clip to buffer size.  */
	  buffer->next_line = buffer->rlimit;
	}

      if (buffer->prev && !buffer->return_at_eof)
	_cpp_pop_buffer (pfile);
      else
	{
	  /* End of translation.  Do not pop the buffer yet. Increment
	     line number so that the EOF token is on a line of its own
	     (_cpp_lex_direct doesn't increment in that case, because
	     it's hard for it to distinguish this special case). */
	  CPP_INCREMENT_LINE (pfile, 0);
	  return false;
	}
    }
}

bool
_cpp_get_fresh_line (cpp_reader *pfile)
{
  return get_fresh_line_impl<false> (pfile);
}


#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE)		\
  do							\
    {							\
      result->type = ELSE_TYPE;				\
      if (*buffer->cur == CHAR)				\
	buffer->cur++, result->type = THEN_TYPE;	\
    }							\
  while (0)

/* Lex a token into pfile->cur_token, which is also incremented, to
   get diagnostics pointing to the correct location.

   Does not handle issues such as token lookahead, multiple-include
   optimization, directives, skipping etc.  This function is only
   suitable for use by _cpp_lex_token, and in special cases like
   lex_expansion_token which doesn't care for any of these issues.

   When meeting a newline, returns CPP_EOF if parsing a directive,
   otherwise returns to the start of the token buffer if permissible.
   Returns the location of the lexed token.  */
cpp_token *
_cpp_lex_direct (cpp_reader *pfile)
{
  cppchar_t c = 0;
  cpp_buffer *buffer;
  const unsigned char *comment_start;
  bool fallthrough_comment = false;
  cpp_token *result = pfile->cur_token++;

 fresh_line:
  result->flags = 0;
  buffer = pfile->buffer;
  if (buffer->need_line)
    {
      if (pfile->state.in_deferred_pragma)
	{
	  /* This can happen in cases like:
	     #define loop(x) whatever
	     #pragma omp loop
	     where when trying to expand loop we need to peek
	     next token after loop, but aren't still in_deferred_pragma
	     mode but are in in_directive mode, so buffer->need_line
	     is set, a CPP_EOF is peeked.  */
	  result->type = CPP_PRAGMA_EOL;
	  pfile->state.in_deferred_pragma = false;
	  if (!pfile->state.pragma_allow_expansion)
	    pfile->state.prevent_expansion--;
	  result->src_loc = pfile->line_table->highest_line;
	  return result;
	}
      if (!_cpp_get_fresh_line (pfile))
	{
	  result->type = CPP_EOF;
	  /* Not a real EOF in a directive or arg parsing -- we refuse
  	     to advance to the next file now, and will once we're out
  	     of those modes.  */
	  if (!pfile->state.in_directive && !pfile->state.parsing_args)
	    {
	      /* Tell the compiler the line number of the EOF token.  */
	      result->src_loc = pfile->line_table->highest_line;
	      result->flags = BOL;
	      /* Now pop the buffer that _cpp_get_fresh_line did not.  */
	      _cpp_pop_buffer (pfile);
	    }
	  else if (c == 0)
	    result->src_loc = pfile->line_table->highest_line;
	  return result;
	}
      if (buffer != pfile->buffer)
	fallthrough_comment = false;
      if (!pfile->keep_tokens)
	{
	  pfile->cur_run = &pfile->base_run;
	  result = pfile->base_run.base;
	  pfile->cur_token = result + 1;
	}
      result->flags = BOL;
      if (pfile->state.parsing_args == 2)
	result->flags |= PREV_WHITE;
    }
  buffer = pfile->buffer;
 update_tokens_line:
  result->src_loc = pfile->line_table->highest_line;

 skipped_white:
  if (buffer->cur >= buffer->notes[buffer->cur_note].pos
      && !pfile->overlaid_buffer)
    {
      _cpp_process_line_notes (pfile, false);
      result->src_loc = pfile->line_table->highest_line;
    }
  c = *buffer->cur++;

  if (pfile->forced_token_location)
    result->src_loc = pfile->forced_token_location;
  else
    result->src_loc = linemap_position_for_column (pfile->line_table,
					  CPP_BUF_COLUMN (buffer, buffer->cur));

  switch (c)
    {
    case ' ': case '\t': case '\f': case '\v': case '\0':
      result->flags |= PREV_WHITE;
      skip_whitespace (pfile, c);
      goto skipped_white;

    case '\n':
      /* Increment the line, unless this is the last line ...  */
      if (buffer->cur < buffer->rlimit
	  /* ... or this is a #include, (where _cpp_stack_file needs to
	     unwind by one line) ...  */
	  || (pfile->state.in_directive > 1
	      /* ... except traditional-cpp increments this elsewhere.  */
	      && !CPP_OPTION (pfile, traditional)))
	CPP_INCREMENT_LINE (pfile, 0);
      buffer->need_line = true;
      if (pfile->state.in_deferred_pragma)
	{
	  /* Produce the PRAGMA_EOL on this line.  File reading
	     ensures there is always a \n at end of the buffer, thus
	     in a deferred pragma we always see CPP_PRAGMA_EOL before
	     any CPP_EOF.  */
	  result->type = CPP_PRAGMA_EOL;
	  result->flags &= ~PREV_WHITE;
	  pfile->state.in_deferred_pragma = false;
	  if (!pfile->state.pragma_allow_expansion)
	    pfile->state.prevent_expansion--;
	  return result;
	}
      goto fresh_line;

    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      {
	struct normalize_state nst = INITIAL_NORMALIZE_STATE;
	result->type = CPP_NUMBER;
	lex_number (pfile, &result->val.str, &nst);
	warn_about_normalization (pfile, result, &nst, false);
	break;
      }

    case 'L':
    case 'u':
    case 'U':
    case 'R':
      /* 'L', 'u', 'U', 'u8' or 'R' may introduce wide characters,
	 wide strings or raw strings.  */
      if (c == 'L' || CPP_OPTION (pfile, rliterals)
	  || (c != 'R' && CPP_OPTION (pfile, uliterals)))
	{
	  if ((*buffer->cur == '\'' && c != 'R')
	      || *buffer->cur == '"'
	      || (*buffer->cur == 'R'
		  && c != 'R'
		  && buffer->cur[1] == '"'
		  && CPP_OPTION (pfile, rliterals))
	      || (*buffer->cur == '8'
		  && c == 'u'
		  && ((buffer->cur[1] == '"' || (buffer->cur[1] == '\''
				&& CPP_OPTION (pfile, utf8_char_literals)))
		      || (buffer->cur[1] == 'R' && buffer->cur[2] == '"'
			  && CPP_OPTION (pfile, rliterals)))))
	    {
	      lex_string (pfile, result, buffer->cur - 1);
	      break;
	    }
	}
      /* Fall through.  */

    case '_':
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
    case 's': case 't':           case 'v': case 'w': case 'x':
    case 'y': case 'z':
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    case 'G': case 'H': case 'I': case 'J': case 'K':
    case 'M': case 'N': case 'O': case 'P': case 'Q':
    case 'S': case 'T':           case 'V': case 'W': case 'X':
    case 'Y': case 'Z':
      result->type = CPP_NAME;
      {
	struct normalize_state nst = INITIAL_NORMALIZE_STATE;
	const auto node = lex_identifier (pfile, buffer->cur - 1, false, &nst,
					  &result->val.node.spelling);
	result->val.node.node = node;
	identifier_diagnostics_on_lex (pfile, node);
	warn_about_normalization (pfile, result, &nst, true);
      }

      /* Convert named operators to their proper types.  */
      if (result->val.node.node->flags & NODE_OPERATOR)
	{
	  result->flags |= NAMED_OP;
	  result->type = (enum cpp_ttype) result->val.node.node->directive_index;
	}

      /* Signal FALLTHROUGH comment followed by another token.  */
      if (fallthrough_comment)
	result->flags |= PREV_FALLTHROUGH;
      break;

    case '\'':
    case '"':
      lex_string (pfile, result, buffer->cur - 1);
      break;

    case '/':
      /* A potential block or line comment.  */
      comment_start = buffer->cur;
      c = *buffer->cur;

      if (c == '*')
	{
	  if (_cpp_skip_block_comment (pfile))
	    cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
	}
      else if (c == '/' && ! CPP_OPTION (pfile, traditional))
	{
	  /* Don't warn for system headers.  */
	  if (_cpp_in_system_header (pfile))
	    ;
	  /* Warn about comments if pedantically GNUC89, and not
	     in system headers.  */
	  else if (CPP_OPTION (pfile, lang) == CLK_GNUC89
		   && CPP_PEDANTIC (pfile)
		   && ! buffer->warned_cplusplus_comments)
	    {
	      if (cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				  "C++ style comments are not allowed "
				  "in ISO C90"))
		cpp_error (pfile, CPP_DL_NOTE,
			   "(this will be reported only once per input file)");
	      buffer->warned_cplusplus_comments = 1;
	    }
	  /* Or if specifically desired via -Wc90-c99-compat.  */
	  else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
		   && ! CPP_OPTION (pfile, cplusplus)
		   && ! buffer->warned_cplusplus_comments)
	    {
	      if (cpp_error (pfile, CPP_DL_WARNING,
			     "C++ style comments are incompatible with C90"))
		cpp_error (pfile, CPP_DL_NOTE,
			   "(this will be reported only once per input file)");
	      buffer->warned_cplusplus_comments = 1;
	    }
	  /* In C89/C94, C++ style comments are forbidden.  */
	  else if ((CPP_OPTION (pfile, lang) == CLK_STDC89
		    || CPP_OPTION (pfile, lang) == CLK_STDC94))
	    {
	      /* But don't be confused about valid code such as
	         - // immediately followed by *,
		 - // in a preprocessing directive,
		 - // in an #if 0 block.  */
	      if (buffer->cur[1] == '*'
		  || pfile->state.in_directive
		  || pfile->state.skipping)
		{
		  result->type = CPP_DIV;
		  break;
		}
	      else if (! buffer->warned_cplusplus_comments)
		{
		  if (cpp_error (pfile, CPP_DL_ERROR,
				 "C++ style comments are not allowed in "
				 "ISO C90"))
		    cpp_error (pfile, CPP_DL_NOTE,
			       "(this will be reported only once per input "
			       "file)");
		  buffer->warned_cplusplus_comments = 1;
		}
	    }
	  if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
	    cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment");
	}
      else if (c == '=')
	{
	  buffer->cur++;
	  result->type = CPP_DIV_EQ;
	  break;
	}
      else
	{
	  result->type = CPP_DIV;
	  break;
	}

      if (fallthrough_comment_p (pfile, comment_start))
	fallthrough_comment = true;

      if (pfile->cb.comment)
	{
	  size_t len = pfile->buffer->cur - comment_start;
	  pfile->cb.comment (pfile, result->src_loc, comment_start - 1,
			     len + 1);
	}

      if (!pfile->state.save_comments)
	{
	  result->flags |= PREV_WHITE;
	  goto update_tokens_line;
	}

      if (fallthrough_comment)
	result->flags |= PREV_FALLTHROUGH;

      /* Save the comment as a token in its own right.  */
      save_comment (pfile, result, comment_start, c);
      break;

    case '<':
      if (pfile->state.angled_headers)
	{
	  lex_string (pfile, result, buffer->cur - 1);
	  if (result->type != CPP_LESS)
	    break;
	}

      result->type = CPP_LESS;
      if (*buffer->cur == '=')
	{
	  buffer->cur++, result->type = CPP_LESS_EQ;
	  if (*buffer->cur == '>'
	      && CPP_OPTION (pfile, cplusplus)
	      && CPP_OPTION (pfile, lang) >= CLK_GNUCXX20)
	    buffer->cur++, result->type = CPP_SPACESHIP;
	}
      else if (*buffer->cur == '<')
	{
	  buffer->cur++;
	  IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT);
	}
      else if (CPP_OPTION (pfile, digraphs))
	{
	  if (*buffer->cur == ':')
	    {
	      /* C++11 [2.5/3 lex.pptoken], "Otherwise, if the next
		 three characters are <:: and the subsequent character
		 is neither : nor >, the < is treated as a preprocessor
		 token by itself".  */
	      if (CPP_OPTION (pfile, cplusplus)
		  && CPP_OPTION (pfile, lang) != CLK_CXX98
		  && CPP_OPTION (pfile, lang) != CLK_GNUCXX
		  && buffer->cur[1] == ':'
		  && buffer->cur[2] != ':' && buffer->cur[2] != '>')
		break;

	      buffer->cur++;
	      result->flags |= DIGRAPH;
	      result->type = CPP_OPEN_SQUARE;
	    }
	  else if (*buffer->cur == '%')
	    {
	      buffer->cur++;
	      result->flags |= DIGRAPH;
	      result->type = CPP_OPEN_BRACE;
	    }
	}
      break;

    case '>':
      result->type = CPP_GREATER;
      if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_GREATER_EQ;
      else if (*buffer->cur == '>')
	{
	  buffer->cur++;
	  IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT);
	}
      break;

    case '%':
      result->type = CPP_MOD;
      if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_MOD_EQ;
      else if (CPP_OPTION (pfile, digraphs))
	{
	  if (*buffer->cur == ':')
	    {
	      buffer->cur++;
	      result->flags |= DIGRAPH;
	      result->type = CPP_HASH;
	      if (*buffer->cur == '%' && buffer->cur[1] == ':')
		buffer->cur += 2, result->type = CPP_PASTE, result->val.token_no = 0;
	    }
	  else if (*buffer->cur == '>')
	    {
	      buffer->cur++;
	      result->flags |= DIGRAPH;
	      result->type = CPP_CLOSE_BRACE;
	    }
	}
      break;

    case '.':
      result->type = CPP_DOT;
      if (ISDIGIT (*buffer->cur))
	{
	  struct normalize_state nst = INITIAL_NORMALIZE_STATE;
	  result->type = CPP_NUMBER;
	  lex_number (pfile, &result->val.str, &nst);
	  warn_about_normalization (pfile, result, &nst, false);
	}
      else if (*buffer->cur == '.' && buffer->cur[1] == '.')
	buffer->cur += 2, result->type = CPP_ELLIPSIS;
      else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus))
	buffer->cur++, result->type = CPP_DOT_STAR;
      break;

    case '+':
      result->type = CPP_PLUS;
      if (*buffer->cur == '+')
	buffer->cur++, result->type = CPP_PLUS_PLUS;
      else if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_PLUS_EQ;
      break;

    case '-':
      result->type = CPP_MINUS;
      if (*buffer->cur == '>')
	{
	  buffer->cur++;
	  result->type = CPP_DEREF;
	  if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus))
	    buffer->cur++, result->type = CPP_DEREF_STAR;
	}
      else if (*buffer->cur == '-')
	buffer->cur++, result->type = CPP_MINUS_MINUS;
      else if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_MINUS_EQ;
      break;

    case '&':
      result->type = CPP_AND;
      if (*buffer->cur == '&')
	buffer->cur++, result->type = CPP_AND_AND;
      else if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_AND_EQ;
      break;

    case '|':
      result->type = CPP_OR;
      if (*buffer->cur == '|')
	buffer->cur++, result->type = CPP_OR_OR;
      else if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_OR_EQ;
      break;

    case ':':
      result->type = CPP_COLON;
      if (*buffer->cur == ':')
	{
	  if (CPP_OPTION (pfile, scope))
	    buffer->cur++, result->type = CPP_SCOPE;
	  else
	    result->flags |= COLON_SCOPE;
	}
      else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs))
	{
	  buffer->cur++;
	  result->flags |= DIGRAPH;
	  result->type = CPP_CLOSE_SQUARE;
	}
      break;

    case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break;
    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.token_no = 0; break;

    case '?': result->type = CPP_QUERY; break;
    case '~': result->type = CPP_COMPL; break;
    case ',': result->type = CPP_COMMA; break;
    case '(': result->type = CPP_OPEN_PAREN; break;
    case ')': result->type = CPP_CLOSE_PAREN; break;
    case '[': result->type = CPP_OPEN_SQUARE; break;
    case ']': result->type = CPP_CLOSE_SQUARE; break;
    case '{': result->type = CPP_OPEN_BRACE; break;
    case '}': result->type = CPP_CLOSE_BRACE; break;
    case ';': result->type = CPP_SEMICOLON; break;

      /* @ is a punctuator in Objective-C.  */
    case '@': result->type = CPP_ATSIGN; break;

    default:
      {
	const uchar *base = --buffer->cur;
	static int no_warn_cnt;

	/* Check for an extended identifier ($ or UCN or UTF-8).  */
	struct normalize_state nst = INITIAL_NORMALIZE_STATE;
	if (forms_identifier_p (pfile, true, &nst))
	  {
	    result->type = CPP_NAME;
	    const auto node = lex_identifier (pfile, base, true, &nst,
					      &result->val.node.spelling);
	    result->val.node.node = node;
	    identifier_diagnostics_on_lex (pfile, node);
	    warn_about_normalization (pfile, result, &nst, true);
	    break;
	  }

	/* Otherwise this will form a CPP_OTHER token.  Parse valid UTF-8 as a
	   single token.  */
	buffer->cur++;
	if (c >= utf8_signifier)
	  {
	    const uchar *pstr = base;
	    cppchar_t s;
	    if (_cpp_valid_utf8 (pfile, &pstr, buffer->rlimit, 0, NULL, &s))
	      {
		if (s > UCS_LIMIT && CPP_OPTION (pfile, cpp_warn_invalid_utf8))
		  {
		    buffer->cur = base;
		    _cpp_warn_invalid_utf8 (pfile);
		  }
		buffer->cur = pstr;
	      }
	    else if (CPP_OPTION (pfile, cpp_warn_invalid_utf8))
	      {
		buffer->cur = base;
		const uchar *end = _cpp_warn_invalid_utf8 (pfile);
		buffer->cur = base + 1;
		no_warn_cnt = end - buffer->cur;
	      }
	  }
	else if (c >= utf8_continuation
		 && CPP_OPTION (pfile, cpp_warn_invalid_utf8))
	  {
	    if (no_warn_cnt)
	      --no_warn_cnt;
	    else
	      {
		buffer->cur = base;
		_cpp_warn_invalid_utf8 (pfile);
		buffer->cur = base + 1;
	      }
	  }
	create_literal (pfile, result, base, buffer->cur - base, CPP_OTHER);
	break;
      }

    }

  /* Potentially convert the location of the token to a range.  */
  if (result->src_loc >= RESERVED_LOCATION_COUNT
      && result->type != CPP_EOF
      && !pfile->forced_token_location)
    {
      /* Ensure that any line notes are processed, so that we have the
	 correct physical line/column for the end-point of the token even
	 when a logical line is split via one or more backslashes.  */
      if (buffer->cur >= buffer->notes[buffer->cur_note].pos
	  && !pfile->overlaid_buffer)
	_cpp_process_line_notes (pfile, false);

      source_range tok_range;
      tok_range.m_start = result->src_loc;
      tok_range.m_finish
	= linemap_position_for_column (pfile->line_table,
				       CPP_BUF_COLUMN (buffer, buffer->cur));

      result->src_loc
	= pfile->line_table->get_or_create_combined_loc (result->src_loc,
							 tok_range, nullptr, 0);
    }

  return result;
}

/* An upper bound on the number of bytes needed to spell TOKEN.
   Does not include preceding whitespace.  */
unsigned int
cpp_token_len (const cpp_token *token)
{
  unsigned int len;

  switch (TOKEN_SPELL (token))
    {
    default:		len = 6;				break;
    case SPELL_LITERAL:	len = token->val.str.len;		break;
    case SPELL_IDENT:	len = NODE_LEN (token->val.node.node) * 10;	break;
    }

  return len;
}

/* Parse UTF-8 out of NAMEP and place a \U escape in BUFFER.
   Return the number of bytes read out of NAME.  (There are always
   10 bytes written to BUFFER.)  */

static size_t
utf8_to_ucn (unsigned char *buffer, const unsigned char *name)
{
  int j;
  int ucn_len = 0;
  int ucn_len_c;
  unsigned t;
  unsigned long utf32;

  /* Compute the length of the UTF-8 sequence.  */
  for (t = *name; t & 0x80; t <<= 1)
    ucn_len++;

  utf32 = *name & (0x7F >> ucn_len);
  for (ucn_len_c = 1; ucn_len_c < ucn_len; ucn_len_c++)
    {
      utf32 = (utf32 << 6) | (*++name & 0x3F);

      /* Ill-formed UTF-8.  */
      if ((*name & ~0x3F) != 0x80)
	abort ();
    }

  *buffer++ = '\\';
  *buffer++ = 'U';
  for (j = 7; j >= 0; j--)
    *buffer++ = "0123456789abcdef"[(utf32 >> (4 * j)) & 0xF];
  return ucn_len;
}

/* Given a token TYPE corresponding to a digraph, return a pointer to
   the spelling of the digraph.  */
static const unsigned char *
cpp_digraph2name (enum cpp_ttype type)
{
  return digraph_spellings[(int) type - (int) CPP_FIRST_DIGRAPH];
}

/* Write the spelling of an identifier IDENT, using UCNs, to BUFFER.
   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 *
_cpp_spell_ident_ucns (unsigned char *buffer, cpp_hashnode *ident)
{
  size_t i;
  const unsigned char *name = NODE_NAME (ident);

  for (i = 0; i < NODE_LEN (ident); i++)
    if (name[i] & ~0x7F)
      {
	i += utf8_to_ucn (buffer, name + i) - 1;
	buffer += 10;
      }
    else
      *buffer++ = name[i];

  return buffer;
}

/* Write the spelling of a token TOKEN to BUFFER.  The buffer must
   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
   if extended identifiers should always be written using UCNs (there is
   no option for always writing them in the internal UTF-8 form).
   FIXME: Would be nice if we didn't need the PFILE argument.  */
unsigned char *
cpp_spell_token (cpp_reader *pfile, const cpp_token *token,
		 unsigned char *buffer, bool forstring)
{
  switch (TOKEN_SPELL (token))
    {
    case SPELL_OPERATOR:
      {
	const unsigned char *spelling;
	unsigned char c;

	if (token->flags & DIGRAPH)
	  spelling = cpp_digraph2name (token->type);
	else if (token->flags & NAMED_OP)
	  goto spell_ident;
	else
	  spelling = TOKEN_NAME (token);

	while ((c = *spelling++) != '\0')
	  *buffer++ = c;
      }
      break;

    spell_ident:
    case SPELL_IDENT:
      if (forstring)
	{
	  memcpy (buffer, NODE_NAME (token->val.node.spelling),
		  NODE_LEN (token->val.node.spelling));
	  buffer += NODE_LEN (token->val.node.spelling);
	}
      else
	buffer = _cpp_spell_ident_ucns (buffer, token->val.node.node);
      break;

    case SPELL_LITERAL:
      memcpy (buffer, token->val.str.text, token->val.str.len);
      buffer += token->val.str.len;
      break;

    case SPELL_NONE:
      cpp_error (pfile, CPP_DL_ICE,
		 "unspellable token %s", TOKEN_NAME (token));
      break;
    }

  return buffer;
}

/* Returns TOKEN spelt as a null-terminated string.  The string is
   freed when the reader is destroyed.  Useful for diagnostics.  */
unsigned char *
cpp_token_as_text (cpp_reader *pfile, const cpp_token *token)
{
  unsigned int len = cpp_token_len (token) + 1;
  unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end;

  end = cpp_spell_token (pfile, token, start, false);
  end[0] = '\0';

  return start;
}

/* Returns a pointer to a string which spells the token defined by
   TYPE and FLAGS.  Used by C front ends, which really should move to
   using cpp_token_as_text.  */
const char *
cpp_type2name (enum cpp_ttype type, unsigned char flags)
{
  if (flags & DIGRAPH)
    return (const char *) cpp_digraph2name (type);
  else if (flags & NAMED_OP)
    return cpp_named_operator2name (type);

  return (const char *) token_spellings[type].name;
}

/* Writes the spelling of token to FP, without any preceding space.
   Separated from cpp_spell_token for efficiency - to avoid stdio
   double-buffering.  */
void
cpp_output_token (const cpp_token *token, FILE *fp)
{
  switch (TOKEN_SPELL (token))
    {
    case SPELL_OPERATOR:
      {
	const unsigned char *spelling;
	int c;

	if (token->flags & DIGRAPH)
	  spelling = cpp_digraph2name (token->type);
	else if (token->flags & NAMED_OP)
	  goto spell_ident;
	else
	  spelling = TOKEN_NAME (token);

	c = *spelling;
	do
	  putc (c, fp);
	while ((c = *++spelling) != '\0');
      }
      break;

    spell_ident:
    case SPELL_IDENT:
      {
	size_t i;
	const unsigned char * name = NODE_NAME (token->val.node.node);
	unsigned len = NODE_LEN (token->val.node.node);

	for (i = 0; i < len; i++)
	  if (name[i] & ~0x7F)
	    {
	      unsigned char buffer[10];
	      i += utf8_to_ucn (buffer, name + i) - 1;
	      fwrite (buffer, 1, 10, fp);
	    }
	  else if (name[i] == ' ' && i == len - 1)
	    /* Omit terminal space in "export ".  */;
	  else
	    fputc (NODE_NAME (token->val.node.node)[i], fp);
      }
      break;

    case SPELL_LITERAL:
      if (token->type == CPP_HEADER_NAME)
	fputc ('"', fp);
      fwrite (token->val.str.text, 1, token->val.str.len, fp);
      if (token->type == CPP_HEADER_NAME)
	fputc ('"', fp);
      break;

    case SPELL_NONE:
      /* An error, most probably.  */
      break;
    }
}

/* Compare two tokens.  */
int
_cpp_equiv_tokens (const cpp_token *a, const cpp_token *b)
{
  if (a->type == b->type && a->flags == b->flags)
    switch (TOKEN_SPELL (a))
      {
      default:			/* Keep compiler happy.  */
      case SPELL_OPERATOR:
	/* token_no is used to track where multiple consecutive ##
	   tokens were originally located.  */
	return (a->type != CPP_PASTE || a->val.token_no == b->val.token_no);
      case SPELL_NONE:
	return (a->type != CPP_MACRO_ARG
		|| (a->val.macro_arg.arg_no == b->val.macro_arg.arg_no
		    && a->val.macro_arg.spelling == b->val.macro_arg.spelling));
      case SPELL_IDENT:
	return (a->val.node.node == b->val.node.node
		&& a->val.node.spelling == b->val.node.spelling);
      case SPELL_LITERAL:
	return (a->val.str.len == b->val.str.len
		&& !memcmp (a->val.str.text, b->val.str.text,
			    a->val.str.len));
      }

  return 0;
}

/* Returns nonzero if a space should be inserted to avoid an
   accidental token paste for output.  For simplicity, it is
   conservative, and occasionally advises a space where one is not
   needed, e.g. "." and ".2".  */
int
cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1,
		 const cpp_token *token2)
{
  enum cpp_ttype a = token1->type, b = token2->type;
  cppchar_t c;

  if (token1->flags & NAMED_OP)
    a = CPP_NAME;
  if (token2->flags & NAMED_OP)
    b = CPP_NAME;

  c = EOF;
  if (token2->flags & DIGRAPH)
    c = digraph_spellings[(int) b - (int) CPP_FIRST_DIGRAPH][0];
  else if (token_spellings[b].category == SPELL_OPERATOR)
    c = token_spellings[b].name[0];

  /* Quickly get everything that can paste with an '='.  */
  if ((int) a <= (int) CPP_LAST_EQ && c == '=')
    return 1;

  switch (a)
    {
    case CPP_GREATER:	return c == '>';
    case CPP_LESS:	return c == '<' || c == '%' || c == ':';
    case CPP_PLUS:	return c == '+';
    case CPP_MINUS:	return c == '-' || c == '>';
    case CPP_DIV:	return c == '/' || c == '*'; /* Comments.  */
    case CPP_MOD:	return c == ':' || c == '>';
    case CPP_AND:	return c == '&';
    case CPP_OR:	return c == '|';
    case CPP_COLON:	return c == ':' || c == '>';
    case CPP_DEREF:	return c == '*';
    case CPP_DOT:	return c == '.' || c == '%' || b == CPP_NUMBER;
    case CPP_HASH:	return c == '#' || c == '%'; /* Digraph form.  */
    case CPP_PRAGMA:
    case CPP_NAME:	return ((b == CPP_NUMBER
				 && name_p (pfile, &token2->val.str))
				|| b == CPP_NAME
				|| b == CPP_CHAR || b == CPP_STRING); /* L */
    case CPP_NUMBER:	return (b == CPP_NUMBER || b == CPP_NAME
				|| b == CPP_CHAR
				|| c == '.' || c == '+' || c == '-');
				      /* UCNs */
    case CPP_OTHER:	return ((token1->val.str.text[0] == '\\'
				 && b == CPP_NAME)
				|| (CPP_OPTION (pfile, objc)
				    && token1->val.str.text[0] == '@'
				    && (b == CPP_NAME || b == CPP_STRING)));
    case CPP_LESS_EQ:	return c == '>';
    case CPP_STRING:
    case CPP_WSTRING:
    case CPP_UTF8STRING:
    case CPP_STRING16:
    case CPP_STRING32:	return (CPP_OPTION (pfile, user_literals)
				&& (b == CPP_NAME
				    || (TOKEN_SPELL (token2) == SPELL_LITERAL
					&& ISIDST (token2->val.str.text[0]))));

    default:		break;
    }

  return 0;
}

/* Output all the remaining tokens on the current line, and a newline
   character, to FP.  Leading whitespace is removed.  If there are
   macros, special token padding is not performed.  */
void
cpp_output_line (cpp_reader *pfile, FILE *fp)
{
  const cpp_token *token;

  token = cpp_get_token (pfile);
  while (token->type != CPP_EOF)
    {
      cpp_output_token (token, fp);
      token = cpp_get_token (pfile);
      if (token->flags & PREV_WHITE)
	putc (' ', fp);
    }

  putc ('\n', fp);
}

/* Return a string representation of all the remaining tokens on the
   current line.  The result is allocated using xmalloc and must be
   freed by the caller.  */
unsigned char *
cpp_output_line_to_string (cpp_reader *pfile, const unsigned char *dir_name)
{
  const cpp_token *token;
  unsigned int out = dir_name ? ustrlen (dir_name) : 0;
  unsigned int alloced = 120 + out;
  unsigned char *result = (unsigned char *) xmalloc (alloced);

  /* If DIR_NAME is empty, there are no initial contents.  */
  if (dir_name)
    {
      sprintf ((char *) result, "#%s ", dir_name);
      out += 2;
    }

  token = cpp_get_token (pfile);
  while (token->type != CPP_EOF)
    {
      unsigned char *last;
      /* Include room for a possible space and the terminating nul.  */
      unsigned int len = cpp_token_len (token) + 2;

      if (out + len > alloced)
	{
	  alloced *= 2;
	  if (out + len > alloced)
	    alloced = out + len;
	  result = (unsigned char *) xrealloc (result, alloced);
	}

      last = cpp_spell_token (pfile, token, &result[out], 0);
      out = last - result;

      token = cpp_get_token (pfile);
      if (token->flags & PREV_WHITE)
	result[out++] = ' ';
    }

  result[out] = '\0';
  return result;
}

/* Memory buffers.  Changing these three constants can have a dramatic
   effect on performance.  The values here are reasonable defaults,
   but might be tuned.  If you adjust them, be sure to test across a
   range of uses of cpplib, including heavy nested function-like macro
   expansion.  Also check the change in peak memory usage (NJAMD is a
   good tool for this).  */
#define MIN_BUFF_SIZE 8000
#define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2)
#define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \
	(MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2)

#if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0)
  #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE!
#endif

/* Create a new allocation buffer.  Place the control block at the end
   of the buffer, so that buffer overflows will cause immediate chaos.  */
static _cpp_buff *
new_buff (size_t len)
{
  _cpp_buff *result;
  unsigned char *base;

  if (len < MIN_BUFF_SIZE)
    len = MIN_BUFF_SIZE;
  len = CPP_ALIGN (len);

#ifdef ENABLE_VALGRIND_WORKAROUNDS
  /* Valgrind warns about uses of interior pointers, so put _cpp_buff
     struct first.  */
  size_t slen = CPP_ALIGN2 (sizeof (_cpp_buff), 2 * DEFAULT_ALIGNMENT);
  base = XNEWVEC (unsigned char, len + slen);
  result = (_cpp_buff *) base;
  base += slen;
#else
  base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff));
  result = (_cpp_buff *) (base + len);
#endif
  result->base = base;
  result->cur = base;
  result->limit = base + len;
  result->next = NULL;
  return result;
}

/* Place a chain of unwanted allocation buffers on the free list.  */
void
_cpp_release_buff (cpp_reader *pfile, _cpp_buff *buff)
{
  _cpp_buff *end = buff;

  while (end->next)
    end = end->next;
  end->next = pfile->free_buffs;
  pfile->free_buffs = buff;
}

/* Return a free buffer of size at least MIN_SIZE.  */
_cpp_buff *
_cpp_get_buff (cpp_reader *pfile, size_t min_size)
{
  _cpp_buff *result, **p;

  for (p = &pfile->free_buffs;; p = &(*p)->next)
    {
      size_t size;

      if (*p == NULL)
	return new_buff (min_size);
      result = *p;
      size = result->limit - result->base;
      /* Return a buffer that's big enough, but don't waste one that's
         way too big.  */
      if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size))
	break;
    }

  *p = result->next;
  result->next = NULL;
  result->cur = result->base;
  return result;
}

/* Creates a new buffer with enough space to hold the uncommitted
   remaining bytes of BUFF, and at least MIN_EXTRA more bytes.  Copies
   the excess bytes to the new buffer.  Chains the new buffer after
   BUFF, and returns the new buffer.  */
_cpp_buff *
_cpp_append_extend_buff (cpp_reader *pfile, _cpp_buff *buff, size_t min_extra)
{
  size_t size = EXTENDED_BUFF_SIZE (buff, min_extra);
  _cpp_buff *new_buff = _cpp_get_buff (pfile, size);

  buff->next = new_buff;
  memcpy (new_buff->base, buff->cur, BUFF_ROOM (buff));
  return new_buff;
}

/* Creates a new buffer with enough space to hold the uncommitted
   remaining bytes of the buffer pointed to by BUFF, and at least
   MIN_EXTRA more bytes.  Copies the excess bytes to the new buffer.
   Chains the new buffer before the buffer pointed to by BUFF, and
   updates the pointer to point to the new buffer.  */
void
_cpp_extend_buff (cpp_reader *pfile, _cpp_buff **pbuff, size_t min_extra)
{
  _cpp_buff *new_buff, *old_buff = *pbuff;
  size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra);

  new_buff = _cpp_get_buff (pfile, size);
  memcpy (new_buff->base, old_buff->cur, BUFF_ROOM (old_buff));
  new_buff->next = old_buff;
  *pbuff = new_buff;
}

/* Free a chain of buffers starting at BUFF.  */
void
_cpp_free_buff (_cpp_buff *buff)
{
  _cpp_buff *next;

  for (; buff; buff = next)
    {
      next = buff->next;
#ifdef ENABLE_VALGRIND_WORKAROUNDS
      free (buff);
#else
      free (buff->base);
#endif
    }
}

/* Allocate permanent, unaligned storage of length LEN.  */
unsigned char *
_cpp_unaligned_alloc (cpp_reader *pfile, size_t len)
{
  _cpp_buff *buff = pfile->u_buff;
  unsigned char *result = buff->cur;

  if (len > (size_t) (buff->limit - result))
    {
      buff = _cpp_get_buff (pfile, len);
      buff->next = pfile->u_buff;
      pfile->u_buff = buff;
      result = buff->cur;
    }

  buff->cur = result + len;
  return result;
}

/* Allocate permanent, unaligned storage of length LEN from a_buff.
   That buffer is used for growing allocations when saving macro
   replacement lists in a #define, and when parsing an answer to an
   assertion in #assert, #unassert or #if (and therefore possibly
   whilst expanding macros).  It therefore must not be used by any
   code that they might call: specifically the lexer and the guts of
   the macro expander.

   All existing other uses clearly fit this restriction: storing
   registered pragmas during initialization.  */
unsigned char *
_cpp_aligned_alloc (cpp_reader *pfile, size_t len)
{
  _cpp_buff *buff = pfile->a_buff;
  unsigned char *result = buff->cur;

  if (len > (size_t) (buff->limit - result))
    {
      buff = _cpp_get_buff (pfile, len);
      buff->next = pfile->a_buff;
      pfile->a_buff = buff;
      result = buff->cur;
    }

  buff->cur = result + len;
  return result;
}

/* Commit or allocate storage from a buffer.  */

void *
_cpp_commit_buff (cpp_reader *pfile, size_t size)
{
  const auto buff = pfile->a_buff;
  void *ptr = BUFF_FRONT (buff);

  if (pfile->hash_table->alloc_subobject)
    {
      void *copy = pfile->hash_table->alloc_subobject (size);
      memcpy (copy, ptr, size);
      ptr = copy;
    }
  else
    {
      BUFF_FRONT (buff) += size;
      /* Make sure the remaining space is maximally aligned for whatever this
	 buffer holds next.  */
      BUFF_FRONT (buff) += BUFF_ROOM (buff) % DEFAULT_ALIGNMENT;
    }

  return ptr;
}

/* Say which field of TOK is in use.  */

enum cpp_token_fld_kind
cpp_token_val_index (const cpp_token *tok)
{
  switch (TOKEN_SPELL (tok))
    {
    case SPELL_IDENT:
      return CPP_TOKEN_FLD_NODE;
    case SPELL_LITERAL:
      return CPP_TOKEN_FLD_STR;
    case SPELL_OPERATOR:
      /* Operands which were originally spelled as ident keep around
         the node for the exact spelling.  */
      if (tok->flags & NAMED_OP)
	return CPP_TOKEN_FLD_NODE;
      else if (tok->type == CPP_PASTE)
	return CPP_TOKEN_FLD_TOKEN_NO;
      else
	return CPP_TOKEN_FLD_NONE;
    case SPELL_NONE:
      if (tok->type == CPP_MACRO_ARG)
	return CPP_TOKEN_FLD_ARG_NO;
      else if (tok->type == CPP_PADDING)
	return CPP_TOKEN_FLD_SOURCE;
      else if (tok->type == CPP_PRAGMA)
	return CPP_TOKEN_FLD_PRAGMA;
      /* fall through */
    default:
      return CPP_TOKEN_FLD_NONE;
    }
}

/* All tokens lexed in R after calling this function will be forced to
   have their location_t to be P, until
   cpp_stop_forcing_token_locations is called for R.  */

void
cpp_force_token_locations (cpp_reader *r, location_t loc)
{
  r->forced_token_location = loc;
}

/* Go back to assigning locations naturally for lexed tokens.  */

void
cpp_stop_forcing_token_locations (cpp_reader *r)
{
  r->forced_token_location = 0;
}

/* We're looking at \, if it's escaping EOL, look past it.  If at
   LIMIT, don't advance.  */

static const unsigned char *
do_peek_backslash (const unsigned char *peek, const unsigned char *limit)
{
  const unsigned char *probe = peek;

  if (__builtin_expect (peek[1] == '\n', true))
    {
    eol:
      probe += 2;
      if (__builtin_expect (probe < limit, true))
	{
	  peek = probe;
	  if (*peek == '\\')
	    /* The user might be perverse.  */
	    return do_peek_backslash (peek, limit);
	}
    }
  else if (__builtin_expect (peek[1] == '\r', false))
    {
      if (probe[2] == '\n')
	probe++;
      goto eol;
    }

  return peek;
}

static const unsigned char *
do_peek_next (const unsigned char *peek, const unsigned char *limit)
{
  if (__builtin_expect (*peek == '\\', false))
    peek = do_peek_backslash (peek, limit);
  return peek;
}

static const unsigned char *
do_peek_prev (const unsigned char *peek, const unsigned char *bound)
{
  if (peek == bound)
    return NULL;

  unsigned char c = *--peek;
  if (__builtin_expect (c == '\n', false)
      || __builtin_expect (c == '\r', false))
    {
      if (peek == bound)
	return peek;
      int ix = -1;
      if (c == '\n' && peek[ix] == '\r')
	{
	  if (peek + ix == bound)
	    return peek;
	  ix--;
	}

      if (peek[ix] == '\\')
	return do_peek_prev (peek + ix, bound);

      return peek;
    }
  else
    return peek;
}

/* If PEEK[-1] is identifier MATCH, scan past it and trailing white
   space.  Otherwise return NULL.  */

static const unsigned char *
do_peek_ident (const char *match, const unsigned char *peek,
	       const unsigned char *limit)
{
  for (; *++match; peek++)
    if (*peek != *match)
      {
	peek = do_peek_next (peek, limit);
	if (*peek != *match)
	  return NULL;
      }

  /* Must now not be looking at an identifier char.  */
  peek = do_peek_next (peek, limit);
  if (ISIDNUM (*peek))
    return NULL;

  /* Skip control-line whitespace.  */
 ws:
  while (*peek == ' ' || *peek == '\t')
    peek++;
  if (__builtin_expect (*peek == '\\', false))
    {
      peek = do_peek_backslash (peek, limit);
      if (*peek != '\\')
	goto ws;
    }

  return peek;
}

/* Are we looking at a module control line starting as PEEK - 1?  */

static bool
do_peek_module (cpp_reader *pfile, unsigned char c,
		const unsigned char *peek, const unsigned char *limit)
{
  bool import = false;

  if (__builtin_expect (c == 'e', false))
    {
      if (!((peek[0] == 'x' || peek[0] == '\\')
	    && (peek = do_peek_ident ("export", peek, limit))))
	return false;

      /* export, peek for import or module.  No need to peek __import
	 here.  */
      if (peek[0] == 'i')
	{
	  if (!((peek[1] == 'm' || peek[1] == '\\')
		&& (peek = do_peek_ident ("import", peek + 1, limit))))
	    return false;
	  import = true;
	}
      else if (peek[0] == 'm')
	{
	  if (!((peek[1] == 'o' || peek[1] == '\\')
		&& (peek = do_peek_ident ("module", peek + 1, limit))))
	    return false;
	}
      else
	return false;
    }
  else if (__builtin_expect (c == 'i', false))
    {
      if (!((peek[0] == 'm' || peek[0] == '\\')
	    && (peek = do_peek_ident ("import", peek, limit))))
	return false;
      import = true;
    }
  else if (__builtin_expect (c == '_', false))
    {
      /* Needed for translated includes.   */
      if (!((peek[0] == '_' || peek[0] == '\\')
	    && (peek = do_peek_ident ("__import", peek, limit))))
	return false;
      import = true;
    }
  else if (__builtin_expect (c == 'm', false))
    {
      if (!((peek[0] == 'o' || peek[0] == '\\')
	    && (peek = do_peek_ident ("module", peek, limit))))
	return false;
    }
  else
    return false;

  /* Peek the next character to see if it's good enough.  We'll be at
     the first non-whitespace char, including skipping an escaped
     newline.  */
  /* ... import followed by identifier, ':', '<' or header-name
     preprocessing tokens, or module followed by identifier, ':' or
     ';' preprocessing tokens.  */
  unsigned char p = *peek++;

  /* A character literal is ... single quotes, ... optionally preceded
     by u8, u, U, or L */
  /* A string-literal is a ... double quotes, optionally prefixed by
     R, u8, u8R, u, uR, U, UR, L, or LR */
  if (p == 'u')
    {
      peek = do_peek_next (peek, limit);
      if (*peek == '8')
	{
	  peek++;
	  goto peek_u8;
	}
      goto peek_u;
    }
  else if (p == 'U' || p == 'L')
    {
    peek_u8:
      peek = do_peek_next (peek, limit);
    peek_u:
      if (*peek == '\"' || *peek == '\'')
	return false;

      if (*peek == 'R')
	goto peek_R;
      /* Identifier. Ok.  */
    }
  else if (p == 'R')
    {
    peek_R:
      if (CPP_OPTION (pfile, rliterals))
	{
	  peek = do_peek_next (peek, limit);
	  if (*peek == '\"')
	    return false;
	}
      /* Identifier. Ok.  */
    }
  else if ('Z' - 'A' == 25
	   ? ((p >= 'A' && p <= 'Z') || (p >= 'a' && p <= 'z') || p == '_')
	   : ISIDST (p))
    {
      /* Identifier.  Ok. */
    }
  else if (p == '<')
    {
      /* Maybe angle header, ok for import.  Reject
	 '<=', '<<' digraph:'<:'.  */
      if (!import)
	return false;
      peek = do_peek_next (peek, limit);
      if (*peek == '=' || *peek == '<'
	  || (*peek == ':' && CPP_OPTION (pfile, digraphs)))
	return false;
    }
  else if (p == ';')
    {
      /* SEMICOLON, ok for module.  */
      if (import)
	return false;
    }
  else if (p == '"')
    {
      /* STRING, ok for import.  */
      if (!import)
	return false;
    }
  else if (p == ':')
    {
      /* Maybe COLON, ok.  Reject '::', digraph:':>'.  */
      peek = do_peek_next (peek, limit);
      if (*peek == ':' || (*peek == '>' && CPP_OPTION (pfile, digraphs)))
	return false;
    }
  else
    /* FIXME: Detect a unicode character, excluding those not
       permitted as the initial character. [lex.name]/1.  I presume
       we need to check the \[uU] spellings, and directly using
       Unicode in say UTF8 form?  Or perhaps we do the phase-1
       conversion of UTF8 to universal-character-names?  */
    return false;

  return true;
}

/* Directives-only scanning.  Somewhat more relaxed than correct
   parsing -- some ill-formed programs will not be rejected.  */

void
cpp_directive_only_process (cpp_reader *pfile,
			    void *data,
			    void (*cb) (cpp_reader *, CPP_DO_task, void *, ...))
{
  bool module_p = CPP_OPTION (pfile, module_directives);

  do
    {
    restart:
      /* Buffer initialization, but no line cleaning. */
      cpp_buffer *buffer = pfile->buffer;
      buffer->cur_note = buffer->notes_used = 0;
      buffer->cur = buffer->line_base = buffer->next_line;
      buffer->need_line = false;
      /* Files always end in a newline or carriage return.  We rely on this for
	 character peeking safety.  */
      gcc_assert (buffer->rlimit[0] == '\n' || buffer->rlimit[0] == '\r');

      const unsigned char *base = buffer->cur;
      unsigned line_count = 0;
      const unsigned char *line_start = base;

      bool bol = true;
      bool raw = false;

      const unsigned char *lwm = base;
      for (const unsigned char *pos = base, *limit = buffer->rlimit;
	   pos < limit;)
	{
	  unsigned char c = *pos++;
	  /* This matches the switch in _cpp_lex_direct.  */
	  switch (c)
	    {
	    case ' ': case '\t': case '\f': case '\v':
	      /* Whitespace, do nothing.  */
	      break;

	    case '\r': /* MAC line ending, or Windows \r\n  */
	      if (*pos == '\n')
		pos++;
	      /* FALLTHROUGH */

	    case '\n':
	      bol = true;

	    next_line:
	      CPP_INCREMENT_LINE (pfile, 0);
	      line_count++;
	      line_start = pos;
	      break;

	    case '\\':
	      /* <backslash><newline> is removed, and doesn't undo any
		 preceeding escape or whatnot.  */
	      if (*pos == '\n')
		{
		  pos++;
		  goto next_line;
		}
	      else if (*pos == '\r')
		{
		  if (pos[1] == '\n')
		    pos++;
		  pos++;
		  goto next_line;
		}
	      goto dflt;

	    case '#':
	      if (bol)
		{
		  /* Line directive.  */
		  if (pos - 1 > base && !pfile->state.skipping)
		    cb (pfile, CPP_DO_print, data,
			line_count, base, pos - 1 - base);

		  /* Prep things for directive handling. */
		  buffer->next_line = pos;
		  buffer->need_line = true;
		  bool ok = _cpp_get_fresh_line (pfile);
		  gcc_checking_assert (ok);

		  /* Ensure proper column numbering for generated
		     error messages. */
		  buffer->line_base -= pos - line_start;

		  if (_cpp_handle_directive (pfile, line_start + 1 != pos) == 2)
		    {
		      if (pfile->directive_result.type != CPP_PADDING)
			cb (pfile, CPP_DO_token, data,
			    &pfile->directive_result, pfile->directive_result.src_loc);
		      if (pfile->context->prev)
			{
			  gcc_assert (pfile->context->tokens_kind == TOKENS_KIND_DIRECT);
			  for (const cpp_token *tok = FIRST (pfile->context).token;
			       tok != LAST (pfile->context).token; ++tok)
			    cb (pfile, CPP_DO_token, data, tok, tok->src_loc);
			  _cpp_pop_context (pfile);
			}
		    }

		  /* Sanitize the line settings.  Duplicate #include's can
		     mess things up. */
		  // FIXME: Necessary?
		  pfile->line_table->highest_location
		    = pfile->line_table->highest_line;

		  if (!pfile->state.skipping
		      && pfile->buffer->next_line < pfile->buffer->rlimit)
		    cb (pfile, CPP_DO_location, data,
			pfile->line_table->highest_line);

		  goto restart;
		}
	      goto dflt;

	    case '/':
	      {
		const unsigned char *peek = do_peek_next (pos, limit);
		if (!(*peek == '/' || *peek == '*'))
		  goto dflt;

		/* Line or block comment  */
		bool is_block = *peek == '*';
		bool star = false;
		bool esc = false;
		location_t sloc
		  = linemap_position_for_column (pfile->line_table,
						 pos - line_start);

		while (pos < limit)
		  {
		    char c = *pos++;
		    switch (c)
		      {
		      case '\\':
			esc = true;
			break;

		      case '\r':
			if (*pos == '\n')
			  pos++;
			/* FALLTHROUGH  */

		      case '\n':
			{
			  CPP_INCREMENT_LINE (pfile, 0);
			  line_count++;
			  line_start = pos;
			  if (!esc && !is_block)
			    {
			      bol = true;
			      goto done_comment;
			    }
			}
			if (!esc)
			  star = false;
			esc = false;
			break;

		      case '*':
			if (pos > peek)
			  star = is_block;
			esc = false;
			break;

		      case '/':
			if (star)
			  goto done_comment;
			/* FALLTHROUGH  */

		      default:
			star = false;
			esc = false;
			break;
		      }
		  }
		if (pos < limit || is_block)
		  cpp_error_with_line (pfile, CPP_DL_ERROR, sloc, 0,
				       "unterminated comment");
	      done_comment:
		lwm = pos;
		break;
	      }

	    case '\'':
	      if (!CPP_OPTION (pfile, digit_separators))
		goto delimited_string;

	      /* Possibly a number punctuator.  */
	      if (!ISIDNUM (*do_peek_next (pos, limit)))
		goto delimited_string;

	      goto quote_peek;

	    case '\"':
	      if (!CPP_OPTION (pfile, rliterals))
		goto delimited_string;

	    quote_peek:
	      {
		/* For ' see if it's a number punctuator
		   \.?<digit>(<digit>|<identifier-nondigit>
		   |'<digit>|'<nondigit>|[eEpP]<sign>|\.)* */
		/* For " see if it's a raw string
		   {U,L,u,u8}R.  This includes CPP_NUMBER detection,
		   because that could be 0e+R.  */
		const unsigned char *peek = pos - 1;
		bool quote_first = c == '"';
		bool quote_eight = false;
		bool maybe_number_start = false;
		bool want_number = false;

		while ((peek = do_peek_prev (peek, lwm)))
		  {
		    unsigned char p = *peek;
		    if (quote_first)
		      {
			if (!raw)
			  {
			    if (p != 'R')
			      break;
			    raw = true;
			    continue;
			  }

			quote_first = false;
			if (p == 'L' || p == 'U' || p == 'u')
			  ;
			else if (p == '8')
			  quote_eight = true;
			else
			  goto second_raw;
		      }
		    else if (quote_eight)
		      {
			if (p != 'u')
			  {
			    raw = false;
			    break;
			  }
			quote_eight = false;
		      }
		    else if (c == '"')
		      {
		      second_raw:;
			if (!want_number && ISIDNUM (p))
			  {
			    raw = false;
			    break;
			  }
		      }

		    if (ISDIGIT (p))
		      maybe_number_start = true;
		    else if (p == '.')
		      want_number = true;
		    else if (ISIDNUM (p))
		      maybe_number_start = false;
		    else if (p == '+' || p == '-')
		      {
			if (const unsigned char *peek_prev
			    = do_peek_prev (peek, lwm))
			  {
			    p = *peek_prev;
			    if (p == 'e' || p == 'E'
				|| p == 'p' || p == 'P')
			      {
				want_number = true;
				maybe_number_start = false;
			      }
			    else
			      break;
			  }
			else
			  break;
		      }
		    else if (p == '\'' || p == '\"')
		      {
			/* If this is lwm, this must be the end of a
			   previous string.  So this is a trailing
			   literal type, (a) if those are allowed,
			     and (b) maybe_start is false.  Otherwise
			     this must be a CPP_NUMBER because we've
			     met another ', and we'd have checked that
			     in its own right.  */
			if (peek == lwm && CPP_OPTION (pfile, uliterals))
			  {
			    if  (!maybe_number_start && !want_number)
			      /* Must be a literal type.  */
			      raw = false;
			  }
			else if (p == '\''
				 && CPP_OPTION (pfile, digit_separators))
			  maybe_number_start = true;
			break;
		      }
		    else if (c == '\'')
		      break;
		    else if (!quote_first && !quote_eight)
		      break;
		  }

		if (maybe_number_start)
		  {
		    if (c == '\'')
		      /* A CPP NUMBER.  */
		      goto dflt;
		    raw = false;
		  }

		goto delimited_string;
	      }

	    delimited_string:
	      {
		/* (Possibly raw) string or char literal.  */
		unsigned char end = c;
		int delim_len = -1;
		const unsigned char *delim = NULL;
		location_t sloc = linemap_position_for_column (pfile->line_table,
							       pos - line_start);
		int esc = 0;

		if (raw)
		  {
		    /* There can be no line breaks in the delimiter.  */
		    delim = pos;
		    for (delim_len = 0; (c = *pos++) != '('; delim_len++)
		      {
			if (delim_len == 16)
			  {
			    cpp_error_with_line (pfile, CPP_DL_ERROR,
						 sloc, 0,
						 "raw string delimiter"
						 " longer than %d"
						 " characters",
						 delim_len);
			    raw = false;
			    pos = delim;
			    break;
			  }
			if (strchr (") \\\t\v\f\n", c))
			  {
			    cpp_error_with_line (pfile, CPP_DL_ERROR,
						 sloc, 0,
						 "invalid character '%c'"
						 " in raw string"
						 " delimiter", c);
			    raw = false;
			    pos = delim;
			    break;
			  }
			if (pos >= limit)
			  goto bad_string;
		      }
		  }

		while (pos < limit)
		  {
		    char c = *pos++;
		    switch (c)
		      {
		      case '\\':
			if (!raw)
			  esc++;
			break;

		      case '\r':
			if (*pos == '\n')
			  pos++;
			/* FALLTHROUGH  */

		      case '\n':
			{
			  CPP_INCREMENT_LINE (pfile, 0);
			  line_count++;
			  line_start = pos;
			}
			if (esc)
			  esc--;
			break;

		      case ')':
			if (raw
			    && pos + delim_len + 1 < limit
			    && pos[delim_len] == end
			    && !memcmp (delim, pos, delim_len))
			  {
			    pos += delim_len + 1;
			    raw = false;
			    goto done_string;
			  }
			break;

		      default:
			if (!raw && !(esc & 1) && c == end)
			  goto done_string;
			esc = 0;
			break;
		      }
		  }
	      bad_string:
		cpp_error_with_line (pfile, CPP_DL_ERROR, sloc, 0,
				     "unterminated literal");

	      done_string:
		raw = false;
		lwm = pos - 1;
	      }
	      goto dflt;

	    case '_':
	    case 'e':
	    case 'i':
	    case 'm':
	      if (bol && module_p && !pfile->state.skipping
		  && do_peek_module (pfile, c, pos, limit))
		{
		  /* We've seen the start of a module control line.
		     Start up the tokenizer.  */
		  pos--; /* Backup over the first character.  */

		  /* Backup over whitespace to start of line.  */
		  while (pos > line_start
			 && (pos[-1] == ' ' || pos[-1] == '\t'))
		    pos--;

		  if (pos > base)
		    cb (pfile, CPP_DO_print, data, line_count, base, pos - base);

		  /* Prep things for directive handling. */
		  buffer->next_line = pos;
		  buffer->need_line = true;

		  /* Now get tokens until the PRAGMA_EOL.  */
		  do
		    {
		      location_t spelling;
		      const cpp_token *tok
			= cpp_get_token_with_location (pfile, &spelling);

		      gcc_assert (pfile->state.in_deferred_pragma
				  || tok->type == CPP_PRAGMA_EOL);
		      cb (pfile, CPP_DO_token, data, tok, spelling);
		    }
		  while (pfile->state.in_deferred_pragma);

		  if (pfile->buffer->next_line < pfile->buffer->rlimit)
		    cb (pfile, CPP_DO_location, data,
			pfile->line_table->highest_line);

		  pfile->mi_valid = false;
		  goto restart;
		}
	      goto dflt;

	    default:
	    dflt:
	      bol = false;
	      pfile->mi_valid = false;
	      break;
	    }
	}

      if (buffer->rlimit > base && !pfile->state.skipping)
	{
	  const unsigned char *limit = buffer->rlimit;
	  /* If the file was not newline terminated, add rlimit, which is
	     guaranteed to point to a newline, to the end of our range.  */
	  if (limit[-1] != '\n')
	    {
	      limit++;
	      CPP_INCREMENT_LINE (pfile, 0);
	      line_count++;
	    }
	  cb (pfile, CPP_DO_print, data, line_count, base, limit - base);
	}

      _cpp_pop_buffer (pfile);
    }
  while (pfile->buffer);
}
