/* Part of CPP library.  (Precompiled header reading/writing.)
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010
   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;

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

/* 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, NULL);
  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;

      /* else 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;

      /* else 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 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 accout, 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");
  return -1;

 fail:
  if (namebuf != NULL)
    free (namebuf);
  if (undeftab != NULL)
    free (undeftab);
  if (nl.defs != NULL)
    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__"));
  }

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