/* Part of CPP library.  (Precompiled header reading/writing.)
   Copyright (C) 2000-2017 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;
  switch (hn->type)
    {
    case NT_VOID:
      if (! (hn->flags & NODE_POISONED))
	return 1;
      /* XXX Really fallthru?  */
      /* FALLTHRU */

    case NT_MACRO:
      if ((hn->flags & NODE_BUILTIN)
	  && (!pfile->cb.user_builtin_macro
	      || !pfile->cb.user_builtin_macro (pfile, hn)))
	return 1;

      {
	struct macrodef_struct s;
	const unsigned char *defn;

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

	if (hn->type == NT_MACRO)
	  {
	    defn = cpp_macro_definition (pfile, hn);
	    s.definition_length = ustrlen (defn);
	  }
	else
	  {
	    defn = NODE_NAME (hn);
	    s.definition_length = s.name_length;
	  }

	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;

    case NT_ASSERTION:
      /* Not currently implemented.  */
      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_MACRO:
      if (hn->flags & NODE_BUILTIN)
	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;

    case NT_ASSERTION:
      /* Not currently implemented.  */
      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_MACRO:
      if (hn->flags & NODE_BUILTIN)
	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;

    case NT_ASSERTION:
      /* Not currently implemented.  */
      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 (source_location), 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 (source_location), 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_MACRO)
	{
	  /* 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 `%s' 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 `%s' 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.  */

struct save_macro_data
{
  uchar **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 ((h->flags & NODE_BUILTIN)
      && h->type == NT_MACRO
      && r->cb.user_builtin_macro)
    r->cb.user_builtin_macro (r, h);

  if (h->type != NT_VOID
      && (h->flags & NODE_BUILTIN) == 0)
    {
      if (data->count == data->array_size)
	{
	  data->array_size *= 2;
	  data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size));
	}

      switch (h->type)
	{
	case NT_ASSERTION:
	  /* Not currently implemented.  */
	  return 1;

	case NT_MACRO:
	  {
	    const uchar * defn = cpp_macro_definition (r, h);
	    size_t defnlen = ustrlen (defn);

	    data->defns[data->count] = (uchar *) xmemdup (defn, defnlen,
                                                          defnlen + 2);
	    data->defns[data->count][defnlen] = '\n';
	  }
	  break;

	default:
	  abort ();
	}
      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 (uchar *, d->array_size);
  d->count = 0;
  cpp_forall_identifiers (r, save_macros, d);
  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__"));
    s->n__has_include__ = cpp_lookup (r, DSC("__has_include__"));
    s->n__has_include_next__ = cpp_lookup (r, DSC("__has_include_next__"));
  }

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

  /* Run through the carefully-saved macros, insert them.  */
  for (i = 0; i < data->count; i++)
    {
      cpp_hashnode *h;
      size_t namelen;
      uchar *defn;

      namelen = ustrcspn (data->defns[i], "( \n");
      h = cpp_lookup (r, data->defns[i], namelen);
      defn = data->defns[i] + 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)
	    {
	      _cpp_clean_line (r);
	      if (!_cpp_create_definition (r, h))
		abort ();
	      _cpp_pop_buffer (r);
	    }
	  else
	    abort ();
	}

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

  _cpp_restore_pragma_names (r, data->saved_pragmas);

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