/* 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, cplusplus)
	       && CPP_OPTION (pfile, lang) >= CLK_GNUCXX26)
	buffer->cur++, result->type = CPP_CLOSE_SPLICE;
      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 '^':
      result->type = CPP_XOR;
      if (*buffer->cur == '=')
	buffer->cur++, result->type = CPP_XOR_EQ;
      else if (*buffer->cur == '^'
	       && CPP_OPTION (pfile, cplusplus)
	       && CPP_OPTION (pfile, lang) >= CLK_GNUCXX26)
	buffer->cur++, result->type = CPP_REFLECT_OP;
      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;
      /* C++ [lex.pptoken]/4.3: "Otherwise, if the next three characters are
	 [:: and the subsequent character is not :, or if the next three
	 characters are [:>, the [ is treated as a preprocessing token by
	 itself and not as the first character of the preprocessing token [:."
	 Also, the tokens [: and :] cannot be composed from digraphs.  */
      if (*buffer->cur == ':'
	  && CPP_OPTION (pfile, cplusplus)
	  && CPP_OPTION (pfile, lang) >= CLK_GNUCXX26)
	{
	  if ((buffer->cur[1] == ':' && buffer->cur[2] != ':')
	      || buffer->cur[1] == '>')
	    break;
	  else
	    buffer->cur++, result->type = CPP_OPEN_SPLICE;
	}
      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);
}
