/* Part of CPP library.  (Precompiled header reading/writing.)
   Copyright (C) 2000-2026 Free Software Foundation, Inc.

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"
#include "hashtab.h"
#include "mkdeps.h"

static int write_macdef (cpp_reader *, cpp_hashnode *, void *);
static int save_idents (cpp_reader *, cpp_hashnode *, void *);
static hashval_t hashmem (const void *, size_t);
static hashval_t cpp_string_hash (const void *);
static int cpp_string_eq (const void *, const void *);
static int count_defs (cpp_reader *, cpp_hashnode *, void *);
static int comp_hashnodes (const void *, const void *);
static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
static int write_defs (cpp_reader *, cpp_hashnode *, void *);
static int save_macros (cpp_reader *, cpp_hashnode *, void *);
static int _cpp_save_pushed_macros (cpp_reader *, FILE *);
static int _cpp_restore_pushed_macros (cpp_reader *, FILE *);

/* This structure represents a macro definition on disk.  */
struct macrodef_struct
{
  unsigned int definition_length;
  unsigned short name_length;
  unsigned short flags;
};

/* This is how we write out a macro definition.
   Suitable for being called by cpp_forall_identifiers.  */

static int
write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
{
  FILE *f = (FILE *) file_p;
  bool is_void = false;
  switch (hn->type)
    {
    case NT_VOID:
      if (! (hn->flags & NODE_POISONED))
	return 1;
      is_void = true;
      goto poisoned;

    case NT_BUILTIN_MACRO:
      return 1;

    case NT_USER_MACRO:
      if (hn->value.macro->kind != cmk_assert)
	{
	poisoned:
	  struct macrodef_struct s;
	  const unsigned char *defn;

	  s.name_length = NODE_LEN (hn);
	  s.flags = hn->flags & NODE_POISONED;

	  if (is_void)
	    {
	      defn = NODE_NAME (hn);
	      s.definition_length = s.name_length;
	    }
	  else
	    {
	      defn = cpp_macro_definition (pfile, hn);
	      s.definition_length = ustrlen (defn);
	    }

	  if (fwrite (&s, sizeof (s), 1, f) != 1
	      || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
	    {
	      cpp_errno (pfile, CPP_DL_ERROR,
			 "while writing precompiled header");
	      return 0;
	    }
	}
      return 1;

    default:
      abort ();
    }
}

/* This structure records the names of the defined macros.
   It's also used as a callback structure for size_initial_idents
   and save_idents.  */

struct cpp_savedstate
{
  /* A hash table of the defined identifiers.  */
  htab_t definedhash;
  /* The size of the definitions of those identifiers (the size of
     'definedstrs').  */
  size_t hashsize;
  /* Number of definitions */
  size_t n_defs;
  /* Array of definitions.  In cpp_write_pch_deps it is used for sorting.  */
  cpp_hashnode **defs;
  /* Space for the next definition.  Definitions are null-terminated
     strings.  */
  unsigned char *definedstrs;
};

/* Save this identifier into the state: put it in the hash table,
   put the definition in 'definedstrs'.  */

static int
save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
  struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;

  if (hn->type != NT_VOID)
    {
      struct cpp_string news;
      void **slot;

      news.len = NODE_LEN (hn);
      news.text= NODE_NAME (hn);
      slot = htab_find_slot (ss->definedhash, &news, INSERT);
      if (*slot == NULL)
	{
	  struct cpp_string *sp;
	  unsigned char *text;

	  sp = XNEW (struct cpp_string);
	  *slot = sp;

	  sp->len = NODE_LEN (hn);
	  sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn));
	  memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
	}
    }

  return 1;
}

/* Hash some memory in a generic way.  */

static hashval_t
hashmem (const void *p_p, size_t sz)
{
  const unsigned char *p = (const unsigned char *)p_p;
  size_t i;
  hashval_t h;

  h = 0;
  for (i = 0; i < sz; i++)
    h = h * 67 - (*p++ - 113);
  return h;
}

/* Hash a cpp string for the hashtable machinery.  */

static hashval_t
cpp_string_hash (const void *a_p)
{
  const struct cpp_string *a = (const struct cpp_string *) a_p;
  return hashmem (a->text, a->len);
}

/* Compare two cpp strings for the hashtable machinery.  */

static int
cpp_string_eq (const void *a_p, const void *b_p)
{
  const struct cpp_string *a = (const struct cpp_string *) a_p;
  const struct cpp_string *b = (const struct cpp_string *) b_p;
  return (a->len == b->len
	  && memcmp (a->text, b->text, a->len) == 0);
}

/* Free memory associated with cpp_string.  */

static void
cpp_string_free (void *a_p)
{
  struct cpp_string *a = (struct cpp_string *) a_p;
  free ((void *) a->text);
  free (a);
}

/* Save the current definitions of the cpp_reader for dependency
   checking purposes.  When writing a precompiled header, this should
   be called at the same point in the compilation as cpp_valid_state
   would be called when reading the precompiled header back in.  */

int
cpp_save_state (cpp_reader *r, FILE *f)
{
  /* Save the list of non-void identifiers for the dependency checking.  */
  r->savedstate = XNEW (struct cpp_savedstate);
  r->savedstate->definedhash = htab_create (100, cpp_string_hash,
					    cpp_string_eq, cpp_string_free);
  cpp_forall_identifiers (r, save_idents, r->savedstate);

  /* Write out the list of defined identifiers.  */
  cpp_forall_identifiers (r, write_macdef, f);

  return 0;
}

/* Calculate the 'hashsize' field of the saved state.  */

static int
count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
  struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;

  switch (hn->type)
    {
    case NT_BUILTIN_MACRO:
      return 1;

    case NT_USER_MACRO:
      if (hn->value.macro->kind == cmk_assert)
	return 1;

      /* fall through.  */

    case NT_VOID:
      {
	struct cpp_string news;
	void **slot;

	news.len = NODE_LEN (hn);
	news.text = NODE_NAME (hn);
	slot = (void **) htab_find (ss->definedhash, &news);
	if (slot == NULL)
	  {
	    ss->hashsize += NODE_LEN (hn) + 1;
	    ss->n_defs += 1;
	  }
      }
      return 1;

    default:
      abort ();
    }
}

/* Collect the identifiers into the state's string table.  */
static int
write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
  struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;

  switch (hn->type)
    {
    case NT_BUILTIN_MACRO:
      return 1;

    case NT_USER_MACRO:
      if (hn->value.macro->kind == cmk_assert)
	return 1;

      /* fall through.  */

    case NT_VOID:
      {
	struct cpp_string news;
	void **slot;

	news.len = NODE_LEN (hn);
	news.text = NODE_NAME (hn);
	slot = (void **) htab_find (ss->definedhash, &news);
	if (slot == NULL)
	  {
	    ss->defs[ss->n_defs] = hn;
	    ss->n_defs += 1;
	  }
      }
      return 1;

    default:
      abort ();
    }
}

/* Comparison function for qsort.  The arguments point to pointers of
   type ht_hashnode *.  */
static int
comp_hashnodes (const void *px, const void *py)
{
  cpp_hashnode *x = *(cpp_hashnode **) px;
  cpp_hashnode *y = *(cpp_hashnode **) py;
  return ustrcmp (NODE_NAME (x), NODE_NAME (y));
}

/* Write out the remainder of the dependency information.  This should be
   called after the PCH is ready to be saved.  */

int
cpp_write_pch_deps (cpp_reader *r, FILE *f)
{
  struct macrodef_struct z;
  struct cpp_savedstate *const ss = r->savedstate;
  unsigned char *definedstrs;
  size_t i;

  /* Collect the list of identifiers which have been seen and
     weren't defined to anything previously.  */
  ss->hashsize = 0;
  ss->n_defs = 0;
  cpp_forall_identifiers (r, count_defs, ss);

  ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs);
  ss->n_defs = 0;
  cpp_forall_identifiers (r, write_defs, ss);

  /* Sort the list, copy it into a buffer, and write it out.  */
  qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
  definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize);
  for (i = 0; i < ss->n_defs; ++i)
    {
      size_t len = NODE_LEN (ss->defs[i]);
      memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1);
      definedstrs += len + 1;
    }

  memset (&z, 0, sizeof (z));
  z.definition_length = ss->hashsize;
  if (fwrite (&z, sizeof (z), 1, f) != 1
      || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1)
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }
  free (ss->definedstrs);
  free (ss->defs);
  htab_delete (ss->definedhash);

  /* Free the saved state.  */
  free (ss);
  r->savedstate = NULL;

  /* Save the next value of __COUNTER__. */
  if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1)
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }

  return 0;
}

/* Write out the definitions of the preprocessor, in a form suitable for
   cpp_read_state.  */

int
cpp_write_pch_state (cpp_reader *r, FILE *f)
{
  if (!r->deps)
    r->deps = deps_init ();

  if (deps_save (r->deps, f) != 0)
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }

  if (! _cpp_save_file_entries (r, f))
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }

  /* Save the next __COUNTER__ value.  When we include a precompiled header,
     we need to start at the offset we would have if the header had been
     included normally. */
  if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1)
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }

  /* Write saved macros.  */
  if (! _cpp_save_pushed_macros (r, f))
    {
      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
      return -1;
    }

  return 0;
}

static int
_cpp_restore_pushed_macros (cpp_reader *r, FILE *f)
{
  size_t count_saved = 0;
  size_t i;
  struct def_pragma_macro *p;
  size_t nlen;
  uchar *defn;
  size_t defnlen;

  if (fread (&count_saved, sizeof (count_saved), 1, f) != 1)
    return 0;
  if (! count_saved)
    return 1;
  for (i = 0; i < count_saved; i++)
    {
      if (fread (&nlen, sizeof (nlen), 1, f) != 1)
	return 0;
      p = XNEW (struct def_pragma_macro);
      memset (p, 0, sizeof (struct def_pragma_macro));
      p->name = XNEWVAR (char, nlen + 1);
      p->name[nlen] = 0;
      if (fread (p->name, nlen, 1, f) != 1)
	return 0;
      if (fread (&defnlen, sizeof (defnlen), 1, f) != 1)
	return 0;
      if (defnlen == 0)
        p->is_undef = 1;
      else
        {
	  defn = XNEWVEC (uchar, defnlen + 1);
	  defn[defnlen] = 0;

	  if (fread (defn, defnlen, 1, f) != 1)
	    return 0;

	  p->definition = defn;
	  if (fread (&(p->line), sizeof (location_t), 1, f) != 1)
	    return 0;
	  defnlen = 0;
	  if (fread (&defnlen, sizeof (defnlen), 1, f) != 1)
	    return 0;
	  p->syshdr = ((defnlen & 1) != 0 ? 1 : 0);
	  p->used =  ((defnlen & 2) != 0 ? 1 : 0);
	}

      p->next = r->pushed_macros;
      r->pushed_macros = p;
    }
  return 1;
}

static int
_cpp_save_pushed_macros (cpp_reader *r, FILE *f)
{
  size_t count_saved = 0;
  size_t i;
  struct def_pragma_macro *p,**pp;
  size_t defnlen;

  /* Get count. */
  p = r->pushed_macros;
  while (p != NULL)
    {
      count_saved++;
      p = p->next;
    }
  if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1)
    return 0;
  if (!count_saved)
    return 1;

  pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *)
					    * count_saved);
  /* Store them in reverse order.  */
  p = r->pushed_macros;
  i = count_saved;
  while (p != NULL)
    {
      --i;
      pp[i] = p;
      p = p->next;
    }
  for (i = 0; i < count_saved; i++)
    {
      defnlen = strlen (pp[i]->name);
      if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
	  || fwrite (pp[i]->name, defnlen, 1, f) != 1)
	return 0;
      if (pp[i]->is_undef)
	{
	  defnlen = 0;
	  if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1)
	    return 0;
	}
      else
        {
	  defnlen = ustrlen (pp[i]->definition);
	  if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
	      || fwrite (pp[i]->definition, defnlen, 1, f) != 1)
	    return 0;
	  if (fwrite (&(pp[i]->line), sizeof (location_t), 1, f) != 1)
	    return 0;
	  defnlen = 0;
	  defnlen |= (pp[i]->syshdr != 0 ? 1 : 0);
	  defnlen |= (pp[i]->used != 0 ? 2 : 0);
	  if (fwrite (&defnlen, sizeof (defnlen), 1, f) != 1)
	    return 0;
	}
    }
  return 1;
}


/* Data structure to transform hash table nodes into a sorted list */

struct ht_node_list
{
  /* Array of nodes */
  cpp_hashnode **defs;
  /* Number of nodes in the array */
  size_t n_defs;
  /* Size of the allocated array */
  size_t asize;
};

/* Callback for collecting identifiers from hash table */

static int
collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
		  void *nl_p)
{
  struct ht_node_list *const nl = (struct ht_node_list *)nl_p;

  if (hn->type != NT_VOID || hn->flags & NODE_POISONED)
    {
      if (nl->n_defs == nl->asize)
        {
          nl->asize *= 2;
          nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize);
        }

      nl->defs[nl->n_defs] = hn;
      ++nl->n_defs;
    }
  return 1;
}


/* Return nonzero if FD is a precompiled header which is consistent
   with the preprocessor's current definitions.  It will be consistent
   when:

   - anything that was defined just before the PCH was generated
     is defined the same way now; and
   - anything that was not defined then, but is defined now, was not
     used by the PCH.

   NAME is used to print warnings if `warn_invalid_pch' is set in the
   reader's flags.
*/

int
cpp_valid_state (cpp_reader *r, const char *name, int fd)
{
  struct macrodef_struct m;
  size_t namebufsz = 256;
  unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz);
  unsigned char *undeftab = NULL;
  struct ht_node_list nl = { 0, 0, 0 };
  unsigned char *first, *last;
  unsigned int i;
  unsigned int counter;

  /* Read in the list of identifiers that must be defined
     Check that they are defined in the same way.  */
  for (;;)
    {
      cpp_hashnode *h;
      const unsigned char *newdefn;

      if (read (fd, &m, sizeof (m)) != sizeof (m))
	goto error;

      if (m.name_length == 0)
	break;

      /* If this file is already preprocessed, there won't be any
	 macros defined, and that's OK.  */
      if (CPP_OPTION (r, preprocessed))
	{
	  if (lseek (fd, m.definition_length, SEEK_CUR) == -1)
	    goto error;
	  continue;
	}

      if (m.definition_length > namebufsz)
	{
	  free (namebuf);
	  namebufsz = m.definition_length + 256;
	  namebuf = XNEWVEC (unsigned char, namebufsz);
	}

      if ((size_t)read (fd, namebuf, m.definition_length)
	  != m.definition_length)
	goto error;

      h = cpp_lookup (r, namebuf, m.name_length);
      if (m.flags & NODE_POISONED
	  || h->flags & NODE_POISONED)
	{
	  if (CPP_OPTION (r, warn_invalid_pch))
	    cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
		                "%s: not used because %<%.*s%> is poisoned",
		                name, m.name_length, namebuf);
	  goto fail;
	}

      if (h->type == NT_VOID)
	{
	  /* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined,
	     as in, when the PCH file is created with -g and we're
	     attempting to use it without -g.  Restoring the PCH file
	     is supposed to bring in this definition *and* enable the
	     generation of call frame information, so that precompiled
	     definitions that take this macro into account, to decide
	     what asm to emit, won't issue .cfi directives when the
	     compiler doesn't.  */
	  if (!(h->flags & NODE_USED)
	      && m.name_length == sizeof ("__GCC_HAVE_DWARF2_CFI_ASM") - 1
	      && !memcmp (namebuf, "__GCC_HAVE_DWARF2_CFI_ASM", m.name_length))
	    continue;

	  if (CPP_OPTION (r, warn_invalid_pch))
	    cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
		                "%s: not used because %<%.*s%> not defined",
		                name, m.name_length, namebuf);
	  goto fail;
	}

      newdefn = cpp_macro_definition (r, h);

      if (m.definition_length != ustrlen (newdefn)
	  || memcmp (namebuf, newdefn, m.definition_length) != 0)
	{
	  if (CPP_OPTION (r, warn_invalid_pch))
	    cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
				"%s: not used because %<%.*s%> defined as "
				"%qs not %<%.*s%>",
				name, m.name_length, namebuf,
				newdefn + m.name_length,
				m.definition_length - m.name_length,
				namebuf +  m.name_length);
	  goto fail;
	}
    }
  free (namebuf);
  namebuf = NULL;

  /* Read in the list of identifiers that must not be defined.
     Check that they really aren't.  */
  undeftab = XNEWVEC (unsigned char, m.definition_length);
  if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
    goto error;

  /* Collect identifiers from the current hash table.  */
  nl.n_defs = 0;
  nl.asize = 10;
  nl.defs = XNEWVEC (cpp_hashnode *, nl.asize);
  cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
  qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);

  /* Loop through nl.defs and undeftab, both of which are sorted lists.
     There should be no matches.  */
  first = undeftab;
  last = undeftab + m.definition_length;
  i = 0;

  while (first < last && i < nl.n_defs)
    {
      int cmp = ustrcmp (first, NODE_NAME (nl.defs[i]));

      if (cmp < 0)
 	first += ustrlen (first) + 1;
      else if (cmp > 0)
 	++i;
      else
	{
	  if (CPP_OPTION (r, warn_invalid_pch))
	    cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
		                "%s: not used because %qs is defined",
		                name, first);
	  goto fail;
	}
    }

  free(nl.defs);
  nl.defs = NULL;
  free (undeftab);
  undeftab = NULL;

  /* Read in the next value of __COUNTER__.
     Check that (a) __COUNTER__ was not used in the pch or (b) __COUNTER__
     has not been used in this translation unit. */
  if (read (fd, &counter, sizeof (counter)) != sizeof (counter))
    goto error;
  if (counter && r->counter)
    {
      if (CPP_OPTION (r, warn_invalid_pch))
	cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
		            "%s: not used because %<__COUNTER__%> is invalid",
		            name);
      goto fail;
    }

  /* We win!  */
  return 0;

 error:
  cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");

 fail:
  free (namebuf);
  free (undeftab);
  free (nl.defs);
  return 1;
}

/* Save all the existing macros.  */

namespace {

struct saved_macro
{
  uchar *defn;
  location_t loc;
  expanded_location xloc;
};

} /* unnamed namespace */

struct save_macro_data
{
  saved_macro *defns;
  size_t count;
  size_t array_size;
  char **saved_pragmas;
};

/* Save the definition of a single macro, so that it will persist
   across a PCH restore.  Because macro data is in GCed memory, which
   will be blown away by PCH, it must be temporarily copied to
   malloced memory.  (The macros will refer to identifier nodes which
   are also GCed and so on, so the copying is done by turning them
   into self-contained strings.)  The assumption is that most macro
   definitions will come from the PCH file, not from the compilation
   before the PCH file is loaded, so it doesn't matter that this is
   a little expensive.

   It would reduce the cost even further if macros defined in the PCH
   file were not saved in this way, but this is not done (yet), except
   for builtins, and for #assert by default.  */

static int
save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
{
  struct save_macro_data *data = (struct save_macro_data *)data_p;

  if (cpp_user_macro_p (h))
    {
      if (data->count == data->array_size)
	{
	  data->array_size *= 2;
	  data->defns = XRESIZEVEC (saved_macro, data->defns, data->array_size);
	}

      const uchar * defn = cpp_macro_definition (r, h);
      size_t defnlen = ustrlen (defn);

      const auto d = data->defns + data->count;
      d->defn = (uchar *) xmemdup (defn, defnlen, defnlen + 2);
      d->defn[defnlen] = '\n';
      d->loc = h->value.macro->line;
      d->xloc = {};
      if (d->loc == r->line_table->cmdline_location)
	{
	  /* The cmdline_location may be different when it comes time to
	     restore the macros, so use 0 to indicate this.  */
	  d->loc = 0;
	}
      else if (d->loc != r->line_table->builtin_location)
	{
	  const auto map = linemap_lookup (r->line_table, d->loc);
	  gcc_assert (map);
	  d->xloc = linemap_expand_location (r->line_table, map, d->loc);
	}
      data->count++;
    }

  return 1;
}

/* Prepare to restore the state, by saving the currently-defined
   macros in 'data'.  */

void
cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
{
  struct save_macro_data *d = XNEW (struct save_macro_data);

  d->array_size = 512;
  d->defns = XNEWVEC (saved_macro, d->array_size);
  d->count = 0;
  cpp_forall_identifiers (r, save_macros, d);

  /* Sort the saved macros in order, so the line map gets built up
     in chronological order as expected when we load them back in.  */
  static line_maps *line_table;
  line_table = r->line_table;
  qsort (d->defns, d->count, sizeof (saved_macro),
	 [] (const void *x1, const void *x2)
	 {
	   const auto d1 = static_cast<const saved_macro *> (x1);
	   const auto d2 = static_cast<const saved_macro *> (x2);
	   return linemap_compare_locations (line_table, d2->loc, d1->loc);
	 });

  d->saved_pragmas = _cpp_save_pragma_names (r);
  *data = d;
}

/* Given a precompiled header that was previously determined to be valid,
   apply all its definitions (and undefinitions) to the current state.
   DEPNAME is passed to deps_restore.  */

int
cpp_read_state (cpp_reader *r, const char *name, FILE *f,
		struct save_macro_data *data)
{
  size_t i;
  struct lexer_state old_state;
  unsigned int counter;

  /* Restore spec_nodes, which will be full of references to the old
     hashtable entries and so will now be invalid.  */
  {
    struct spec_nodes *s = &r->spec_nodes;
    s->n_defined	= cpp_lookup (r, DSC("defined"));
    s->n_true		= cpp_lookup (r, DSC("true"));
    s->n_false		= cpp_lookup (r, DSC("false"));
    s->n__VA_ARGS__     = cpp_lookup (r, DSC("__VA_ARGS__"));
    s->n__VA_OPT__      = cpp_lookup (r, DSC("__VA_OPT__"));
  }

  old_state = r->state;
  r->state.in_directive = 1;
  r->state.prevent_expansion = 1;
  r->state.angled_headers = 0;

  const auto old_directive_line = r->directive_line;

  /* Run through the carefully-saved macros, insert them.  */
  const char *cur_fname = nullptr;
  for (i = 0; i < data->count; i++)
    {
      const auto d = data->defns + i;
      const size_t namelen = ustrcspn (d->defn, "( \n");
      cpp_hashnode *const h = cpp_lookup (r, d->defn, namelen);
      const auto defn = d->defn + namelen;

      /* The PCH file is valid, so we know that if there is a definition
	 from the PCH file it must be the same as the one we had
	 originally, and so do not need to restore it.  */
      if (h->type == NT_VOID)
	{
	  if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true)
	      != NULL)
	    {
	      if (d->loc == r->line_table->builtin_location)
		r->directive_line = r->line_table->builtin_location;
	      else if (d->loc == 0)
		/* This was a command-line-defined macro, preserve that
		   aspect now.  */
		r->directive_line = r->line_table->cmdline_location;
	      else
		{
		  /* In practice, almost all of the locations ought to be in the
		     main file, since a PCH cannot be loaded after including
		     other headers.  The (probably sole) exception is that
		     implicit preincludes can be loaded, so if an implicit
		     preinclude such as /usr/include/stdc-predef.h has changed
		     since the PCH was created (in a way not invalidating the
		     PCH), we can end up here with locations that are not in the
		     main file.  In that case, we may be adding them to the
		     line_map out of order (the implicit preinclude already
		     being represented in the line_map we have loaded from the
		     PCH), but it is probably not going to cause any observable
		     issue given the constraints on what can appear in a header
		     before loading a PCH.  */
		  if (!cur_fname || strcmp (cur_fname, d->xloc.file))
		    {
		      linemap_add (r->line_table, LC_RENAME, d->xloc.sysp,
				   d->xloc.file, d->xloc.line);
		      cur_fname = d->xloc.file;
		    }
		  r->directive_line = linemap_line_start (r->line_table,
							  d->xloc.line, 127);
		}

	      /* Even when the macro was defined in the main file, we have to
		 use cpp_force_token_locations here, so all tokens in the macro
		 will have location assigned to the directive line with no
		 column information.  We no longer know even which line the
		 tokens appeared on originally now, much less the column, since
		 we only stored the macro definition string after lexing it.  */
	      cpp_force_token_locations (r, r->directive_line);

	      _cpp_clean_line (r);
	      if (!_cpp_create_definition (r, h, r->directive_line))
		abort ();
	      cpp_stop_forcing_token_locations (r);
	      _cpp_pop_buffer (r);

	      if (d->loc < RESERVED_LOCATION_COUNT)
		/* Macros defined on the command line or as builtins are always
		   implicitly used.  It is necessary to note this here or else
		   -Wunused-macros will complain, because these locations do
		   return TRUE for MAIN_FILE_P().  For a command line
		   definition, d->loc was set to 0 when we saved it, so it does
		   satisfy the check performed here.  */
		h->value.macro->used = true;
	    }
	  else
	    abort ();
	}

      free (data->defns[i].defn);
    }
  r->state = old_state;
  r->directive_line = old_directive_line;

  _cpp_restore_pragma_names (r, data->saved_pragmas);

  XDELETEVEC (data->defns);
  free (data);

  if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
      != 0)
    goto error;

  if (! _cpp_read_file_entries (r, f))
    goto error;

  if (fread (&counter, sizeof (counter), 1, f) != 1)
    goto error;

  if (!r->counter)
    r->counter = counter;

  /* Read pushed macros. */
  if (! _cpp_restore_pushed_macros (r, f))
    goto error;
  return 0;

 error:
  cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
  return -1;
}
