/* C++ modules.  Experimental!
   Copyright (C) 2017-2021 Free Software Foundation, Inc.
   Written by Nathan Sidwell <nathan@acm.org> while at FaceBook

   This file is part of GCC.

   GCC 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.

   GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* Comments in this file have a non-negligible chance of being wrong
   or at least inaccurate.  Due to (a) my misunderstanding, (b)
   ambiguities that I have interpretted differently to original intent
   (c) changes in the specification, (d) my poor wording, (e) source
   changes.  */

/* (Incomplete) Design Notes

   A hash table contains all module names.  Imported modules are
   present in a modules array, which by construction places an
   import's dependencies before the import itself.  The single
   exception is the current TU, which always occupies slot zero (even
   when it is not a module).

   Imported decls occupy an entity_ary, an array of binding_slots, indexed
   by importing module and index within that module.  A flat index is
   used, as each module reserves a contiguous range of indices.
   Initially each slot indicates the CMI section containing the
   streamed decl.  When the decl is imported it will point to the decl
   itself.

   Additionally each imported decl is mapped in the entity_map via its
   DECL_UID to the flat index in the entity_ary.  Thus we can locate
   the index for any imported decl by using this map and then
   de-flattening the index via a binary seach of the module vector.
   Cross-module references are by (remapped) module number and
   module-local index.

   Each importable DECL contains several flags.  The simple set are
   DECL_EXPORT_P, DECL_MODULE_PURVIEW_P and DECL_MODULE_IMPORT_P.  The
   first indicates whether it is exported, the second whether it is in
   the module purview (as opposed to the global module fragment), and
   the third indicates whether it was an import into this TU or not.

   The more detailed flags are DECL_MODULE_PARTITION_P,
   DECL_MODULE_ENTITY_P.  The first is set in a primary interface unit
   on decls that were read from module partitions (these will have
   DECL_MODULE_IMPORT_P set too).  Such decls will be streamed out to
   the primary's CMI.  DECL_MODULE_ENTITY_P is set when an entity is
   imported, even if it matched a non-imported entity.  Such a decl
   will not have DECL_MODULE_IMPORT_P set, even though it has an entry
   in the entity map and array.

   Header units are module-like.

   For namespace-scope lookup, the decls for a particular module are
   held located in a sparse array hanging off the binding of the name.
   This is partitioned into two: a few fixed slots at the start
   followed by the sparse slots afterwards.  By construction we only
   need to append new slots to the end -- there is never a need to
   insert in the middle.  The fixed slots are MODULE_SLOT_CURRENT for
   the current TU (regardless of whether it is a module or not),
   MODULE_SLOT_GLOBAL and MODULE_SLOT_PARTITION.  These latter two
   slots are used for merging entities across the global module and
   module partitions respectively.  MODULE_SLOT_PARTITION is only
   present in a module.  Neither of those two slots is searched during
   name lookup -- they are internal use only.  This vector is created
   lazily once we require it, if there is only a declaration from the
   current TU, a regular binding is present.  It is converted on
   demand.

   OPTIMIZATION: Outside of the current TU, we only need ADL to work.
   We could optimize regular lookup for the current TU by glomming all
   the visible decls on its slot.  Perhaps wait until design is a
   little more settled though.

   There is only one instance of each extern-linkage namespace.  It
   appears in every module slot that makes it visible.  It also
   appears in MODULE_SLOT_GLOBAL.  (It is an ODR violation if they
   collide with some other global module entity.)  We also have an
   optimization that shares the slot for adjacent modules that declare
   the same such namespace.

   A module interface compilation produces a Compiled Module Interface
   (CMI).  The format used is Encapsulated Lazy Records Of Numbered
   Declarations, which is essentially ELF's section encapsulation. (As
   all good nerds are aware, Elrond is half Elf.)  Some sections are
   named, and contain information about the module as a whole (indices
   etc), and other sections are referenced by number.  Although I
   don't defend against actively hostile CMIs, there is some
   checksumming involved to verify data integrity.  When dumping out
   an interface, we generate a graph of all the
   independently-redeclarable DECLS that are needed, and the decls
   they reference.  From that we determine the strongly connected
   components (SCC) within this TU.  Each SCC is dumped to a separate
   numbered section of the CMI.  We generate a binding table section,
   mapping each namespace&name to a defining section.  This allows
   lazy loading.

   Lazy loading employs mmap to map a read-only image of the CMI.
   It thus only occupies address space and is paged in on demand,
   backed by the CMI file itself.  If mmap is unavailable, regular
   FILEIO is used.  Also, there's a bespoke ELF reader/writer here,
   which implements just the section table and sections (including
   string sections) of a 32-bit ELF in host byte-order.  You can of
   course inspect it with readelf.  I figured 32-bit is sufficient,
   for a single module.  I detect running out of section numbers, but
   do not implement the ELF overflow mechanism.  At least you'll get
   an error if that happens.

   We do not separate declarations and definitions.  My guess is that
   if you refer to the declaration, you'll also need the definition
   (template body, inline function, class definition etc).  But this
   does mean we can get larger SCCs than if we separated them.  It is
   unclear whether this is a win or not.

   Notice that we embed section indices into the contents of other
   sections.  Thus random manipulation of the CMI file by ELF tools
   may well break it.  The kosher way would probably be to introduce
   indirection via section symbols, but that would require defining a
   relocation type.

   Notice that lazy loading of one module's decls can cause lazy
   loading of other decls in the same or another module.  Clearly we
   want to avoid loops.  In a correct program there can be no loops in
   the module dependency graph, and the above-mentioned SCC algorithm
   places all intra-module circular dependencies in the same SCC.  It
   also orders the SCCs wrt each other, so dependent SCCs come first.
   As we load dependent modules first, we know there can be no
   reference to a higher-numbered module, and because we write out
   dependent SCCs first, likewise for SCCs within the module.  This
   allows us to immediately detect broken references.  When loading,
   we must ensure the rest of the compiler doesn't cause some
   unconnected load to occur (for instance, instantiate a template).

Classes used:

   dumper - logger

   data - buffer

   bytes - data streamer
   bytes_in : bytes - scalar reader
   bytes_out : bytes - scalar writer

   elf - ELROND format
   elf_in : elf - ELROND reader
   elf_out : elf - ELROND writer

   trees_in : bytes_in - tree reader
   trees_out : bytes_out - tree writer

   depset - dependency set
   depset::hash - hash table of depsets
   depset::tarjan - SCC determinator

   uidset<T> - set T's related to a UID
   uidset<T>::hash hash table of uidset<T>

   loc_spans - location map data

   module_state - module object

   slurping - data needed during loading

   macro_import - imported macro data
   macro_export - exported macro data

   The ELROND objects use mmap, for both reading and writing.  If mmap
   is unavailable, fileno IO is used to read and write blocks of data.

   The mapper object uses fileno IO to communicate with the server or
   program.   */

/* In expermental (trunk) sources, MODULE_VERSION is a #define passed
   in from the Makefile.  It records the modification date of the
   source directory -- that's the only way to stay sane.  In release
   sources, we (plan to) use the compiler's major.minor versioning.
   While the format might not change between at minor versions, it
   seems simplest to tie the two together.  There's no concept of
   inter-version compatibility.  */
#define IS_EXPERIMENTAL(V) ((V) >= (1U << 20))
#define MODULE_MAJOR(V) ((V) / 10000)
#define MODULE_MINOR(V) ((V) % 10000)
#define EXPERIMENT(A,B) (IS_EXPERIMENTAL (MODULE_VERSION) ? (A) : (B))
#ifndef MODULE_VERSION
#include "bversion.h"
#define MODULE_VERSION (BUILDING_GCC_MAJOR * 10000U + BUILDING_GCC_MINOR)
#elif !IS_EXPERIMENTAL (MODULE_VERSION)
#error "This is not the version I was looking for."
#endif

#define _DEFAULT_SOURCE 1 /* To get TZ field of struct tm, if available.  */
#include "config.h"
#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "timevar.h"
#include "stringpool.h"
#include "dumpfile.h"
#include "bitmap.h"
#include "cgraph.h"
#include "tree-iterator.h"
#include "cpplib.h"
#include "mkdeps.h"
#include "incpath.h"
#include "libiberty.h"
#include "stor-layout.h"
#include "version.h"
#include "tree-diagnostic.h"
#include "toplev.h"
#include "opts.h"
#include "attribs.h"
#include "intl.h"
#include "langhooks.h"
/* This TU doesn't need or want to see the networking.  */
#define CODY_NETWORKING 0
#include "mapper-client.h"

#if 0 // 1 for testing no mmap
#define MAPPED_READING 0
#define MAPPED_WRITING 0
#else
#if HAVE_MMAP_FILE && _POSIX_MAPPED_FILES > 0
/* mmap, munmap.  */
#define MAPPED_READING 1
#if HAVE_SYSCONF && defined (_SC_PAGE_SIZE)
/* msync, sysconf (_SC_PAGE_SIZE), ftruncate  */
/* posix_fallocate used if available.  */
#define MAPPED_WRITING 1
#else
#define MAPPED_WRITING 0
#endif
#else
#define MAPPED_READING 0
#define MAPPED_WRITING 0
#endif
#endif

/* Some open(2) flag differences, what a colourful world it is!  */
#if defined (O_CLOEXEC)
// OK
#elif defined (_O_NOINHERIT)
/* Windows' _O_NOINHERIT matches O_CLOEXEC flag */
#define O_CLOEXEC _O_NOINHERIT
#else
#define O_CLOEXEC 0
#endif
#if defined (O_BINARY)
// Ok?
#elif defined (_O_BINARY)
/* Windows' open(2) call defaults to text!  */
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif

static inline cpp_hashnode *cpp_node (tree id)
{
  return CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (id));
}

static inline tree identifier (const cpp_hashnode *node)
{
  return HT_IDENT_TO_GCC_IDENT (HT_NODE (const_cast<cpp_hashnode *> (node)));
}

/* Id for dumping module information.  */
int module_dump_id;

/* We have a special module owner.  */
#define MODULE_UNKNOWN (~0U)    /* Not yet known.  */

/* Prefix for section names.  */
#define MOD_SNAME_PFX ".gnu.c++"

/* Format a version for user consumption.  */

typedef char verstr_t[32];
static void
version2string (unsigned version, verstr_t &out)
{
  unsigned major = MODULE_MAJOR (version);
  unsigned minor = MODULE_MINOR (version);

  if (IS_EXPERIMENTAL (version))
    sprintf (out, "%04u/%02u/%02u-%02u:%02u%s",
	     2000 + major / 10000, (major / 100) % 100, (major % 100),
	     minor / 100, minor % 100,
	     EXPERIMENT ("", " (experimental)"));
  else
    sprintf (out, "%u.%u", major, minor);
}

/* Include files to note translation for.  */
static vec<const char *, va_heap, vl_embed> *note_includes;

/* Modules to note CMI pathames.  */
static vec<const char *, va_heap, vl_embed> *note_cmis;

/* Traits to hash an arbitrary pointer.  Entries are not deletable,
   and removal is a noop (removal needed upon destruction).  */
template <typename T>
struct nodel_ptr_hash : pointer_hash<T>, typed_noop_remove <T *> {
  /* Nothing is deletable.  Everything is insertable.  */
  static bool is_deleted (T *) { return false; }
  static void mark_deleted (T *) { gcc_unreachable (); }
};

/* Map from pointer to signed integer.   */
typedef simple_hashmap_traits<nodel_ptr_hash<void>, int> ptr_int_traits;
typedef hash_map<void *,signed,ptr_int_traits> ptr_int_hash_map;

/********************************************************************/
/* Basic streaming & ELF.  Serialization is usually via mmap.  For
   writing we slide a buffer over the output file, syncing it
   approproiately.  For reading we simply map the whole file (as a
   file-backed read-only map -- it's just address space, leaving the
   OS pager to deal with getting the data to us).  Some buffers need
   to be more conventional malloc'd contents.   */

/* Variable length buffer.  */

class data {
public:
  class allocator {
  public:
    /* Tools tend to moan if the dtor's not virtual.  */
    virtual ~allocator () {}

  public:
    void grow (data &obj, unsigned needed, bool exact);
    void shrink (data &obj);

  public:
    virtual char *grow (char *ptr, unsigned needed);
    virtual void shrink (char *ptr);
  };

public:
  char *buffer;		/* Buffer being transferred.  */
  /* Although size_t would be the usual size, we know we never get
     more than 4GB of buffer -- because that's the limit of the
     encapsulation format.  And if you need bigger imports, you're
     doing it wrong.  */
  unsigned size;	/* Allocated size of buffer.  */
  unsigned pos;		/* Position in buffer.  */

public:
  data ()
    :buffer (NULL), size (0), pos (0)
  {
  }
  ~data ()
  {
    /* Make sure the derived and/or using class know what they're
       doing.  */
    gcc_checking_assert (!buffer);
  }

protected:
  char *use (unsigned count)
  {
    if (size < pos + count)
      return NULL;
    char *res = &buffer[pos];
    pos += count;
    return res;
  }

public:
  void unuse (unsigned count)
  {
    pos -= count;
  }

public:
  static allocator simple_memory;
};

/* The simple data allocator.  */
data::allocator data::simple_memory;

/* Grow buffer to at least size NEEDED.  */

void
data::allocator::grow (data &obj, unsigned needed, bool exact)
{
  gcc_checking_assert (needed ? needed > obj.size : !obj.size);
  if (!needed)
    /* Pick a default size.  */
    needed = EXPERIMENT (100, 1000);

  if (!exact)
    needed *= 2;
  obj.buffer = grow (obj.buffer, needed);
  if (obj.buffer)
    obj.size = needed;
  else
    obj.pos = obj.size = 0;
}

/* Free a buffer.  */

void
data::allocator::shrink (data &obj)
{
  shrink (obj.buffer);
  obj.buffer = NULL;
  obj.size = 0;
}

char *
data::allocator::grow (char *ptr, unsigned needed)
{
  return XRESIZEVAR (char, ptr, needed);
}

void
data::allocator::shrink (char *ptr)
{
  XDELETEVEC (ptr);
}

/* Byte streamer base.   Buffer with read/write position and smarts
   for single bits.  */

class bytes : public data {
public:
  typedef data parent;

protected:
  uint32_t bit_val;	/* Bit buffer.  */
  unsigned bit_pos;	/* Next bit in bit buffer.  */

public:
  bytes ()
    :parent (), bit_val (0), bit_pos (0)
  {}
  ~bytes () 
  {
  }

protected:
  unsigned calc_crc (unsigned) const;

protected:
  /* Finish bit packet.  Rewind the bytes not used.  */
  unsigned bit_flush ()
  {
    gcc_assert (bit_pos);
    unsigned bytes = (bit_pos + 7) / 8;
    unuse (4 - bytes);
    bit_pos = 0;
    bit_val = 0;
    return bytes;
  }
};

/* Calculate the crc32 of the buffer.  Note the CRC is stored in the
   first 4 bytes, so don't include them.  */

unsigned
bytes::calc_crc (unsigned l) const
{
  unsigned crc = 0;
  for (size_t ix = 4; ix < l; ix++)
    crc = crc32_byte (crc, buffer[ix]);
  return crc;
}

class elf_in;

/* Byte stream reader.  */

class bytes_in : public bytes {
  typedef bytes parent;

protected:
  bool overrun;  /* Sticky read-too-much flag.  */

public:
  bytes_in ()
    : parent (), overrun (false)
  {
  }
  ~bytes_in ()
  {
  }

public:
  /* Begin reading a named section.  */
  bool begin (location_t loc, elf_in *src, const char *name);
  /* Begin reading a numbered section with optional name.  */
  bool begin (location_t loc, elf_in *src, unsigned, const char * = NULL);
  /* Complete reading a buffer.  Propagate errors and return true on
     success.  */
  bool end (elf_in *src);
  /* Return true if there is unread data.  */
  bool more_p () const
  {
    return pos != size;
  }

public:
  /* Start reading at OFFSET.  */
  void random_access (unsigned offset)
  {
    if (offset > size)
      set_overrun ();
    pos = offset;
    bit_pos = bit_val = 0;
  }

public:
  void align (unsigned boundary)
  {
    if (unsigned pad = pos & (boundary - 1))
      read (boundary - pad);
  }

public:
  const char *read (unsigned count)
  {
    char *ptr = use (count);
    if (!ptr)
      set_overrun ();
    return ptr;
  }

public:
  bool check_crc () const;
  /* We store the CRC in the first 4 bytes, using host endianness.  */
  unsigned get_crc () const
  {
    return *(const unsigned *)&buffer[0];
  }

public:
  /* Manipulate the overrun flag.  */
  bool get_overrun () const
  {
    return overrun;
  }
  void set_overrun ()
  {
    overrun = true;
  }

public:
  unsigned u32 ();  	/* Read uncompressed integer.  */

public:
  bool b ();	    	/* Read a bool.  */
  void bflush ();	/* Completed a block of bools.  */

private:
  void bfill ();	/* Get the next block of bools.  */

public:
  int c ();		/* Read a char.  */
  int i ();		/* Read a signed int.  */
  unsigned u ();	/* Read an unsigned int.  */
  size_t z ();		/* Read a size_t.  */
  HOST_WIDE_INT wi ();  /* Read a HOST_WIDE_INT.  */
  unsigned HOST_WIDE_INT wu (); /* Read an unsigned HOST_WIDE_INT.  */
  const char *str (size_t * = NULL); /* Read a string.  */
  const void *buf (size_t); /* Read a fixed-length buffer.  */
  cpp_hashnode *cpp_node (); /* Read a cpp node.  */
};

/* Verify the buffer's CRC is correct.  */

bool
bytes_in::check_crc () const
{
  if (size < 4)
    return false;

  unsigned c_crc = calc_crc (size);
  if (c_crc != get_crc ())
    return false;

  return true;
}

class elf_out;

/* Byte stream writer.  */

class bytes_out : public bytes {
  typedef bytes parent;

public:
  allocator *memory;	/* Obtainer of memory.  */
  
public:
  bytes_out (allocator *memory)
    : parent (), memory (memory)
  {
  }
  ~bytes_out ()
  {
  }

public:
  bool streaming_p () const
  {
    return memory != NULL;
  }

public:
  void set_crc (unsigned *crc_ptr);

public:
  /* Begin writing, maybe reserve space for CRC.  */
  void begin (bool need_crc = true);
  /* Finish writing.  Spill to section by number.  */
  unsigned end (elf_out *, unsigned, unsigned *crc_ptr = NULL);

public:
  void align (unsigned boundary)
  {
    if (unsigned pad = pos & (boundary - 1))
      write (boundary - pad);
  }
  
public:
  char *write (unsigned count, bool exact = false)
  {
    if (size < pos + count)
      memory->grow (*this, pos + count, exact);
    return use (count);
  }

public:
  void u32 (unsigned);  /* Write uncompressed integer.  */

public:
  void b (bool);	/* Write bool.  */
  void bflush ();	/* Finish block of bools.  */

public:
  void c (unsigned char); /* Write unsigned char.  */
  void i (int);		/* Write signed int.  */
  void u (unsigned);	/* Write unsigned int.  */
  void z (size_t s);	/* Write size_t.  */
  void wi (HOST_WIDE_INT); /* Write HOST_WIDE_INT.  */
  void wu (unsigned HOST_WIDE_INT);  /* Write unsigned HOST_WIDE_INT.  */
  void str (const char *ptr)
  {
    str (ptr, strlen (ptr));
  }
  void cpp_node (const cpp_hashnode *node)
  {
    str ((const char *)NODE_NAME (node), NODE_LEN (node));
  }
  void str (const char *, size_t);  /* Write string of known length.  */
  void buf (const void *, size_t);  /* Write fixed length buffer.  */
  void *buf (size_t); /* Create a writable buffer */

public:
  /* Format a NUL-terminated raw string.  */
  void printf (const char *, ...) ATTRIBUTE_PRINTF_2;
  void print_time (const char *, const tm *, const char *);

public:
  /* Dump instrumentation.  */
  static void instrument ();

protected:
  /* Instrumentation.  */
  static unsigned spans[4];
  static unsigned lengths[4];
  static int is_set;
};

/* Instrumentation.  */
unsigned bytes_out::spans[4];
unsigned bytes_out::lengths[4];
int bytes_out::is_set = -1;

/* If CRC_PTR non-null, set the CRC of the buffer.  Mix the CRC into
   that pointed to by CRC_PTR.  */

void
bytes_out::set_crc (unsigned *crc_ptr)
{
  if (crc_ptr)
    {
      gcc_checking_assert (pos >= 4);

      unsigned crc = calc_crc (pos);
      unsigned accum = *crc_ptr;
      /* Only mix the existing *CRC_PTR if it is non-zero.  */
      accum = accum ? crc32_unsigned (accum, crc) : crc;
      *crc_ptr = accum;

      /* Buffer will be sufficiently aligned.  */
      *(unsigned *)buffer = crc;
    }
}

/* Finish a set of bools.  */

void
bytes_out::bflush ()
{
  if (bit_pos)
    {
      u32 (bit_val);
      lengths[2] += bit_flush ();
    }
  spans[2]++;
  is_set = -1;
}

void
bytes_in::bflush ()
{
  if (bit_pos)
    bit_flush ();
}

/* When reading, we don't know how many bools we'll read in.  So read
   4 bytes-worth, and then rewind when flushing if we didn't need them
   all.  You can't have a block of bools closer than 4 bytes to the
   end of the buffer.  */

void
bytes_in::bfill ()
{
  bit_val = u32 ();
}

/* Bools are packed into bytes.  You cannot mix bools and non-bools.
   You must call bflush before emitting another type.  So batch your
   bools.

   It may be worth optimizing for most bools being zero.  Some kind of
   run-length encoding?  */

void
bytes_out::b (bool x)
{
  if (is_set != x)
    {
      is_set = x;
      spans[x]++;
    }
  lengths[x]++;
  bit_val |= unsigned (x) << bit_pos++;
  if (bit_pos == 32)
    {
      u32 (bit_val);
      lengths[2] += bit_flush ();
    }
}

bool
bytes_in::b ()
{
  if (!bit_pos)
    bfill ();
  bool v = (bit_val >> bit_pos++) & 1;
  if (bit_pos == 32)
    bit_flush ();
  return v;
}

/* Exactly 4 bytes.  Used internally for bool packing and a few other
   places.  We can't simply use uint32_t because (a) alignment and
   (b) we need little-endian for the bool streaming rewinding to make
   sense.  */

void
bytes_out::u32 (unsigned val)
{
  if (char *ptr = write (4))
    {
      ptr[0] = val;
      ptr[1] = val >> 8;
      ptr[2] = val >> 16;
      ptr[3] = val >> 24;
    }
}

unsigned
bytes_in::u32 ()
{
  unsigned val = 0;
  if (const char *ptr = read (4))
    {
      val |= (unsigned char)ptr[0];
      val |= (unsigned char)ptr[1] << 8;
      val |= (unsigned char)ptr[2] << 16;
      val |= (unsigned char)ptr[3] << 24;
    }

  return val;
}

/* Chars are unsigned and written as single bytes. */

void
bytes_out::c (unsigned char v)
{
  if (char *ptr = write (1))
    *ptr = v;
}

int
bytes_in::c ()
{
  int v = 0;
  if (const char *ptr = read (1))
    v = (unsigned char)ptr[0];
  return v;
}

/* Ints 7-bit as a byte. Otherwise a 3bit count of following bytes in
   big-endian form.  4 bits are in the first byte.  */

void
bytes_out::i (int v)
{
  if (char *ptr = write (1))
    {
      if (v <= 0x3f && v >= -0x40)
	*ptr = v & 0x7f;
      else
	{
	  unsigned bytes = 0;
	  int probe;
	  if (v >= 0)
	    for (probe = v >> 8; probe > 0x7; probe >>= 8)
	      bytes++;
	  else
	    for (probe = v >> 8; probe < -0x8; probe >>= 8)
	      bytes++;
	  *ptr = 0x80 | bytes << 4 | (probe & 0xf);
	  if ((ptr = write (++bytes)))
	    for (; bytes--; v >>= 8)
	      ptr[bytes] = v & 0xff;
	}
    }
}

int
bytes_in::i ()
{
  int v = 0;
  if (const char *ptr = read (1))
    {
      v = *ptr & 0xff;
      if (v & 0x80)
	{
	  unsigned bytes = (v >> 4) & 0x7;
	  v &= 0xf;
	  if (v & 0x8)
	    v |= -1 ^ 0x7;
	  /* unsigned necessary due to left shifts of -ve values.  */
	  unsigned uv = unsigned (v);
	  if ((ptr = read (++bytes)))
	    while (bytes--)
	      uv = (uv << 8) | (*ptr++ & 0xff);
	  v = int (uv);
	}
      else if (v & 0x40)
	v |= -1 ^ 0x3f;
    }

  return v;
}

void
bytes_out::u (unsigned v)
{
  if (char *ptr = write (1))
    {
      if (v <= 0x7f)
	*ptr = v;
      else
	{
	  unsigned bytes = 0;
	  unsigned probe;
	  for (probe = v >> 8; probe > 0xf; probe >>= 8)
	    bytes++;
	  *ptr = 0x80 | bytes << 4 | probe;
	  if ((ptr = write (++bytes)))
	    for (; bytes--; v >>= 8)
	      ptr[bytes] = v & 0xff;
	}
    }
}

unsigned
bytes_in::u ()
{
  unsigned v = 0;

  if (const char *ptr = read (1))
    {
      v = *ptr & 0xff;
      if (v & 0x80)
	{
	  unsigned bytes = (v >> 4) & 0x7;
	  v &= 0xf;
	  if ((ptr = read (++bytes)))
	    while (bytes--)
	      v = (v << 8) | (*ptr++ & 0xff);
	}
    }

  return v;
}

void
bytes_out::wi (HOST_WIDE_INT v)
{
  if (char *ptr = write (1))
    {
      if (v <= 0x3f && v >= -0x40)
	*ptr = v & 0x7f;
      else
	{
	  unsigned bytes = 0;
	  HOST_WIDE_INT probe;
	  if (v >= 0)
	    for (probe = v >> 8; probe > 0x7; probe >>= 8)
	      bytes++;
	  else
	    for (probe = v >> 8; probe < -0x8; probe >>= 8)
	      bytes++;
	  *ptr = 0x80 | bytes << 4 | (probe & 0xf);
	  if ((ptr = write (++bytes)))
	    for (; bytes--; v >>= 8)
	      ptr[bytes] = v & 0xff;
	}
    }
}

HOST_WIDE_INT
bytes_in::wi ()
{
  HOST_WIDE_INT v = 0;
  if (const char *ptr = read (1))
    {
      v = *ptr & 0xff;
      if (v & 0x80)
	{
	  unsigned bytes = (v >> 4) & 0x7;
	  v &= 0xf;
	  if (v & 0x8)
	    v |= -1 ^ 0x7;
	  /* unsigned necessary due to left shifts of -ve values.  */
	  unsigned HOST_WIDE_INT uv = (unsigned HOST_WIDE_INT) v;
	  if ((ptr = read (++bytes)))
	    while (bytes--)
	      uv = (uv << 8) | (*ptr++ & 0xff);
	  v = (HOST_WIDE_INT) uv;
	}
      else if (v & 0x40)
	v |= -1 ^ 0x3f;
    }

  return v;
}

/* unsigned wide ints are just written as signed wide ints.  */

inline void
bytes_out::wu (unsigned HOST_WIDE_INT v)
{
  wi ((HOST_WIDE_INT) v);
}

inline unsigned HOST_WIDE_INT
bytes_in::wu ()
{
  return (unsigned HOST_WIDE_INT) wi ();
}

/* size_t written as unsigned or unsigned wide int.  */

inline void
bytes_out::z (size_t s)
{
  if (sizeof (s) == sizeof (unsigned))
    u (s);
  else
    wu (s);
}

inline size_t
bytes_in::z ()
{
  if (sizeof (size_t) == sizeof (unsigned))
    return u ();
  else
    return wu ();
}

/* Buffer simply memcpied.  */
void *
bytes_out::buf (size_t len)
{
  align (sizeof (void *) * 2);
  return write (len);
}

void
bytes_out::buf (const void *src, size_t len)
{
  if (void *ptr = buf (len))
    memcpy (ptr, src, len);
}

const void *
bytes_in::buf (size_t len)
{
  align (sizeof (void *) * 2);
  const char *ptr = read (len);

  return ptr;
}

/* strings as an size_t length, followed by the buffer.  Make sure
   there's a NUL terminator on read.  */

void
bytes_out::str (const char *string, size_t len)
{
  z (len);
  if (len)
    {
      gcc_checking_assert (!string[len]);
      buf (string, len + 1);
    }
}

const char *
bytes_in::str (size_t *len_p)
{
  size_t len = z ();

  /* We're about to trust some user data.  */
  if (overrun)
    len = 0;
  if (len_p)
    *len_p = len;
  const char *str = NULL;
  if (len)
    {
      str = reinterpret_cast<const char *> (buf (len + 1));
      if (!str || str[len])
	{
	  set_overrun ();
	  str = NULL;
	}
    }
  return str ? str : "";
}

cpp_hashnode *
bytes_in::cpp_node ()
{
  size_t len;
  const char *s = str (&len);
  if (!len)
    return NULL;
  return ::cpp_node (get_identifier_with_length (s, len));
}

/* Format a string directly to the buffer, including a terminating
   NUL.  Intended for human consumption.  */

void
bytes_out::printf (const char *format, ...)
{
  va_list args;
  /* Exercise buffer expansion.  */
  size_t len = EXPERIMENT (10, 500);

  while (char *ptr = write (len))
    {
      va_start (args, format);
      size_t actual = vsnprintf (ptr, len, format, args) + 1;
      va_end (args);
      if (actual <= len)
	{
	  unuse (len - actual);
	  break;
	}
      unuse (len);
      len = actual;
    }
}

void
bytes_out::print_time (const char *kind, const tm *time, const char *tz)
{
  printf ("%stime: %4u/%02u/%02u %02u:%02u:%02u %s",
	  kind, time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
	  time->tm_hour, time->tm_min, time->tm_sec, tz);
}

/* Encapsulated Lazy Records Of Named Declarations.
   Header: Stunningly Elf32_Ehdr-like
   Sections: Sectional data
     [1-N) : User data sections
     N .strtab  : strings, stunningly ELF STRTAB-like
   Index: Section table, stunningly ELF32_Shdr-like.   */

class elf {
protected:
  /* Constants used within the format.  */
  enum private_constants {
    /* File kind. */
    ET_NONE = 0,
    EM_NONE = 0,
    OSABI_NONE = 0,

    /* File format. */
    EV_CURRENT = 1,
    CLASS32 = 1,
    DATA2LSB = 1,
    DATA2MSB = 2,

    /* Section numbering.  */
    SHN_UNDEF = 0,
    SHN_LORESERVE = 0xff00,
    SHN_XINDEX = 0xffff,

    /* Section types.  */
    SHT_NONE = 0,	/* No contents.  */
    SHT_PROGBITS = 1, /* Random bytes.  */
    SHT_STRTAB = 3,	/* A string table.  */

    /* Section flags.  */
    SHF_NONE = 0x00,	/* Nothing.  */
    SHF_STRINGS = 0x20,  /* NUL-Terminated strings.  */

    /* I really hope we do not get CMI files larger than 4GB.  */
    MY_CLASS = CLASS32,
    /* It is host endianness that is relevant.  */
    MY_ENDIAN = DATA2LSB
#ifdef WORDS_BIGENDIAN
    ^ DATA2LSB ^ DATA2MSB
#endif
  };

public:
  /* Constants visible to users.  */
  enum public_constants {
    /* Special error codes.  Breaking layering a bit.  */
    E_BAD_DATA = -1,  /* Random unexpected data errors.  */
    E_BAD_LAZY = -2,  /* Badly ordered laziness.  */
    E_BAD_IMPORT = -3 /* A nested import failed.  */
  };

protected:
  /* File identification.  On-disk representation.  */
  struct ident {
    uint8_t magic[4];	/* 0x7f, 'E', 'L', 'F' */
    uint8_t klass;	/* 4:CLASS32 */
    uint8_t data;	/* 5:DATA2[LM]SB */
    uint8_t version;	/* 6:EV_CURRENT  */
    uint8_t osabi;	/* 7:OSABI_NONE */
    uint8_t abiver;	/* 8: 0 */
    uint8_t pad[7];	/* 9-15 */
  };
  /* File header.  On-disk representation.  */
  struct header {
    struct ident ident;
    uint16_t type;	/* ET_NONE */
    uint16_t machine;	/* EM_NONE */
    uint32_t version;	/* EV_CURRENT */
    uint32_t entry;	/* 0 */
    uint32_t phoff;	/* 0 */
    uint32_t shoff;	/* Section Header Offset in file */
    uint32_t flags; 
    uint16_t ehsize;	/* ELROND Header SIZE -- sizeof (header) */
    uint16_t phentsize; /* 0 */
    uint16_t phnum;	/* 0 */
    uint16_t shentsize; /* Section Header SIZE -- sizeof (section) */
    uint16_t shnum;	/* Section Header NUM */
    uint16_t shstrndx;	/* Section Header STRing iNDeX */
  };
  /* File section.  On-disk representation.  */
  struct section {
    uint32_t name;	/* String table offset.  */
    uint32_t type;	/* SHT_* */
    uint32_t flags;	/* SHF_* */
    uint32_t addr;	/* 0 */
    uint32_t offset;	/* OFFSET in file */
    uint32_t size;	/* SIZE of section */
    uint32_t link;	/* 0 */
    uint32_t info;	/* 0 */
    uint32_t addralign; /* 0 */
    uint32_t entsize;	/* ENTry SIZE, usually 0 */
  };

protected:
  data hdr;	/* The header.  */
  data sectab; 	/* The section table.  */
  data strtab;  /* String table.  */
  int fd;   	/* File descriptor we're reading or writing.  */
  int err; 	/* Sticky error code.  */

public:
  /* Construct from STREAM.  E is errno if STREAM NULL.  */
  elf (int fd, int e)
    :hdr (), sectab (), strtab (), fd (fd), err (fd >= 0 ? 0 : e)
  {}
  ~elf ()
  {
    gcc_checking_assert (fd < 0 && !hdr.buffer
			 && !sectab.buffer && !strtab.buffer);
  }

public:
  /* Return the error, if we have an error.  */
  int get_error () const
  {
    return err;
  }
  /* Set the error, unless it's already been set.  */
  void set_error (int e = E_BAD_DATA)
  {
    if (!err)
      err = e;
  }
  /* Get an error string.  */
  const char *get_error (const char *) const;

public:
  /* Begin reading/writing file.  Return false on error.  */
  bool begin () const
  {
    return !get_error ();
  }
  /* Finish reading/writing file.  Return false on error.  */
  bool end ();
};

/* Return error string.  */

const char *
elf::get_error (const char *name) const
{
  if (!name)
    return "Unknown CMI mapping";

  switch (err)
    {
    case 0:
      gcc_unreachable ();
    case E_BAD_DATA:
      return "Bad file data";
    case E_BAD_IMPORT:
      return "Bad import dependency";
    case E_BAD_LAZY:
      return "Bad lazy ordering";
    default:
      return xstrerror (err);
    }
}

/* Finish file, return true if there's an error.  */

bool
elf::end ()
{
  /* Close the stream and free the section table.  */
  if (fd >= 0 && close (fd))
    set_error (errno);
  fd = -1;

  return !get_error ();
}

/* ELROND reader.  */

class elf_in : public elf {
  typedef elf parent;

private:
  /* For freezing & defrosting.  */
#if !defined (HOST_LACKS_INODE_NUMBERS)
  dev_t device;
  ino_t inode;
#endif

public:
  elf_in (int fd, int e)
    :parent (fd, e)
  {
  }
  ~elf_in ()
  {
  }

public:
  bool is_frozen () const
  {
    return fd < 0 && hdr.pos;
  }
  bool is_freezable () const
  {
    return fd >= 0 && hdr.pos;
  }
  void freeze ();
  bool defrost (const char *);

  /* If BYTES is in the mmapped area, allocate a new buffer for it.  */
  void preserve (bytes_in &bytes ATTRIBUTE_UNUSED)
  {
#if MAPPED_READING
    if (hdr.buffer && bytes.buffer >= hdr.buffer
	&& bytes.buffer < hdr.buffer + hdr.pos)
      {
	char *buf = bytes.buffer;
	bytes.buffer = data::simple_memory.grow (NULL, bytes.size);
	memcpy (bytes.buffer, buf, bytes.size);
      }
#endif
  }
  /* If BYTES is not in SELF's mmapped area, free it.  SELF might be
     NULL. */
  static void release (elf_in *self ATTRIBUTE_UNUSED, bytes_in &bytes)
  {
#if MAPPED_READING
    if (!(self && self->hdr.buffer && bytes.buffer >= self->hdr.buffer
	  && bytes.buffer < self->hdr.buffer + self->hdr.pos))
#endif
      data::simple_memory.shrink (bytes.buffer);
    bytes.buffer = NULL;
    bytes.size = 0;
  }

public:
  static void grow (data &data, unsigned needed)
  {
    gcc_checking_assert (!data.buffer);
#if !MAPPED_READING
    data.buffer = XNEWVEC (char, needed);
#endif
    data.size = needed;
  }
  static void shrink (data &data)
  {
#if !MAPPED_READING
    XDELETEVEC (data.buffer);
#endif
    data.buffer = NULL;
    data.size = 0;
  }

public:
  const section *get_section (unsigned s) const
  {
    if (s * sizeof (section) < sectab.size)
      return reinterpret_cast<const section *>
	(&sectab.buffer[s * sizeof (section)]);
    else
      return NULL;
  }
  unsigned get_section_limit () const
  {
    return sectab.size / sizeof (section);
  }

protected:
  const char *read (data *, unsigned, unsigned);

public:
  /* Read section by number.  */
  bool read (data *d, const section *s)
  {
    return s && read (d, s->offset, s->size);
  }

  /* Find section by name.  */
  unsigned find (const char *name);
  /* Find section by index.  */
  const section *find (unsigned snum, unsigned type = SHT_PROGBITS);

public:
  /* Release the string table, when we're done with it.  */
  void release ()
  {
    shrink (strtab);
  }

public:
  bool begin (location_t);
  bool end ()
  {
    release ();
#if MAPPED_READING
    if (hdr.buffer)
      munmap (hdr.buffer, hdr.pos);
    hdr.buffer = NULL;
#endif
    shrink (sectab);

    return parent::end ();
  }

public:
  /* Return string name at OFFSET.  Checks OFFSET range.  Always
     returns non-NULL.  We know offset 0 is an empty string.  */
  const char *name (unsigned offset)
  {
    return &strtab.buffer[offset < strtab.size ? offset : 0];
  }
};

/* ELROND writer.  */

class elf_out : public elf, public data::allocator {
  typedef elf parent;
  /* Desired section alignment on disk.  */
  static const int SECTION_ALIGN = 16;

private:
  ptr_int_hash_map identtab;	/* Map of IDENTIFIERS to strtab offsets. */
  unsigned pos;			/* Write position in file.  */
#if MAPPED_WRITING
  unsigned offset;		/* Offset of the mapping.  */
  unsigned extent;		/* Length of mapping.  */
  unsigned page_size;		/* System page size.  */
#endif

public:
  elf_out (int fd, int e)
    :parent (fd, e), identtab (500), pos (0)
  {
#if MAPPED_WRITING
    offset = extent = 0;
    page_size = sysconf (_SC_PAGE_SIZE);
    if (page_size < SECTION_ALIGN)
      /* Something really strange.  */
      set_error (EINVAL);
#endif
  }
  ~elf_out ()
  {
    data::simple_memory.shrink (hdr);
    data::simple_memory.shrink (sectab);
    data::simple_memory.shrink (strtab);
  }

#if MAPPED_WRITING
private:
  void create_mapping (unsigned ext, bool extending = true);
  void remove_mapping ();
#endif

protected:
  using allocator::grow;
  virtual char *grow (char *, unsigned needed);
#if MAPPED_WRITING
  using allocator::shrink;
  virtual void shrink (char *);
#endif

public:
  unsigned get_section_limit () const
  {
    return sectab.pos / sizeof (section);
  }

protected:
  unsigned add (unsigned type, unsigned name = 0,
		unsigned off = 0, unsigned size = 0, unsigned flags = SHF_NONE);
  unsigned write (const data &);
#if MAPPED_WRITING
  unsigned write (const bytes_out &);
#endif

public:
  /* IDENTIFIER to strtab offset.  */
  unsigned name (tree ident);
  /* String literal to strtab offset.  */
  unsigned name (const char *n);
  /* Qualified name of DECL to strtab offset.  */
  unsigned qualified_name (tree decl, bool is_defn);

private:
  unsigned strtab_write (const char *s, unsigned l);
  void strtab_write (tree decl, int);

public:
  /* Add a section with contents or strings.  */
  unsigned add (const bytes_out &, bool string_p, unsigned name);

public:
  /* Begin and end writing.  */
  bool begin ();
  bool end ();
};

/* Begin reading section NAME (of type PROGBITS) from SOURCE.
   Data always checked for CRC.  */

bool
bytes_in::begin (location_t loc, elf_in *source, const char *name)
{
  unsigned snum = source->find (name);

  return begin (loc, source, snum, name);
}

/* Begin reading section numbered SNUM with NAME (may be NULL).  */

bool
bytes_in::begin (location_t loc, elf_in *source, unsigned snum, const char *name)
{
  if (!source->read (this, source->find (snum))
      || !size || !check_crc ())
    {
      source->set_error (elf::E_BAD_DATA);
      source->shrink (*this);
      if (name)
	error_at (loc, "section %qs is missing or corrupted", name);
      else
	error_at (loc, "section #%u is missing or corrupted", snum);
      return false;
    }
  pos = 4;
  return true;
}

/* Finish reading a section.  */

bool
bytes_in::end (elf_in *src)
{
  if (more_p ())
    set_overrun ();
  if (overrun)
    src->set_error ();

  src->shrink (*this);

  return !overrun;
}

/* Begin writing buffer.  */

void
bytes_out::begin (bool need_crc)
{
  if (need_crc)
    pos = 4;
  memory->grow (*this, 0, false);
}

/* Finish writing buffer.  Stream out to SINK as named section NAME.
   Return section number or 0 on failure.  If CRC_PTR is true, crc
   the data.  Otherwise it is a string section.  */

unsigned
bytes_out::end (elf_out *sink, unsigned name, unsigned *crc_ptr)
{
  lengths[3] += pos;
  spans[3]++;

  set_crc (crc_ptr);
  unsigned sec_num = sink->add (*this, !crc_ptr, name);
  memory->shrink (*this);

  return sec_num;
}

/* Close and open the file, without destroying it.  */

void
elf_in::freeze ()
{
  gcc_checking_assert (!is_frozen ());
#if MAPPED_READING
  if (munmap (hdr.buffer, hdr.pos) < 0)
    set_error (errno);
#endif
  if (close (fd) < 0)
    set_error (errno);
  fd = -1;
}

bool
elf_in::defrost (const char *name)
{
  gcc_checking_assert (is_frozen ());
  struct stat stat;

  fd = open (name, O_RDONLY | O_CLOEXEC | O_BINARY);
  if (fd < 0 || fstat (fd, &stat) < 0)
    set_error (errno);
  else
    {
      bool ok = hdr.pos == unsigned (stat.st_size);
#ifndef HOST_LACKS_INODE_NUMBERS
      if (device != stat.st_dev
	  || inode != stat.st_ino)
	ok = false;
#endif
      if (!ok)
	set_error (EMFILE);
#if MAPPED_READING
      if (ok)
	{
	  char *mapping = reinterpret_cast<char *>
	    (mmap (NULL, hdr.pos, PROT_READ, MAP_SHARED, fd, 0));
	  if (mapping == MAP_FAILED)
	  fail:
	      set_error (errno);
	  else
	    {
	      if (madvise (mapping, hdr.pos, MADV_RANDOM))
		goto fail;

	      /* These buffers are never NULL in this case.  */
	      strtab.buffer = mapping + strtab.pos;
	      sectab.buffer = mapping + sectab.pos;
	      hdr.buffer = mapping;
	    }
	}
#endif
    }

  return !get_error ();
}

/* Read at current position into BUFFER.  Return true on success.  */

const char *
elf_in::read (data *data, unsigned pos, unsigned length)
{
#if MAPPED_READING
  if (pos + length > hdr.pos)
    {
      set_error (EINVAL);
      return NULL;
    }
#else
  if (pos != ~0u && lseek (fd, pos, SEEK_SET) < 0)
    {
      set_error (errno);
      return NULL;
    }
#endif
  grow (*data, length);
#if MAPPED_READING  
  data->buffer = hdr.buffer + pos;
#else
  if (::read (fd, data->buffer, data->size) != ssize_t (length))
    {
      set_error (errno);
      shrink (*data);
      return NULL;
    }
#endif

  return data->buffer;
}

/* Read section SNUM of TYPE.  Return section pointer or NULL on error.  */

const elf::section *
elf_in::find (unsigned snum, unsigned type)
{
  const section *sec = get_section (snum);
  if (!snum || !sec || sec->type != type)
    return NULL;
  return sec;
}

/* Find a section NAME and TYPE.  Return section number, or zero on
   failure.  */

unsigned
elf_in::find (const char *sname)
{
  for (unsigned pos = sectab.size; pos -= sizeof (section); )
    {
      const section *sec
	= reinterpret_cast<const section *> (&sectab.buffer[pos]);

      if (0 == strcmp (sname, name (sec->name)))
	return pos / sizeof (section);
    }

  return 0;
}

/* Begin reading file.  Verify header.  Pull in section and string
   tables.  Return true on success.  */

bool
elf_in::begin (location_t loc)
{
  if (!parent::begin ())
    return false;

  struct stat stat;
  unsigned size = 0;
  if (!fstat (fd, &stat))
    {
#if !defined (HOST_LACKS_INODE_NUMBERS)
      device = stat.st_dev;
      inode = stat.st_ino;
#endif
      /* Never generate files > 4GB, check we've not been given one.  */
      if (stat.st_size == unsigned (stat.st_size))
	size = unsigned (stat.st_size);
    }

#if MAPPED_READING
  /* MAP_SHARED so that the file is backing store.  If someone else
     concurrently writes it, they're wrong.  */
  void *mapping = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  if (mapping == MAP_FAILED)
    {
    fail:
      set_error (errno);
      return false;
    }
  /* We'll be hopping over this randomly.  Some systems declare the
     first parm as char *, and other declare it as void *.  */
  if (madvise (reinterpret_cast <char *> (mapping), size, MADV_RANDOM))
    goto fail;

  hdr.buffer = (char *)mapping;
#else
  read (&hdr, 0, sizeof (header));
#endif
  hdr.pos = size; /* Record size of the file.  */

  const header *h = reinterpret_cast<const header *> (hdr.buffer);
  if (!h)
    return false;

  if (h->ident.magic[0] != 0x7f
      || h->ident.magic[1] != 'E'
      || h->ident.magic[2] != 'L'
      || h->ident.magic[3] != 'F')
    {
      error_at (loc, "not Encapsulated Lazy Records of Named Declarations");
    failed:
      shrink (hdr);
      return false;
    }

  /* We expect a particular format -- the ELF is not intended to be
     distributable.  */
  if (h->ident.klass != MY_CLASS
      || h->ident.data != MY_ENDIAN
      || h->ident.version != EV_CURRENT
      || h->type != ET_NONE
      || h->machine != EM_NONE
      || h->ident.osabi != OSABI_NONE)
    {
      error_at (loc, "unexpected encapsulation format or type");
      goto failed;
    }

  int e = -1;
  if (!h->shoff || h->shentsize != sizeof (section))
    {
    malformed:
      set_error (e);
      error_at (loc, "encapsulation is malformed");
      goto failed;
    }

  unsigned strndx = h->shstrndx;
  unsigned shnum = h->shnum;
  if (shnum == SHN_XINDEX)
    {
      if (!read (&sectab, h->shoff, sizeof (section)))
	{
	section_table_fail:
	  e = errno;
	  goto malformed;
	}
      shnum = get_section (0)->size;
      /* Freeing does mean we'll re-read it in the case we're not
	 mapping, but this is going to be rare.  */
      shrink (sectab);
    }

  if (!shnum)
    goto malformed;

  if (!read (&sectab, h->shoff, shnum * sizeof (section)))
    goto section_table_fail;

  if (strndx == SHN_XINDEX)
    strndx = get_section (0)->link;

  if (!read (&strtab, find (strndx, SHT_STRTAB)))
    goto malformed;

  /* The string table should be at least one byte, with NUL chars
     at either end.  */
  if (!(strtab.size && !strtab.buffer[0]
	&& !strtab.buffer[strtab.size - 1]))
    goto malformed;

#if MAPPED_READING
  /* Record the offsets of the section and string tables.  */
  sectab.pos = h->shoff;
  strtab.pos = shnum * sizeof (section);
#else
  shrink (hdr);
#endif

  return true;
}

/* Create a new mapping.  */

#if MAPPED_WRITING
void
elf_out::create_mapping (unsigned ext, bool extending)
{
#ifndef HAVE_POSIX_FALLOCATE
#define posix_fallocate(fd,off,len) ftruncate (fd, off + len)
#endif
  void *mapping = MAP_FAILED;
  if (extending && ext < 1024 * 1024)
    {
      if (!posix_fallocate (fd, offset, ext * 2))
	mapping = mmap (NULL, ext * 2, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, offset);
      if (mapping != MAP_FAILED)
	ext *= 2;
    }
  if (mapping == MAP_FAILED)
    {
      if (!extending || !posix_fallocate (fd, offset, ext))
	mapping = mmap (NULL, ext, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, offset);
      if (mapping == MAP_FAILED)
	{
	  set_error (errno);
	  mapping = NULL;
	  ext = 0;
	}
    }
#undef posix_fallocate
  hdr.buffer = (char *)mapping;
  extent = ext;
}
#endif

/* Flush out the current mapping.  */

#if MAPPED_WRITING
void
elf_out::remove_mapping ()
{
  if (hdr.buffer)
    {
      /* MS_ASYNC dtrt with the removed mapping, including a
	 subsequent overlapping remap.  */
      if (msync (hdr.buffer, extent, MS_ASYNC)
	  || munmap (hdr.buffer, extent))
	/* We're somewhat screwed at this point.  */
	set_error (errno);
    }

  hdr.buffer = NULL;
}
#endif

/* Grow a mapping of PTR to be NEEDED bytes long.  This gets
   interesting if the new size grows the EXTENT.  */

char *
elf_out::grow (char *data, unsigned needed)
{
  if (!data)
    {
      /* First allocation, check we're aligned.  */
      gcc_checking_assert (!(pos & (SECTION_ALIGN - 1)));
#if MAPPED_WRITING
      data = hdr.buffer + (pos - offset);
#endif
    }

#if MAPPED_WRITING
  unsigned off = data - hdr.buffer;
  if (off + needed > extent)
    {
      /* We need to grow the mapping.  */
      unsigned lwm = off & ~(page_size - 1);
      unsigned hwm = (off + needed + page_size - 1) & ~(page_size - 1);

      gcc_checking_assert (hwm > extent);

      remove_mapping ();

      offset += lwm;
      create_mapping (extent < hwm - lwm ? hwm - lwm : extent);

      data = hdr.buffer + (off - lwm);
    }
#else
  data = allocator::grow (data, needed);
#endif

  return data;
}

#if MAPPED_WRITING
/* Shrinking is a NOP.  */
void
elf_out::shrink (char *)
{
}
#endif

/* Write S of length L to the strtab buffer.  L must include the ending
   NUL, if that's what you want.  */

unsigned
elf_out::strtab_write (const char *s, unsigned l)
{
  if (strtab.pos + l > strtab.size)
    data::simple_memory.grow (strtab, strtab.pos + l, false);
  memcpy (strtab.buffer + strtab.pos, s, l);
  unsigned res = strtab.pos;
  strtab.pos += l;
  return res;
}

/* Write qualified name of decl.  INNER >0 if this is a definition, <0
   if this is a qualifier of an outer name.  */

void
elf_out::strtab_write (tree decl, int inner)
{
  tree ctx = CP_DECL_CONTEXT (decl);
  if (TYPE_P (ctx))
    ctx = TYPE_NAME (ctx);
  if (ctx != global_namespace)
    strtab_write (ctx, -1);

  tree name = DECL_NAME (decl);
  if (!name)
    name = DECL_ASSEMBLER_NAME_RAW (decl);
  strtab_write (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));

  if (inner)
    strtab_write (&"::{}"[inner+1], 2);
}

/* Map IDENTIFIER IDENT to strtab offset.  Inserts into strtab if not
   already there.  */

unsigned
elf_out::name (tree ident)
{
  unsigned res = 0;
  if (ident)
    {
      bool existed;
      int *slot = &identtab.get_or_insert (ident, &existed);
      if (!existed)
	*slot = strtab_write (IDENTIFIER_POINTER (ident),
			      IDENTIFIER_LENGTH (ident) + 1);
      res = *slot;
    }
  return res;
}

/* Map LITERAL to strtab offset.  Does not detect duplicates and
   expects LITERAL to remain live until strtab is written out.  */

unsigned
elf_out::name (const char *literal)
{
  return strtab_write (literal, strlen (literal) + 1);
}

/* Map a DECL's qualified name to strtab offset.  Does not detect
   duplicates.  */

unsigned
elf_out::qualified_name (tree decl, bool is_defn)
{
  gcc_checking_assert (DECL_P (decl) && decl != global_namespace);
  unsigned result = strtab.pos;

  strtab_write (decl, is_defn);
  strtab_write ("", 1);

  return result;
}

/* Add section to file.  Return section number.  TYPE & NAME identify
   the section.  OFF and SIZE identify the file location of its
   data.  FLAGS contains additional info.  */

unsigned
elf_out::add (unsigned type, unsigned name, unsigned off, unsigned size,
	      unsigned flags)
{
  gcc_checking_assert (!(off & (SECTION_ALIGN - 1)));
  if (sectab.pos + sizeof (section) > sectab.size)
    data::simple_memory.grow (sectab, sectab.pos + sizeof (section), false);
  section *sec = reinterpret_cast<section *> (sectab.buffer + sectab.pos);
  memset (sec, 0, sizeof (section));
  sec->type = type;
  sec->flags = flags;
  sec->name = name;
  sec->offset = off;
  sec->size = size;
  if (flags & SHF_STRINGS)
    sec->entsize = 1;

  unsigned res = sectab.pos;
  sectab.pos += sizeof (section);
  return res / sizeof (section);
}

/* Pad to the next alignment boundary, then write BUFFER to disk.
   Return the position of the start of the write, or zero on failure.   */

unsigned
elf_out::write (const data &buffer)
{
#if MAPPED_WRITING
  /* HDR is always mapped.  */
  if (&buffer != &hdr)
    {
      bytes_out out (this);
      grow (out, buffer.pos, true);
      if (out.buffer)
	memcpy (out.buffer, buffer.buffer, buffer.pos);
      shrink (out);
    }
  else
    /* We should have been aligned during the first allocation.  */
    gcc_checking_assert (!(pos & (SECTION_ALIGN - 1)));
#else
  if (::write (fd, buffer.buffer, buffer.pos) != ssize_t (buffer.pos))
    {
      set_error (errno);
      return 0;
    }
#endif
  unsigned res = pos;
  pos += buffer.pos;

  if (unsigned padding = -pos & (SECTION_ALIGN - 1))
    {
#if !MAPPED_WRITING
      /* Align the section on disk, should help the necessary copies.
	 fseeking to extend is non-portable.  */
      static char zero[SECTION_ALIGN];
      if (::write (fd, &zero, padding) != ssize_t (padding))
	set_error (errno);
#endif
      pos += padding;
    }
  return res;
}

/* Write a streaming buffer.  It must be using us as an allocator.  */

#if MAPPED_WRITING
unsigned
elf_out::write (const bytes_out &buf)
{
  gcc_checking_assert (buf.memory == this);
  /* A directly mapped buffer.  */
  gcc_checking_assert (buf.buffer - hdr.buffer >= 0
		       && buf.buffer - hdr.buffer + buf.size <= extent);
  unsigned res = pos;
  pos += buf.pos;

  /* Align up.  We're not going to advance into the next page. */
  pos += -pos & (SECTION_ALIGN - 1);

  return res;
}
#endif

/* Write data and add section.  STRING_P is true for a string
   section, false for PROGBITS.  NAME identifies the section (0 is the
   empty name).  DATA is the contents.  Return section number or 0 on
   failure (0 is the undef section).  */

unsigned
elf_out::add (const bytes_out &data, bool string_p, unsigned name)
{
  unsigned off = write (data);

  return add (string_p ? SHT_STRTAB : SHT_PROGBITS, name,
	      off, data.pos, string_p ? SHF_STRINGS : SHF_NONE);
}

/* Begin writing the file.  Initialize the section table and write an
   empty header.  Return false on failure.  */

bool
elf_out::begin ()
{
  if (!parent::begin ())
    return false;

  /* Let the allocators pick a default.  */
  data::simple_memory.grow (strtab, 0, false);
  data::simple_memory.grow (sectab, 0, false);

  /* The string table starts with an empty string.  */
  name ("");

  /* Create the UNDEF section.  */
  add (SHT_NONE);

#if MAPPED_WRITING
  /* Start a mapping.  */
  create_mapping (EXPERIMENT (page_size,
			      (32767 + page_size) & ~(page_size - 1)));
  if (!hdr.buffer)
    return false;
#endif

  /* Write an empty header.  */
  grow (hdr, sizeof (header), true);
  header *h = reinterpret_cast<header *> (hdr.buffer);
  memset (h, 0, sizeof (header));
  hdr.pos = hdr.size;
  write (hdr);
  return !get_error ();
}

/* Finish writing the file.  Write out the string & section tables.
   Fill in the header.  Return true on error.  */

bool
elf_out::end ()
{
  if (fd >= 0)
    {
      /* Write the string table.  */
      unsigned strnam = name (".strtab");
      unsigned stroff = write (strtab);
      unsigned strndx = add (SHT_STRTAB, strnam, stroff, strtab.pos,
			     SHF_STRINGS);

      /* Store escape values in section[0].  */
      if (strndx >= SHN_LORESERVE)
	{
	  reinterpret_cast<section *> (sectab.buffer)->link = strndx;
	  strndx = SHN_XINDEX;
	}
      unsigned shnum = sectab.pos / sizeof (section);
      if (shnum >= SHN_LORESERVE)
	{
	  reinterpret_cast<section *> (sectab.buffer)->size = shnum;
	  shnum = SHN_XINDEX;
	}

      unsigned shoff = write (sectab);

#if MAPPED_WRITING
      if (offset)
	{
	  remove_mapping ();
	  offset = 0;
	  create_mapping ((sizeof (header) + page_size - 1) & ~(page_size - 1),
			  false);
	}
      unsigned length = pos;
#else
      if (lseek (fd, 0, SEEK_SET) < 0)
	set_error (errno);
#endif
      /* Write header.  */
      if (!get_error ())
	{
	  /* Write the correct header now.  */
	  header *h = reinterpret_cast<header *> (hdr.buffer);
	  h->ident.magic[0] = 0x7f;
	  h->ident.magic[1] = 'E';	/* Elrond */
	  h->ident.magic[2] = 'L';	/* is an */
	  h->ident.magic[3] = 'F';	/* elf.  */
	  h->ident.klass = MY_CLASS;
	  h->ident.data =  MY_ENDIAN;
	  h->ident.version = EV_CURRENT;
	  h->ident.osabi = OSABI_NONE;
	  h->type = ET_NONE;
	  h->machine = EM_NONE;
	  h->version = EV_CURRENT;
	  h->shoff = shoff;
	  h->ehsize = sizeof (header);
	  h->shentsize = sizeof (section);
	  h->shnum = shnum;
	  h->shstrndx = strndx;

	  pos = 0;
	  write (hdr);
	}

#if MAPPED_WRITING
      remove_mapping ();
      if (ftruncate (fd, length))
	set_error (errno);
#endif
    }

  data::simple_memory.shrink (sectab);
  data::simple_memory.shrink (strtab);

  return parent::end ();
}

/********************************************************************/

/* A dependency set.  This is used during stream out to determine the
   connectivity of the graph.  Every namespace-scope declaration that
   needs writing has a depset.  The depset is filled with the (depsets
   of) declarations within this module that it references.  For a
   declaration that'll generally be named types.  For definitions
   it'll also be declarations in the body.

   From that we can convert the graph to a DAG, via determining the
   Strongly Connected Clusters.  Each cluster is streamed
   independently, and thus we achieve lazy loading.

   Other decls that get a depset are namespaces themselves and
   unnameable declarations.   */

class depset {
private:
  tree entity;  /* Entity, or containing namespace.  */
  uintptr_t discriminator;  /* Flags or identifier.  */

public:
  /* The kinds of entity the depset could describe.  The ordering is
     significant, see entity_kind_name.  */
  enum entity_kind
  {
    EK_DECL,		/* A decl.  */
    EK_SPECIALIZATION,  /* A specialization.  */
    EK_PARTIAL,		/* A partial specialization.  */
    EK_USING,		/* A using declaration (at namespace scope).  */
    EK_NAMESPACE,	/* A namespace.  */
    EK_REDIRECT,	/* Redirect to a template_decl.  */
    EK_EXPLICIT_HWM,  
    EK_BINDING = EK_EXPLICIT_HWM, /* Implicitly encoded.  */
    EK_FOR_BINDING,	/* A decl being inserted for a binding.  */
    EK_INNER_DECL,	/* A decl defined outside of it's imported
			   context.  */
    EK_DIRECT_HWM = EK_PARTIAL + 1,

    EK_BITS = 3		/* Only need to encode below EK_EXPLICIT_HWM.  */
  };

private:
  /* Placement of bit fields in discriminator.  */
  enum disc_bits 
  {
    DB_ZERO_BIT, /* Set to disambiguate identifier from flags  */
    DB_SPECIAL_BIT, /* First dep slot is special.  */
    DB_KIND_BIT, /* Kind of the entity.  */
    DB_KIND_BITS = EK_BITS,
    DB_DEFN_BIT = DB_KIND_BIT + DB_KIND_BITS,
    DB_IS_MEMBER_BIT,		/* Is an out-of-class member.  */
    DB_IS_INTERNAL_BIT,		/* It is an (erroneous)
				   internal-linkage entity.  */
    DB_REFS_INTERNAL_BIT,	/* Refers to an internal-linkage
				   entity. */
    DB_IMPORTED_BIT,		/* An imported entity.  */
    DB_UNREACHED_BIT,		/* A yet-to-be reached entity.  */
    DB_HIDDEN_BIT,		/* A hidden binding.  */
    /* The following bits are not independent, but enumerating them is
       awkward.  */
    DB_ALIAS_TMPL_INST_BIT,	/* An alias template instantiation. */
    DB_ALIAS_SPEC_BIT,		/* Specialization of an alias template
				   (in both spec tables).  */
    DB_TYPE_SPEC_BIT,		/* Specialization in the type table.
				   */
    DB_FRIEND_SPEC_BIT,		/* An instantiated template friend.  */
  };

public:
  /* The first slot is special for EK_SPECIALIZATIONS it is a
     spec_entry pointer.  It is not relevant for the SCC
     determination.  */
  vec<depset *> deps;  /* Depsets we reference.  */

public:
  unsigned cluster; /* Strongly connected cluster, later entity number  */
  unsigned section; /* Section written to.  */
  /* During SCC construction, section is lowlink, until the depset is
     removed from the stack.  See Tarjan algorithm for details.  */

private:
  /* Construction via factories.  Destruction via hash traits.  */
  depset (tree entity);
  ~depset ();

public:
  static depset *make_binding (tree, tree);
  static depset *make_entity (tree, entity_kind, bool = false);
  /* Late setting a binding name -- /then/ insert into hash!  */
  inline void set_binding_name (tree name)
  {
    gcc_checking_assert (!get_name ());
    discriminator = reinterpret_cast<uintptr_t> (name);
  }

private:
  template<unsigned I> void set_flag_bit ()
  {
    gcc_checking_assert (I < 2 || !is_binding ());
    discriminator |= 1u << I;
  }
  template<unsigned I> void clear_flag_bit ()
  {
    gcc_checking_assert (I < 2 || !is_binding ());
    discriminator &= ~(1u << I);
  }
  template<unsigned I> bool get_flag_bit () const
  {
    gcc_checking_assert (I < 2 || !is_binding ());
    return bool ((discriminator >> I) & 1);
  }
  
public:
  bool is_binding () const
  {
    return !get_flag_bit<DB_ZERO_BIT> ();
  }
  entity_kind get_entity_kind () const
  {
    if (is_binding ())
      return EK_BINDING;
    return entity_kind ((discriminator >> DB_KIND_BIT) & ((1u << EK_BITS) - 1));
  }
  const char *entity_kind_name () const;

public:
  bool has_defn () const
  {
    return get_flag_bit<DB_DEFN_BIT> ();
  }

public:
  /* This class-member is defined here, but the class was imported.  */
  bool is_member () const
  {
    gcc_checking_assert (get_entity_kind () == EK_DECL);
    return get_flag_bit<DB_IS_MEMBER_BIT> ();
  }
public:
  bool is_internal () const
  {
    return get_flag_bit<DB_IS_INTERNAL_BIT> ();
  }
  bool refs_internal () const
  {
    return get_flag_bit<DB_REFS_INTERNAL_BIT> ();
  }
  bool is_import () const
  {
    return get_flag_bit<DB_IMPORTED_BIT> ();
  }
  bool is_unreached () const
  {
    return get_flag_bit<DB_UNREACHED_BIT> ();
  }
  bool is_alias_tmpl_inst () const
  {
    return get_flag_bit<DB_ALIAS_TMPL_INST_BIT> ();
  }
  bool is_alias () const
  {
    return get_flag_bit<DB_ALIAS_SPEC_BIT> ();
  }
  bool is_hidden () const
  {
    return get_flag_bit<DB_HIDDEN_BIT> ();
  }
  bool is_type_spec () const
  {
    return get_flag_bit<DB_TYPE_SPEC_BIT> ();
  }
  bool is_friend_spec () const
  {
    return get_flag_bit<DB_FRIEND_SPEC_BIT> ();
  }

public:
  /* We set these bit outside of depset.  */
  void set_hidden_binding ()
  {
    set_flag_bit<DB_HIDDEN_BIT> ();
  }
  void clear_hidden_binding ()
  {
    clear_flag_bit<DB_HIDDEN_BIT> ();
  }

public:
  bool is_special () const
  {
    return get_flag_bit<DB_SPECIAL_BIT> ();
  }
  void set_special ()
  {
    set_flag_bit<DB_SPECIAL_BIT> ();
  }

public:
  tree get_entity () const
  {
    return entity;
  }
  tree get_name () const
  {
    gcc_checking_assert (is_binding ());
    return reinterpret_cast <tree> (discriminator);
  }

public:
  /* Traits for a hash table of pointers to bindings.  */
  struct traits {
    /* Each entry is a pointer to a depset. */
    typedef depset *value_type;
    /* We lookup by container:maybe-identifier pair.  */
    typedef std::pair<tree,tree> compare_type;

    static const bool empty_zero_p = true;

    /* hash and equality for compare_type.  */
    inline static hashval_t hash (const compare_type &p)
    {
      hashval_t h = pointer_hash<tree_node>::hash (p.first);
      if (p.second)
	{
	  hashval_t nh = IDENTIFIER_HASH_VALUE (p.second);
	  h = iterative_hash_hashval_t (h, nh);
	}
      return h;
    }
    inline static bool equal (const value_type b, const compare_type &p)
    {
      if (b->entity != p.first)
	return false;

      if (p.second)
	return b->discriminator == reinterpret_cast<uintptr_t> (p.second);
      else
	return !b->is_binding ();
    }

    /* (re)hasher for a binding itself.  */
    inline static hashval_t hash (const value_type b)
    {
      hashval_t h = pointer_hash<tree_node>::hash (b->entity);
      if (b->is_binding ())
	{
	  hashval_t nh = IDENTIFIER_HASH_VALUE (b->get_name ());
	  h = iterative_hash_hashval_t (h, nh);
	}
      return h;
    }

    /* Empty via NULL.  */
    static inline void mark_empty (value_type &p) {p = NULL;}
    static inline bool is_empty (value_type p) {return !p;}

    /* Nothing is deletable.  Everything is insertable.  */
    static bool is_deleted (value_type) { return false; }
    static void mark_deleted (value_type) { gcc_unreachable (); }

    /* We own the entities in the hash table.  */
    static void remove (value_type p)
    {
      delete (p);
    }
  };

public:
  class hash : public hash_table<traits> {
    typedef traits::compare_type key_t;
    typedef hash_table<traits> parent;

  public:
    vec<depset *> worklist;  /* Worklist of decls to walk.  */
    hash *chain;	     /* Original table.  */
    depset *current;         /* Current depset being depended.  */
    unsigned section;	     /* When writing out, the section.  */
    bool sneakoscope;        /* Detecting dark magic (of a voldemort).  */
    bool reached_unreached;  /* We reached an unreached entity.  */

  public:
    hash (size_t size, hash *c = NULL)
      : parent (size), chain (c), current (NULL), section (0),
	sneakoscope (false), reached_unreached (false)
    {
      worklist.create (size);
    }
    ~hash ()
    {
      worklist.release ();
    }

  public:
    bool is_key_order () const
    {
      return chain != NULL;
    }

  private:
    depset **entity_slot (tree entity, bool = true);
    depset **binding_slot (tree ctx, tree name, bool = true);
    depset *maybe_add_declaration (tree decl);

  public:
    depset *find_dependency (tree entity);
    depset *find_binding (tree ctx, tree name);
    depset *make_dependency (tree decl, entity_kind);
    void add_dependency (depset *);

  public:
    void add_mergeable (depset *);
    depset *add_dependency (tree decl, entity_kind);
    void add_namespace_context (depset *, tree ns);

  private:
    static bool add_binding_entity (tree, WMB_Flags, void *);

  public:
    bool add_namespace_entities (tree ns, bitmap partitions);
    void add_specializations (bool decl_p);
    void add_partial_entities (vec<tree, va_gc> *);
    void add_class_entities (vec<tree, va_gc> *);

  public:    
    void find_dependencies (module_state *);
    bool finalize_dependencies ();
    vec<depset *> connect ();
  };

public:
  struct tarjan {
    vec<depset *> result;
    vec<depset *> stack;
    unsigned index;

    tarjan (unsigned size)
      : index (0)
    {
      result.create (size);
      stack.create (50);
    }
    ~tarjan () 
    {
      gcc_assert (!stack.length ());
      stack.release ();
    }

  public:
    void connect (depset *);
  };
};

inline
depset::depset (tree entity)
  :entity (entity), discriminator (0), cluster (0), section (0)
{
  deps.create (0);
}

inline
depset::~depset ()
{
  deps.release ();
}

const char *
depset::entity_kind_name () const
{
  /* Same order as entity_kind.  */
  static const char *const names[] = 
    {"decl", "specialization", "partial", "using",
     "namespace", "redirect", "binding"};
  entity_kind kind = get_entity_kind ();
  gcc_checking_assert (kind < sizeof (names) / sizeof(names[0]));
  return names[kind];
}

/* Create a depset for a namespace binding NS::NAME.  */

depset *depset::make_binding (tree ns, tree name)
{
  depset *binding = new depset (ns);

  binding->discriminator = reinterpret_cast <uintptr_t> (name);

  return binding;
}

depset *depset::make_entity (tree entity, entity_kind ek, bool is_defn)
{
  depset *r = new depset (entity);

  r->discriminator = ((1 << DB_ZERO_BIT)
		      | (ek << DB_KIND_BIT)
		      | is_defn << DB_DEFN_BIT);

  return r;
}

class pending_key
{
public:
  tree ns;
  tree id;
};

template<>
struct default_hash_traits<pending_key>
{
  using value_type = pending_key;

  static const bool empty_zero_p = false;
  static hashval_t hash (const value_type &k)
  {
    hashval_t h = IDENTIFIER_HASH_VALUE (k.id);
    h = iterative_hash_hashval_t (DECL_UID (k.ns), h);

    return h;
  }
  static bool equal (const value_type &k, const value_type &l)
  {
    return k.ns == l.ns && k.id == l.id;
  }
  static void mark_empty (value_type &k)
  {
    k.ns = k.id = NULL_TREE;
  }
  static void mark_deleted (value_type &k)
  {
    k.ns = NULL_TREE;
    gcc_checking_assert (k.id);
  }
  static bool is_empty (const value_type &k)
  {
    return k.ns == NULL_TREE && k.id == NULL_TREE;
  }
  static bool is_deleted (const value_type &k)
  {
    return k.ns == NULL_TREE && k.id != NULL_TREE;
  }
  static void remove (value_type &)
  {
  }
};

typedef hash_map<pending_key, auto_vec<unsigned>> pending_map_t;

/* Not-loaded entities that are keyed to a namespace-scope
   identifier.  See module_state::write_pendings for details.  */
pending_map_t *pending_table;

/* Decls that need some post processing once a batch of lazy loads has
   completed.  */
vec<tree, va_heap, vl_embed> *post_load_decls;

/* Some entities are attached to another entitity for ODR purposes.
   For example, at namespace scope, 'inline auto var = []{};', that
   lambda is attached to 'var', and follows its ODRness.  */
typedef hash_map<tree, auto_vec<tree>> attached_map_t;
static attached_map_t *attached_table;

/********************************************************************/
/* Tree streaming.   The tree streaming is very specific to the tree
   structures themselves.  A tag indicates the kind of tree being
   streamed.  -ve tags indicate backreferences to already-streamed
   trees.  Backreferences are auto-numbered.  */

/* Tree tags.  */
enum tree_tag {
  tt_null,		/* NULL_TREE.  */
  tt_fixed,		/* Fixed vector index.  */

  tt_node,		/* By-value node.  */
  tt_decl,		/* By-value mergeable decl.  */
  tt_tpl_parm,		/* Template parm.  */

  /* The ordering of the following 4 is relied upon in
     trees_out::tree_node.  */
  tt_id,  		/* Identifier node.  */
  tt_conv_id,		/* Conversion operator name.  */
  tt_anon_id,		/* Anonymous name.  */
  tt_lambda_id,		/* Lambda name.  */

  tt_typedef_type,	/* A (possibly implicit) typedefed type.  */
  tt_derived_type,	/* A type derived from another type.  */
  tt_variant_type,	/* A variant of another type.  */

  tt_tinfo_var,		/* Typeinfo object. */
  tt_tinfo_typedef,	/* Typeinfo typedef.  */
  tt_ptrmem_type,	/* Pointer to member type.  */

  tt_parm,		/* Function parameter or result.  */
  tt_enum_value,	/* An enum value.  */
  tt_enum_decl,		/* An enum decl.  */
  tt_data_member,	/* Data member/using-decl.  */

  tt_binfo,		/* A BINFO.  */
  tt_vtable,		/* A vtable.  */
  tt_thunk,		/* A thunk.  */
  tt_clone_ref,

  tt_entity,		/* A extra-cluster entity.  */

  tt_template,		/* The TEMPLATE_RESULT of a template.  */
};

enum walk_kind {
  WK_none,	/* No walk to do (a back- or fixed-ref happened).  */
  WK_normal,	/* Normal walk (by-name if possible).  */

  WK_value,	/* By-value walk.  */
};

enum merge_kind
{
  MK_unique,	/* Known unique.  */
  MK_named,	/* Found by CTX, NAME + maybe_arg types etc.  */
  MK_field,	/* Found by CTX and index on TYPE_FIELDS  */
  MK_vtable,	/* Found by CTX and index on TYPE_VTABLES  */
  MK_as_base,	/* Found by CTX.  */

  MK_partial,

  MK_enum,	/* Found by CTX, & 1stMemberNAME.  */
  MK_attached,  /* Found by attachee & index.  */

  MK_friend_spec,  /* Like named, but has a tmpl & args too.  */
  MK_local_friend, /* Found by CTX, index.  */

  MK_indirect_lwm = MK_enum,
  
  /* Template specialization kinds below. These are all found via
     primary template and specialization args.  */
  MK_template_mask = 0x10,  /* A template specialization.  */

  MK_tmpl_decl_mask = 0x4, /* In decl table.  */
  MK_tmpl_alias_mask = 0x2, /* Also in type table  */

  MK_tmpl_tmpl_mask = 0x1, /* We want TEMPLATE_DECL.  */

  MK_type_spec = MK_template_mask,
  MK_decl_spec = MK_template_mask | MK_tmpl_decl_mask,
  MK_alias_spec = MK_decl_spec | MK_tmpl_alias_mask,

  MK_hwm = 0x20
};
/* This is more than a debugging array.  NULLs are used to determine
   an invalid merge_kind number.  */
static char const *const merge_kind_name[MK_hwm] =
  {
    "unique", "named", "field", "vtable",	/* 0...3  */
    "asbase", "partial", "enum", "attached",	/* 4...7  */

    "friend spec", "local friend", NULL, NULL,  /* 8...11 */
    NULL, NULL, NULL, NULL,

    "type spec", "type tmpl spec",	/* 16,17 type (template).  */
    NULL, NULL,

    "decl spec", "decl tmpl spec",	/* 20,21 decl (template).  */
    "alias spec", "alias tmpl spec",	/* 22,23 alias (template). */
    NULL, NULL, NULL, NULL,
    NULL, NULL, NULL, NULL,
  };

/* Mergeable entity location data.  */
struct merge_key {
  cp_ref_qualifier ref_q : 2;
  unsigned index;

  tree ret;  /* Return type, if appropriate.  */
  tree args; /* Arg types, if appropriate.  */

  tree constraints;  /* Constraints.  */

  merge_key ()
    :ref_q (REF_QUAL_NONE), index (0),
     ret (NULL_TREE), args (NULL_TREE),
     constraints (NULL_TREE)
  {
  }
};

struct duplicate_hash : nodel_ptr_hash<tree_node>
{
  inline static hashval_t hash (value_type decl)
  {
    if (TREE_CODE (decl) == TREE_BINFO)
      decl = TYPE_NAME (BINFO_TYPE (decl));
    return hashval_t (DECL_UID (decl));
  }
};

/* Hashmap of merged duplicates.  Usually decls, but can contain
   BINFOs.  */
typedef hash_map<tree,uintptr_t,
		 simple_hashmap_traits<duplicate_hash,uintptr_t> >
duplicate_hash_map;

/* Tree stream reader.  Note that reading a stream doesn't mark the
   read trees with TREE_VISITED.  Thus it's quite safe to have
   multiple concurrent readers.  Which is good, because lazy
   loading. */
class trees_in : public bytes_in {
  typedef bytes_in parent;

private:
  module_state *state;		/* Module being imported.  */
  vec<tree> back_refs;		/* Back references.  */
  duplicate_hash_map *duplicates;	/* Map from existings to duplicate.  */
  vec<tree> post_decls;		/* Decls to post process.  */
  unsigned unused;		/* Inhibit any interior TREE_USED
				   marking.  */

public:
  trees_in (module_state *);
  ~trees_in ();

public:
  int insert (tree);
  tree back_ref (int);

private:
  tree start (unsigned = 0);

public:
  /* Needed for binfo writing  */
  bool core_bools (tree);

private:
  /* Stream tree_core, lang_decl_specific and lang_type_specific
     bits.  */
  bool core_vals (tree);
  bool lang_type_bools (tree);
  bool lang_type_vals (tree);
  bool lang_decl_bools (tree);
  bool lang_decl_vals (tree);
  bool lang_vals (tree);
  bool tree_node_bools (tree);
  bool tree_node_vals (tree);
  tree tree_value ();
  tree decl_value ();
  tree tpl_parm_value ();

private:
  tree chained_decls ();  /* Follow DECL_CHAIN.  */
  vec<tree, va_heap> *vec_chained_decls ();
  vec<tree, va_gc> *tree_vec (); /* vec of tree.  */
  vec<tree_pair_s, va_gc> *tree_pair_vec (); /* vec of tree_pair.  */
  tree tree_list (bool has_purpose);

public:
  /* Read a tree node.  */
  tree tree_node (bool is_use = false);

private:
  bool install_entity (tree decl);
  tree tpl_parms (unsigned &tpl_levels);
  bool tpl_parms_fini (tree decl, unsigned tpl_levels);
  bool tpl_header (tree decl, unsigned *tpl_levels);
  int fn_parms_init (tree);
  void fn_parms_fini (int tag, tree fn, tree existing, bool has_defn);
  unsigned add_indirect_tpl_parms (tree);
public:
  bool add_indirects (tree);

public:
  /* Serialize various definitions. */
  bool read_definition (tree decl);
  
private:
  bool is_matching_decl (tree existing, tree decl, bool is_typedef);
  static bool install_implicit_member (tree decl);
  bool read_function_def (tree decl, tree maybe_template);
  bool read_var_def (tree decl, tree maybe_template);
  bool read_class_def (tree decl, tree maybe_template);
  bool read_enum_def (tree decl, tree maybe_template);

public:
  tree decl_container ();
  tree key_mergeable (int tag, merge_kind, tree decl, tree inner, tree type,
		      tree container, bool is_mod);
  unsigned binfo_mergeable (tree *);

private:
  uintptr_t *find_duplicate (tree existing);
  void register_duplicate (tree decl, tree existing);
  /* Mark as an already diagnosed bad duplicate.  */
  void unmatched_duplicate (tree existing)
  {
    *find_duplicate (existing) |= 1;
  }

public:
  bool is_duplicate (tree decl)
  {
    return find_duplicate (decl) != NULL;
  }
  tree maybe_duplicate (tree decl)
  {
    if (uintptr_t *dup = find_duplicate (decl))
      return reinterpret_cast<tree> (*dup & ~uintptr_t (1));
    return decl;
  }
  tree odr_duplicate (tree decl, bool has_defn);

public:
  /* Return the next decl to postprocess, or NULL.  */
  tree post_process ()
  {
    return post_decls.length () ? post_decls.pop () : NULL_TREE;
  }
private:
  /* Register DECL for postprocessing.  */
  void post_process (tree decl)
  {
    post_decls.safe_push (decl);
  }

private:
  void assert_definition (tree, bool installing);
};

trees_in::trees_in (module_state *state)
  :parent (), state (state), unused (0)
{
  duplicates = NULL;
  back_refs.create (500);
  post_decls.create (0);
}

trees_in::~trees_in ()
{
  delete (duplicates);
  back_refs.release ();
  post_decls.release ();
}

/* Tree stream writer.  */
class trees_out : public bytes_out {
  typedef bytes_out parent;

private:
  module_state *state;		/* The module we are writing.  */
  ptr_int_hash_map tree_map; 	/* Trees to references */
  depset::hash *dep_hash;    	/* Dependency table.  */
  int ref_num;			/* Back reference number.  */
  unsigned section;
#if CHECKING_P
  int importedness;		/* Checker that imports not occurring
				   inappropriately.  +ve imports ok,
				   -ve imports not ok.  */
#endif

public:
  trees_out (allocator *, module_state *, depset::hash &deps, unsigned sec = 0);
  ~trees_out ();

private:
  void mark_trees ();
  void unmark_trees ();

public:
  /* Hey, let's ignore the well known STL iterator idiom.  */
  void begin ();
  unsigned end (elf_out *sink, unsigned name, unsigned *crc_ptr);
  void end ();

public:
  enum tags 
  {
    tag_backref = -1,	/* Upper bound on the backrefs.  */
    tag_value = 0,	/* Write by value.  */
    tag_fixed		/* Lower bound on the fixed trees.  */
  };

public:
  bool is_key_order () const
  {
    return dep_hash->is_key_order ();
  }

public:
  int insert (tree, walk_kind = WK_normal);

private:
  void start (tree, bool = false);

private:
  walk_kind ref_node (tree);
public:
  int get_tag (tree);
  void set_importing (int i ATTRIBUTE_UNUSED)
  {
#if CHECKING_P
    importedness = i;
#endif
  }

private:
  void core_bools (tree);
  void core_vals (tree);
  void lang_type_bools (tree);
  void lang_type_vals (tree);
  void lang_decl_bools (tree);
  void lang_decl_vals (tree);
  void lang_vals (tree);
  void tree_node_bools (tree);
  void tree_node_vals (tree);

private:
  void chained_decls (tree);
  void vec_chained_decls (tree);
  void tree_vec (vec<tree, va_gc> *);
  void tree_pair_vec (vec<tree_pair_s, va_gc> *);
  void tree_list (tree, bool has_purpose);

public:
  /* Mark a node for by-value walking.  */
  void mark_by_value (tree);

public:
  void tree_node (tree);

private:
  void install_entity (tree decl, depset *);
  void tpl_parms (tree parms, unsigned &tpl_levels);
  void tpl_parms_fini (tree decl, unsigned tpl_levels);
  void fn_parms_fini (tree) {}
  unsigned add_indirect_tpl_parms (tree);
public:
  void add_indirects (tree);
  void fn_parms_init (tree);
  void tpl_header (tree decl, unsigned *tpl_levels);

public:
  merge_kind get_merge_kind (tree decl, depset *maybe_dep);
  tree decl_container (tree decl);
  void key_mergeable (int tag, merge_kind, tree decl, tree inner,
		      tree container, depset *maybe_dep);
  void binfo_mergeable (tree binfo);

private:
  bool decl_node (tree, walk_kind ref);
  void type_node (tree);
  void tree_value (tree);
  void tpl_parm_value (tree);

public:
  void decl_value (tree, depset *);

public:
  /* Serialize various definitions. */
  void write_definition (tree decl);
  void mark_declaration (tree decl, bool do_defn);

private:
  void mark_function_def (tree decl);
  void mark_var_def (tree decl);
  void mark_class_def (tree decl);
  void mark_enum_def (tree decl);
  void mark_class_member (tree decl, bool do_defn = true);
  void mark_binfos (tree type);

private:
  void write_var_def (tree decl);
  void write_function_def (tree decl);
  void write_class_def (tree decl);
  void write_enum_def (tree decl);

private:
  static void assert_definition (tree);

public:
  static void instrument ();

private:
  /* Tree instrumentation. */
  static unsigned tree_val_count;
  static unsigned decl_val_count;
  static unsigned back_ref_count;
  static unsigned null_count;
};

/* Instrumentation counters.  */
unsigned trees_out::tree_val_count;
unsigned trees_out::decl_val_count;
unsigned trees_out::back_ref_count;
unsigned trees_out::null_count;

trees_out::trees_out (allocator *mem, module_state *state, depset::hash &deps,
		      unsigned section)
  :parent (mem), state (state), tree_map (500),
   dep_hash (&deps), ref_num (0), section (section)
{
#if CHECKING_P
  importedness = 0;
#endif
}

trees_out::~trees_out ()
{
}

/********************************************************************/
/* Location.  We're aware of the line-map concept and reproduce it
   here.  Each imported module allocates a contiguous span of ordinary
   maps, and of macro maps.  adhoc maps are serialized by contents,
   not pre-allocated.   The scattered linemaps of a module are
   coalesced when writing.  */


/* I use half-open [first,second) ranges.  */
typedef std::pair<unsigned,unsigned> range_t;

/* A range of locations.  */
typedef std::pair<location_t,location_t> loc_range_t;

/* Spans of the line maps that are occupied by this TU.  I.e. not
   within imports.  Only extended when in an interface unit.
   Interval zero corresponds to the forced header linemap(s).  This
   is a singleton object.  */

class loc_spans {
public:
  /* An interval of line maps.  The line maps here represent a contiguous
     non-imported range.  */
  struct span {
    loc_range_t ordinary;	/* Ordinary map location range. */
    loc_range_t macro;		/* Macro map location range.  */
    int ordinary_delta;	/* Add to ordinary loc to get serialized loc.  */
    int macro_delta;	/* Likewise for macro loc.  */
  };

private:
  vec<span> *spans;

public:
  loc_spans ()
    /* Do not preallocate spans, as that causes
       --enable-detailed-mem-stats problems.  */
    : spans (nullptr)
  {
  }
  ~loc_spans ()
  {
    delete spans;
  }

public:
  span &operator[] (unsigned ix)
  {
    return (*spans)[ix];
  }
  unsigned length () const
  {
    return spans->length ();
  }

public:
  bool init_p () const
  {
    return spans != nullptr;
  }
  /* Initializer.  */
  void init (const line_maps *lmaps, const line_map_ordinary *map);

  /* Slightly skewed preprocessed files can cause us to miss an
     initialization in some places.  Fallback initializer.  */
  void maybe_init ()
  {
    if (!init_p ())
      init (line_table, nullptr);
  }

public:
  enum {
    SPAN_RESERVED = 0,	/* Reserved (fixed) locations.  */
    SPAN_FIRST = 1,	/* LWM of locations to stream  */
    SPAN_MAIN = 2	/* Main file and onwards.  */
  };

public:
  location_t main_start () const
  {
    return (*spans)[SPAN_MAIN].ordinary.first;
  }

public:
  void open (location_t);
  void close ();

public:
  /* Propagate imported linemaps to us, if needed.  */
  bool maybe_propagate (module_state *import, location_t loc);

public:
  const span *ordinary (location_t);
  const span *macro (location_t);
};

static loc_spans spans;
/* Indirection to allow bsearching imports by ordinary location.  */
static vec<module_state *> *ool;

/********************************************************************/
/* Data needed by a module during the process of loading.  */
struct GTY(()) slurping {

  /* Remap import's module numbering to our numbering.  Values are
     shifted by 1.  Bit0 encodes if the import is direct.  */
  vec<unsigned, va_heap, vl_embed> *
    GTY((skip)) remap;			/* Module owner remapping.  */

  elf_in *GTY((skip)) from;     	/* The elf loader.  */

  /* This map is only for header imports themselves -- the global
     headers bitmap hold it for the current TU.  */
  bitmap headers;	/* Transitive set of direct imports, including
			   self.  Used for macro visibility and
			   priority.  */

  /* These objects point into the mmapped area, unless we're not doing
     that, or we got frozen or closed.  In those cases they point to
     buffers we own.  */
  bytes_in macro_defs;	/* Macro definitions.  */
  bytes_in macro_tbl;	/* Macro table.  */

  /* Location remapping.  first->ordinary, second->macro.  */
  range_t GTY((skip)) loc_deltas;

  unsigned current;	/* Section currently being loaded.  */
  unsigned remaining;	/* Number of lazy sections yet to read.  */
  unsigned lru;		/* An LRU counter.  */

 public:
  slurping (elf_in *);
  ~slurping ();

 public:
  /* Close the ELF file, if it's open.  */
  void close ()
  {
    if (from)
      {
	from->end ();
	delete from;
	from = NULL;
      }
  }

 public:
  void release_macros ();

 public:
  void alloc_remap (unsigned size)
  {
    gcc_assert (!remap);
    vec_safe_reserve (remap, size);
    for (unsigned ix = size; ix--;)
      remap->quick_push (0);
  }
  unsigned remap_module (unsigned owner)
  {
    if (owner < remap->length ())
      return (*remap)[owner] >> 1;
    return 0;
  }

 public:
  /* GC allocation.  But we must explicitly delete it.   */
  static void *operator new (size_t x)
  {
    return ggc_alloc_atomic (x);
  }
  static void operator delete (void *p)
  {
    ggc_free (p);
  }
};

slurping::slurping (elf_in *from)
  : remap (NULL), from (from),
    headers (BITMAP_GGC_ALLOC ()), macro_defs (), macro_tbl (),
    loc_deltas (0, 0),
    current (~0u), remaining (0), lru (0)
{
}

slurping::~slurping ()
{
  vec_free (remap);
  remap = NULL;
  release_macros ();
  close ();
}

void slurping::release_macros ()
{
  if (macro_defs.size)
    elf_in::release (from, macro_defs);
  if (macro_tbl.size)
    elf_in::release (from, macro_tbl);
}

/* Information about location maps used during writing.  */

struct location_map_info {
  range_t num_maps;

  unsigned max_range;
};

/* Flage for extensions that end up being streamed.  */

enum streamed_extensions {
  SE_OPENMP = 1 << 0,
  SE_BITS = 1
};

/********************************************************************/
struct module_state_config;

/* Increasing levels of loadedness.  */
enum module_loadedness {
  ML_NONE,		/* Not loaded.  */
  ML_CONFIG,		/* Config loaed.  */
  ML_PREPROCESSOR,	/* Preprocessor loaded.  */
  ML_LANGUAGE,		/* Language loaded.  */
};

/* Increasing levels of directness (toplevel) of import.  */
enum module_directness {
  MD_NONE,  		/* Not direct.  */
  MD_PARTITION_DIRECT,	/* Direct import of a partition.  */
  MD_DIRECT,		/* Direct import.  */
  MD_PURVIEW_DIRECT,	/* direct import in purview.  */
};

/* State of a particular module. */

class GTY((chain_next ("%h.parent"), for_user)) module_state {
 public:
  /* We always import & export ourselves.  */
  bitmap imports;	/* Transitive modules we're importing.  */
  bitmap exports;	/* Subset of that, that we're exporting.  */

  module_state *parent;
  tree name;		/* Name of the module.  */

  slurping *slurp;	/* Data for loading.  */

  const char *flatname;	/* Flatname of module.  */
  char *filename;	/* CMI Filename */

  /* Indices into the entity_ary.  */
  unsigned entity_lwm;
  unsigned entity_num;

  /* Location ranges for this module.  adhoc-locs are decomposed, so
     don't have a range.  */
  loc_range_t GTY((skip)) ordinary_locs;
  loc_range_t GTY((skip)) macro_locs;

  /* LOC is first set too the importing location.  When initially
     loaded it refers to a module loc whose parent is the importing
     location.  */
  location_t loc; 	/* Location referring to module itself.  */
  unsigned crc;		/* CRC we saw reading it in. */

  unsigned mod;		/* Module owner number.  */
  unsigned remap;	/* Remapping during writing.  */

  unsigned short subst;	/* Mangle subst if !0.  */

  /* How loaded this module is.  */
  enum module_loadedness loadedness : 2;

  bool module_p : 1;    /* /The/ module of this TU.  */
  bool header_p : 1;	/* Is a header unit.  */
  bool interface_p : 1; /* An interface.  */
  bool partition_p : 1; /* A partition.  */

  /* How directly this module is imported.  */
  enum module_directness directness : 2;

  bool exported_p : 1;	/* directness != MD_NONE && exported.  */
  bool cmi_noted_p : 1; /* We've told the user about the CMI, don't
			   do it again  */
  bool call_init_p : 1; /* This module's global initializer needs
			   calling.  */
  bool inform_cmi_p : 1; /* Inform of a read/write.  */
  bool visited_p : 1;    /* A walk-once flag. */
  /* Record extensions emitted or permitted.  */
  unsigned extensions : SE_BITS;
  /* 14 bits used, 2 bits remain  */

 public:
  module_state (tree name, module_state *, bool);
  ~module_state ();

 public:
  void release ()
  {
    imports = exports = NULL;
    slurped ();
  }
  void slurped ()
  {
    delete slurp;
    slurp = NULL;
  }
  elf_in *from () const
  {
    return slurp->from;
  }

 public:
  /* Kind of this module.  */
  bool is_module () const
  {
    return module_p;
  }
  bool is_header () const
  {
    return header_p;
  }
  bool is_interface () const
  {
    return interface_p;
  }
  bool is_partition () const
  {
    return partition_p;
  }

  /* How this module is used in the current TU.  */
  bool is_exported () const
  {
    return exported_p;
  }
  bool is_direct () const
  {
    return directness >= MD_DIRECT;
  }
  bool is_purview_direct () const
  {
    return directness == MD_PURVIEW_DIRECT;
  }
  bool is_partition_direct () const
  {
    return directness == MD_PARTITION_DIRECT;
  }

 public:
  /* Is this a real module?  */
  bool has_location () const
  {
    return loc != UNKNOWN_LOCATION;
  }

 public:
  bool check_not_purview (location_t loc);

 public:
  void mangle (bool include_partition);

 public:
  void set_import (module_state const *, bool is_export);
  void announce (const char *) const;

 public:
  /* Read and write module.  */
  void write (elf_out *to, cpp_reader *);
  bool read_initial (cpp_reader *);
  bool read_preprocessor (bool);
  bool read_language (bool);

 public:
  /* Read a section.  */
  bool load_section (unsigned snum, binding_slot *mslot);
  /* Lazily read a section.  */
  bool lazy_load (unsigned index, binding_slot *mslot);

 public:
  /* Juggle a limited number of file numbers.  */
  static void freeze_an_elf ();
  bool maybe_defrost ();

 public:
  void maybe_completed_reading ();
  bool check_read (bool outermost, bool ok);

 private:
  /* The README, for human consumption.  */
  void write_readme (elf_out *to, cpp_reader *,
		     const char *dialect, unsigned extensions);
  void write_env (elf_out *to);

 private:
  /* Import tables. */
  void write_imports (bytes_out &cfg, bool direct);
  unsigned read_imports (bytes_in &cfg, cpp_reader *, line_maps *maps);

 private:
  void write_imports (elf_out *to, unsigned *crc_ptr);
  bool read_imports (cpp_reader *, line_maps *);

 private:
  void write_partitions (elf_out *to, unsigned, unsigned *crc_ptr);
  bool read_partitions (unsigned);

 private:
  void write_config (elf_out *to, struct module_state_config &, unsigned crc);
  bool read_config (struct module_state_config &);
  static void write_counts (elf_out *to, unsigned [], unsigned *crc_ptr);
  bool read_counts (unsigned []);

 public:
  void note_cmi_name ();

 private:
  static unsigned write_bindings (elf_out *to, vec<depset *> depsets,
				  unsigned *crc_ptr);
  bool read_bindings (unsigned count, unsigned lwm, unsigned hwm);

  static void write_namespace (bytes_out &sec, depset *ns_dep);
  tree read_namespace (bytes_in &sec);

  void write_namespaces (elf_out *to, vec<depset *> spaces,
			 unsigned, unsigned *crc_ptr);
  bool read_namespaces (unsigned);

  void intercluster_seed (trees_out &sec, unsigned index, depset *dep);
  unsigned write_cluster (elf_out *to, depset *depsets[], unsigned size,
			  depset::hash &, unsigned *counts, unsigned *crc_ptr);
  bool read_cluster (unsigned snum);

 private:
  unsigned write_inits (elf_out *to, depset::hash &, unsigned *crc_ptr);
  bool read_inits (unsigned count);

 private:
  unsigned write_pendings (elf_out *to, vec<depset *> depsets,
			   depset::hash &, unsigned *crc_ptr);
  bool read_pendings (unsigned count);

 private:
  void write_entities (elf_out *to, vec<depset *> depsets,
		       unsigned count, unsigned *crc_ptr);
  bool read_entities (unsigned count, unsigned lwm, unsigned hwm);

 private:
  location_map_info write_prepare_maps (module_state_config *);
  bool read_prepare_maps (const module_state_config *);

  void write_ordinary_maps (elf_out *to, location_map_info &,
			    module_state_config *, bool, unsigned *crc_ptr);
  bool read_ordinary_maps ();
  void write_macro_maps (elf_out *to, location_map_info &,
			 module_state_config *, unsigned *crc_ptr);
  bool read_macro_maps ();

 private:
  void write_define (bytes_out &, const cpp_macro *, bool located = true);
  cpp_macro *read_define (bytes_in &, cpp_reader *, bool located = true) const;
  unsigned write_macros (elf_out *to, cpp_reader *, unsigned *crc_ptr);
  bool read_macros ();
  void install_macros ();

 public:
  void import_macros ();

 public:
  static void undef_macro (cpp_reader *, location_t, cpp_hashnode *);
  static cpp_macro *deferred_macro (cpp_reader *, location_t, cpp_hashnode *);

 public:
  static void write_location (bytes_out &, location_t);
  location_t read_location (bytes_in &) const;

 public:
  void set_flatname ();
  const char *get_flatname () const
  {
    return flatname;
  }
  location_t imported_from () const;

 public:
  void set_filename (const Cody::Packet &);
  bool do_import (cpp_reader *, bool outermost);
};

/* Hash module state by name.  This cannot be a member of
   module_state, because of GTY restrictions.  We never delete from
   the hash table, but ggc_ptr_hash doesn't support that
   simplification.  */

struct module_state_hash : ggc_ptr_hash<module_state> {
  typedef std::pair<tree,uintptr_t> compare_type; /* {name,parent} */

  static inline hashval_t hash (const value_type m);
  static inline hashval_t hash (const compare_type &n);
  static inline bool equal (const value_type existing,
			    const compare_type &candidate);
};

module_state::module_state (tree name, module_state *parent, bool partition)
  : imports (BITMAP_GGC_ALLOC ()), exports (BITMAP_GGC_ALLOC ()),
    parent (parent), name (name), slurp (NULL),
    flatname (NULL), filename (NULL),
    entity_lwm (~0u >> 1), entity_num (0),
    ordinary_locs (0, 0), macro_locs (0, 0),
    loc (UNKNOWN_LOCATION),
    crc (0), mod (MODULE_UNKNOWN), remap (0), subst (0)
{
  loadedness = ML_NONE;

  module_p = header_p = interface_p = partition_p = false;

  directness = MD_NONE;
  exported_p = false;

  cmi_noted_p = false;
  call_init_p = false;

  partition_p = partition;

  inform_cmi_p = false;
  visited_p = false;

  extensions = 0;
  if (name && TREE_CODE (name) == STRING_CST)
    {
      header_p = true;

      const char *string = TREE_STRING_POINTER (name);
      gcc_checking_assert (string[0] == '.'
			   ? IS_DIR_SEPARATOR (string[1])
			   : IS_ABSOLUTE_PATH (string));
    }

  gcc_checking_assert (!(parent && header_p));
}

module_state::~module_state ()
{
  release ();
}

/* Hash module state.  */
static hashval_t
module_name_hash (const_tree name)
{
  if (TREE_CODE (name) == STRING_CST)
    return htab_hash_string (TREE_STRING_POINTER (name));
  else
    return IDENTIFIER_HASH_VALUE (name);
}

hashval_t
module_state_hash::hash (const value_type m)
{
  hashval_t ph = pointer_hash<void>::hash
    (reinterpret_cast<void *> (reinterpret_cast<uintptr_t> (m->parent)
			       | m->is_partition ()));
  hashval_t nh = module_name_hash (m->name);
  return iterative_hash_hashval_t (ph, nh);
}

/* Hash a name.  */
hashval_t
module_state_hash::hash (const compare_type &c)
{
  hashval_t ph = pointer_hash<void>::hash (reinterpret_cast<void *> (c.second));
  hashval_t nh = module_name_hash (c.first);

  return iterative_hash_hashval_t (ph, nh);
}

bool
module_state_hash::equal (const value_type existing,
			  const compare_type &candidate)
{
  uintptr_t ep = (reinterpret_cast<uintptr_t> (existing->parent)
		  | existing->is_partition ());
  if (ep != candidate.second)
    return false;

  /* Identifier comparison is by pointer.  If the string_csts happen
     to be the same object, then they're equal too.  */
  if (existing->name == candidate.first)
    return true;

  /* If neither are string csts, they can't be equal.  */
  if (TREE_CODE (candidate.first) != STRING_CST
      || TREE_CODE (existing->name) != STRING_CST)
    return false;

  /* String equality.  */
  if (TREE_STRING_LENGTH (existing->name)
      == TREE_STRING_LENGTH (candidate.first)
      && !memcmp (TREE_STRING_POINTER (existing->name),
		  TREE_STRING_POINTER (candidate.first),
		  TREE_STRING_LENGTH (existing->name)))
    return true;

  return false;
}

/********************************************************************/
/* Global state */

/* Mapper name.  */
static const char *module_mapper_name;

/* Deferred import queue (FIFO).  */
static vec<module_state *, va_heap, vl_embed> *pending_imports;

/* CMI repository path and workspace.  */
static char *cmi_repo;
static size_t cmi_repo_length;
static char *cmi_path;
static size_t cmi_path_alloc;

/* Count of available and loaded clusters.  */
static unsigned available_clusters;
static unsigned loaded_clusters;

/* What the current TU is.  */
unsigned module_kind;

/* Number of global init calls needed.  */
unsigned num_init_calls_needed = 0;

/* Global trees.  */
static const std::pair<tree *, unsigned> global_tree_arys[] =
  {
    std::pair<tree *, unsigned> (sizetype_tab, stk_type_kind_last),
    std::pair<tree *, unsigned> (integer_types, itk_none),
    std::pair<tree *, unsigned> (global_trees, TI_MODULE_HWM),
    std::pair<tree *, unsigned> (c_global_trees, CTI_MODULE_HWM),
    std::pair<tree *, unsigned> (cp_global_trees, CPTI_MODULE_HWM),
    std::pair<tree *, unsigned> (NULL, 0)
  };
static GTY(()) vec<tree, va_gc> *fixed_trees;
static unsigned global_crc;

/* Lazy loading can open many files concurrently, there are
   per-process limits on that.  We pay attention to the process limit,
   and attempt to increase it when we run out.  Otherwise we use an
   LRU scheme to figure out who to flush.  Note that if the import
   graph /depth/ exceeds lazy_limit, we'll exceed the limit.  */
static unsigned lazy_lru;  /* LRU counter.  */
static unsigned lazy_open; /* Number of open modules */
static unsigned lazy_limit; /* Current limit of open modules.  */
static unsigned lazy_hard_limit; /* Hard limit on open modules.  */
/* Account for source, assembler and dump files & directory searches.
   We don't keep the source file's open, so we don't have to account
   for #include depth.  I think dump files are opened and closed per
   pass, but ICBW.  */
#define LAZY_HEADROOM 15 /* File descriptor headroom.  */

/* Vector of module state.  Indexed by OWNER.  Has at least 2 slots.  */
static GTY(()) vec<module_state *, va_gc> *modules;

/* Hash of module state, findable by {name, parent}. */
static GTY(()) hash_table<module_state_hash> *modules_hash;

/* Map of imported entities.  We map DECL_UID to index of entity
   vector.  */
typedef hash_map<unsigned/*UID*/, unsigned/*index*/,
		 simple_hashmap_traits<int_hash<unsigned,0>, unsigned>
		 > entity_map_t;
static entity_map_t *entity_map;
/* Doesn't need GTYing, because any tree referenced here is also
   findable by, symbol table, specialization table, return type of
   reachable function.  */
static vec<binding_slot, va_heap, vl_embed> *entity_ary;

/* Members entities of imported classes that are defined in this TU.
   These are where the entity's context is not from the current TU.
   We need to emit the definition (but not the enclosing class).

   We could find these by walking ALL the imported classes that we
   could provide a member definition.  But that's expensive,
   especially when you consider lazy implicit member declarations,
   which could be ANY imported class.  */
static GTY(()) vec<tree, va_gc> *class_members;

/* The same problem exists for class template partial
   specializations.  Now that we have constraints, the invariant of
   expecting them in the instantiation table no longer holds.  One of
   the constrained partial specializations will be there, but the
   others not so much.  It's not even an unconstrained partial
   spacialization in the table :(  so any partial template declaration
   is added to this list too.  */
static GTY(()) vec<tree, va_gc> *partial_specializations;

/********************************************************************/

/* Our module mapper (created lazily).  */
module_client *mapper;

static module_client *make_mapper (location_t loc);
inline module_client *get_mapper (location_t loc)
{
  auto *res = mapper;
  if (!res)
    res = make_mapper (loc);
  return res;
}

/********************************************************************/
static tree
get_clone_target (tree decl)
{
  tree target;

  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      tree res_orig = DECL_CLONED_FUNCTION (DECL_TEMPLATE_RESULT (decl));
      
      target = DECL_TI_TEMPLATE (res_orig);
    }
  else
    target = DECL_CLONED_FUNCTION (decl);

  gcc_checking_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (target));

  return target;
}

/* Like FOR_EACH_CLONE, but will walk cloned templates.  */
#define FOR_EVERY_CLONE(CLONE, FN)			\
  if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (FN));		\
  else							\
    for (CLONE = DECL_CHAIN (FN);			\
	 CLONE && DECL_CLONED_FUNCTION_P (CLONE);	\
	 CLONE = DECL_CHAIN (CLONE))

/* It'd be nice if USE_TEMPLATE was a field of template_info
   (a) it'd solve the enum case dealt with below,
   (b) both class templates and decl templates would store this in the
   same place
   (c) this function wouldn't need the by-ref arg, which is annoying.  */

static tree
node_template_info (tree decl, int &use)
{
  tree ti = NULL_TREE;
  int use_tpl = -1;
  if (DECL_IMPLICIT_TYPEDEF_P (decl))
    {
      tree type = TREE_TYPE (decl);

      ti = TYPE_TEMPLATE_INFO (type);
      if (ti)
	{
	  if (TYPE_LANG_SPECIFIC (type))
	    use_tpl = CLASSTYPE_USE_TEMPLATE (type);
	  else
	    {
	      /* An enum, where we don't explicitly encode use_tpl.
		 If the containing context (a type or a function), is
		 an ({im,ex}plicit) instantiation, then this is too.
		 If it's a partial or explicit specialization, then
		 this is not!.  */
	      tree ctx = CP_DECL_CONTEXT (decl);
	      if (TYPE_P (ctx))
		ctx = TYPE_NAME (ctx);
	      node_template_info (ctx, use);
	      use_tpl = use != 2 ? use : 0;
	    }
	}
    }
  else if (DECL_LANG_SPECIFIC (decl)
	   && (TREE_CODE (decl) == VAR_DECL
	       || TREE_CODE (decl) == TYPE_DECL
	       || TREE_CODE (decl) == FUNCTION_DECL
	       || TREE_CODE (decl) == FIELD_DECL
	       || TREE_CODE (decl) == TEMPLATE_DECL))
    {
      use_tpl = DECL_USE_TEMPLATE (decl);
      ti = DECL_TEMPLATE_INFO (decl);
    }

  use = use_tpl;
  return ti;
}

/* Find the index in entity_ary for an imported DECL.  It should
   always be there, but bugs can cause it to be missing, and that can
   crash the crash reporting -- let's not do that!  When streaming
   out we place entities from this module there too -- with negated
   indices.  */

static unsigned
import_entity_index (tree decl, bool null_ok = false)
{
  if (unsigned *slot = entity_map->get (DECL_UID (decl)))
    return *slot;

  gcc_checking_assert (null_ok);
  return ~(~0u >> 1);
}

/* Find the module for an imported entity at INDEX in the entity ary.
   There must be one.  */

static module_state *
import_entity_module (unsigned index)
{
  if (index > ~(~0u >> 1))
    /* This is an index for an exported entity.  */
    return (*modules)[0];

  /* Do not include the current TU (not an off-by-one error).  */
  unsigned pos = 1;
  unsigned len = modules->length () - pos;
  while (len)
    {
      unsigned half = len / 2;
      module_state *probe = (*modules)[pos + half];
      if (index < probe->entity_lwm)
	len = half;
      else if (index < probe->entity_lwm + probe->entity_num)
	return probe;
      else
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
    }
  gcc_unreachable ();
}


/********************************************************************/
/* A dumping machinery.  */

class dumper {
public:
  enum {
    LOCATION = TDF_LINENO,  /* -lineno:Source location streaming.  */
    DEPEND = TDF_GRAPH,	/* -graph:Dependency graph construction.  */
    CLUSTER = TDF_BLOCKS,   /* -blocks:Clusters.  */
    TREE = TDF_UID, 	/* -uid:Tree streaming.  */
    MERGE = TDF_ALIAS,	/* -alias:Mergeable Entities.  */
    ELF = TDF_ASMNAME,	/* -asmname:Elf data.  */
    MACRO = TDF_VOPS	/* -vops:Macros.  */
  };

private:
  struct impl {
    typedef vec<module_state *, va_heap, vl_embed> stack_t;

    FILE *stream;	/* Dump stream.  */
    unsigned indent; 	/* Local indentation.  */
    bool bol; 		/* Beginning of line.  */
    stack_t stack;	/* Trailing array of module_state.  */

    bool nested_name (tree);  /* Dump a name following DECL_CONTEXT.  */
  };

public:
  /* The dumper.  */
  impl *dumps;
  dump_flags_t flags;

public:
  /* Push/pop module state dumping.  */
  unsigned push (module_state *);
  void pop (unsigned);

public:
  /* Change local indentation.  */
  void indent ()
  {
    if (dumps)
      dumps->indent++;
  }
  void outdent ()
  {
    if (dumps)
      {
	gcc_checking_assert (dumps->indent);
	dumps->indent--;
      }
  }

public:
  /* Is dump enabled?.  */
  bool operator () (int mask = 0)
  {
    if (!dumps || !dumps->stream)
      return false;
    if (mask && !(mask & flags))
      return false;
    return true;
  }
  /* Dump some information.  */
  bool operator () (const char *, ...);
};

/* The dumper.  */
static dumper dump = {0, dump_flags_t (0)};

/* Push to dumping M.  Return previous indentation level.  */

unsigned
dumper::push (module_state *m)
{
  FILE *stream = NULL;
  if (!dumps || !dumps->stack.length ())
    {
      stream = dump_begin (module_dump_id, &flags);
      if (!stream)
	return 0;
    }

  if (!dumps || !dumps->stack.space (1))
    {
      /* Create or extend the dump implementor.  */
      unsigned current = dumps ? dumps->stack.length () : 0;
      unsigned count = current ? current * 2 : EXPERIMENT (1, 20);
      size_t alloc = (offsetof (impl, stack)
		      + impl::stack_t::embedded_size (count));
      dumps = XRESIZEVAR (impl, dumps, alloc);
      dumps->stack.embedded_init (count, current);
    }
  if (stream)
    dumps->stream = stream;

  unsigned n = dumps->indent;
  dumps->indent = 0;
  dumps->bol = true;
  dumps->stack.quick_push (m);
  if (m)
    {
      module_state *from = NULL;

      if (dumps->stack.length () > 1)
	from = dumps->stack[dumps->stack.length () - 2];
      else
	dump ("");
      dump (from ? "Starting module %M (from %M)"
	    : "Starting module %M", m, from);
    }

  return n;
}

/* Pop from dumping.  Restore indentation to N.  */

void dumper::pop (unsigned n)
{
  if (!dumps)
    return;

  gcc_checking_assert (dump () && !dumps->indent);
  if (module_state *m = dumps->stack[dumps->stack.length () - 1])
    {
      module_state *from = (dumps->stack.length () > 1
			    ? dumps->stack[dumps->stack.length () - 2] : NULL);
      dump (from ? "Finishing module %M (returning to %M)"
	    : "Finishing module %M", m, from);
    }
  dumps->stack.pop ();
  dumps->indent = n;
  if (!dumps->stack.length ())
    {
      dump_end (module_dump_id, dumps->stream);
      dumps->stream = NULL;
    }
}

/* Dump a nested name for arbitrary tree T.  Sometimes it won't have a
   name.  */

bool
dumper::impl::nested_name (tree t)
{
  tree ti = NULL_TREE;
  int origin = -1;
  tree name = NULL_TREE;

  if (t && TREE_CODE (t) == TREE_BINFO)
    t = BINFO_TYPE (t);

  if (t && TYPE_P (t))
    t = TYPE_NAME (t);

  if (t && DECL_P (t))
    {
      if (t == global_namespace || DECL_TEMPLATE_PARM_P (t))
	;
      else if (tree ctx = DECL_CONTEXT (t))
	if (TREE_CODE (ctx) == TRANSLATION_UNIT_DECL
	    || nested_name (ctx))
	  fputs ("::", stream);

      int use_tpl;
      ti = node_template_info (t, use_tpl);
      if (ti && TREE_CODE (TI_TEMPLATE (ti)) == TEMPLATE_DECL
	  && (DECL_TEMPLATE_RESULT (TI_TEMPLATE (ti)) == t))
	t = TI_TEMPLATE (ti);
      tree not_tmpl = t;
      if (TREE_CODE (t) == TEMPLATE_DECL)
	{
	  fputs ("template ", stream);
	  not_tmpl = DECL_TEMPLATE_RESULT (t);
	}

      if (not_tmpl
	  && DECL_P (not_tmpl)
	  && DECL_LANG_SPECIFIC (not_tmpl)
	  && DECL_MODULE_IMPORT_P (not_tmpl))
	{
	  /* We need to be careful here, so as to not explode on
	     inconsistent data -- we're probably debugging, because
	     Something Is Wrong.  */
	  unsigned index = import_entity_index (t, true);
	  if (!(index & ~(~0u >> 1)))
	    origin = import_entity_module (index)->mod;
	  else if (index > ~(~0u >> 1))
	    /* An imported partition member that we're emitting.  */
	    origin = 0;
	  else
	    origin = -2;
	}

      name = DECL_NAME (t) ? DECL_NAME (t)
	: HAS_DECL_ASSEMBLER_NAME_P (t) ? DECL_ASSEMBLER_NAME_RAW (t)
	: NULL_TREE;
    }
  else
    name = t;

  if (name)
    switch (TREE_CODE (name))
      {
      default:
	fputs ("#unnamed#", stream);
	break;

      case IDENTIFIER_NODE:
	fwrite (IDENTIFIER_POINTER (name), 1, IDENTIFIER_LENGTH (name), stream);
	break;

      case INTEGER_CST:
	print_hex (wi::to_wide (name), stream);
	break;

      case STRING_CST:
	/* If TREE_TYPE is NULL, this is a raw string.  */
	fwrite (TREE_STRING_POINTER (name), 1,
		TREE_STRING_LENGTH (name) - (TREE_TYPE (name) != NULL_TREE),
		stream);
	break;
      }
  else
    fputs ("#null#", stream);

  if (origin >= 0)
    {
      const module_state *module = (*modules)[origin];
      fprintf (stream, "@%s:%d", !module ? "" : !module->name ? "(unnamed)"
	       : module->get_flatname (), origin);
    }
  else if (origin == -2)
    fprintf (stream, "@???");

  if (ti)
    {
      tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti));
      fputs ("<", stream);
      if (args)
	for (int ix = 0; ix != TREE_VEC_LENGTH (args); ix++)
	  {
	    if (ix)
	      fputs (",", stream);
	    nested_name (TREE_VEC_ELT (args, ix));
	  }
      fputs (">", stream);
    }

  return true;
}

/* Formatted dumping.  FORMAT begins with '+' do not emit a trailing
   new line.  (Normally it is appended.)
   Escapes:
      %C - tree_code
      %I - identifier
      %M - module_state
      %N - name -- DECL_NAME
      %P - context:name pair
      %R - unsigned:unsigned ratio
      %S - symbol -- DECL_ASSEMBLER_NAME
      %U - long unsigned
      %V - version
      --- the following are printf-like, but without its flexibility
      %d - decimal int
      %p - pointer
      %s - string
      %u - unsigned int
      %x - hex int

  We do not implement the printf modifiers.  */

bool
dumper::operator () (const char *format, ...)
{
  if (!(*this) ())
    return false;

  bool no_nl = format[0] == '+';
  format += no_nl;

  if (dumps->bol)
    {
      /* Module import indent.  */
      if (unsigned depth = dumps->stack.length () - 1)
	{
	  const char *prefix = ">>>>";
	  fprintf (dumps->stream, (depth <= strlen (prefix)
				   ? &prefix[strlen (prefix) - depth]
				   : ">.%d.>"), depth);
	}

      /* Local indent.  */
      if (unsigned indent = dumps->indent)
	{
	  const char *prefix = "      ";
	  fprintf (dumps->stream, (indent <= strlen (prefix)
				   ? &prefix[strlen (prefix) - indent]
				   : "  .%d.  "), indent);
	}
      dumps->bol = false;
    }

  va_list args;
  va_start (args, format);
  while (const char *esc = strchr (format, '%'))
    {
      fwrite (format, 1, (size_t)(esc - format), dumps->stream);
      format = ++esc;
      switch (*format++)
	{
	default:
	  gcc_unreachable ();

	case '%':
	  fputc ('%', dumps->stream);
	  break;

	case 'C': /* Code */
	  {
	    tree_code code = (tree_code)va_arg (args, unsigned);
	    fputs (get_tree_code_name (code), dumps->stream);
	  }
	  break;

	case 'I': /* Identifier.  */
	  {
	    tree t = va_arg (args, tree);
	    dumps->nested_name (t);
	  }
	  break;

	case 'M': /* Module. */
	  {
	    const char *str = "(none)";
	    if (module_state *m = va_arg (args, module_state *))
	      {
		if (!m->has_location ())
		  str = "(detached)";
		else
		  str = m->get_flatname ();
	      }
	    fputs (str, dumps->stream);
	  }
	  break;

	case 'N': /* Name.  */
	  {
	    tree t = va_arg (args, tree);
	    while (t && TREE_CODE (t) == OVERLOAD)
	      t = OVL_FUNCTION (t);
	    fputc ('\'', dumps->stream);
	    dumps->nested_name (t);
	    fputc ('\'', dumps->stream);
	  }
	  break;

	case 'P': /* Pair.  */
	  {
	    tree ctx = va_arg (args, tree);
	    tree name = va_arg (args, tree);
	    fputc ('\'', dumps->stream);
	    dumps->nested_name (ctx);
	    if (ctx && ctx != global_namespace)
	      fputs ("::", dumps->stream);
	    dumps->nested_name (name);
	    fputc ('\'', dumps->stream);
	  }
	  break;

	case 'R': /* Ratio */
	  {
	    unsigned a = va_arg (args, unsigned);
	    unsigned b = va_arg (args, unsigned);
	    fprintf (dumps->stream, "%.1f", (float) a / (b + !b));
	  }
	  break;

	case 'S': /* Symbol name */
	  {
	    tree t = va_arg (args, tree);
	    if (t && TYPE_P (t))
	      t = TYPE_NAME (t);
	    if (t && HAS_DECL_ASSEMBLER_NAME_P (t)
		&& DECL_ASSEMBLER_NAME_SET_P (t))
	      {
		fputc ('(', dumps->stream);
		fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t)),
		       dumps->stream);
		fputc (')', dumps->stream);
	      }
	  }
	  break;

	case 'U': /* long unsigned.  */
	  {
	    unsigned long u = va_arg (args, unsigned long);
	    fprintf (dumps->stream, "%lu", u);
	  }
	  break;

	case 'V': /* Verson.  */
	  {
	    unsigned v = va_arg (args, unsigned);
	    verstr_t string;

	    version2string (v, string);
	    fputs (string, dumps->stream);
	  }
	  break;

	case 'c': /* Character.  */
	  {
	    int c = va_arg (args, int);
	    fputc (c, dumps->stream);
	  }
	  break;

	case 'd': /* Decimal Int.  */
	  {
	    int d = va_arg (args, int);
	    fprintf (dumps->stream, "%d", d);
	  }
	  break;

	case 'p': /* Pointer. */
	  {
	    void *p = va_arg (args, void *);
	    fprintf (dumps->stream, "%p", p);
	  }
	  break;

	case 's': /* String. */
	  {
	    const char *s = va_arg (args, char *);
	    gcc_checking_assert (s);
	    fputs (s, dumps->stream);
	  }
	  break;

	case 'u': /* Unsigned.  */
	  {
	    unsigned u = va_arg (args, unsigned);
	    fprintf (dumps->stream, "%u", u);
	  }
	  break;

	case 'x': /* Hex. */
	  {
	    unsigned x = va_arg (args, unsigned);
	    fprintf (dumps->stream, "%x", x);
	  }
	  break;
	}
    }
  fputs (format, dumps->stream);
  va_end (args);
  if (!no_nl)
    {
      dumps->bol = true;
      fputc ('\n', dumps->stream);
    }
  return true;
}

struct note_def_cache_hasher : ggc_cache_ptr_hash<tree_node>
{
  static int keep_cache_entry (tree t)
  {
    if (!CHECKING_P)
      /* GTY is unfortunately not clever enough to conditionalize
	 this.  */
      gcc_unreachable ();

    if (ggc_marked_p (t))
      return -1;

    unsigned n = dump.push (NULL);
    /* This might or might not be an error.  We should note its
       dropping whichever.  */
    dump () && dump ("Dropping %N from note_defs table", t);
    dump.pop (n);

    return 0;
  }
};

/* We should stream each definition at most once.
   This needs to be a cache because there are cases where a definition
   ends up being not retained, and we need to drop those so we don't
   get confused if memory is reallocated.  */
typedef hash_table<note_def_cache_hasher> note_defs_table_t;
static GTY((cache)) note_defs_table_t *note_defs;

void
trees_in::assert_definition (tree decl ATTRIBUTE_UNUSED,
			     bool installing ATTRIBUTE_UNUSED)
{
#if CHECKING_P
  tree *slot = note_defs->find_slot (decl, installing ? INSERT : NO_INSERT);
  tree not_tmpl = STRIP_TEMPLATE (decl);
  if (installing)
    {
      /* We must be inserting for the first time.  */
      gcc_assert (!*slot);
      *slot = decl;
    }
  else
    /* If this is not the mergeable entity, it should not be in the
       table.  If it is a non-global-module mergeable entity, it
       should be in the table.  Global module entities could have been
       defined textually in the current TU and so might or might not
       be present.  */
    gcc_assert (!is_duplicate (decl)
		? !slot
		: (slot
		   || !DECL_LANG_SPECIFIC (not_tmpl)
		   || !DECL_MODULE_PURVIEW_P (not_tmpl)
		   || (!DECL_MODULE_IMPORT_P (not_tmpl)
		       && header_module_p ())));

  if (not_tmpl != decl)
    gcc_assert (!note_defs->find_slot (not_tmpl, NO_INSERT));
#endif
}

void
trees_out::assert_definition (tree decl ATTRIBUTE_UNUSED)
{
#if CHECKING_P
  tree *slot = note_defs->find_slot (decl, INSERT);
  gcc_assert (!*slot);
  *slot = decl;
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    gcc_assert (!note_defs->find_slot (DECL_TEMPLATE_RESULT (decl), NO_INSERT));
#endif
}

/********************************************************************/
static bool
noisy_p ()
{
  if (quiet_flag)
    return false;

  pp_needs_newline (global_dc->printer) = true;
  diagnostic_set_last_function (global_dc, (diagnostic_info *) NULL);

  return true;
}

/* Set the cmi repo.  Strip trailing '/', '.' becomes NULL.  */

static void
set_cmi_repo (const char *r)
{
  XDELETEVEC (cmi_repo);
  XDELETEVEC (cmi_path);
  cmi_path_alloc = 0;

  cmi_repo = NULL;
  cmi_repo_length = 0;

  if (!r || !r[0])
    return;

  size_t len = strlen (r);
  cmi_repo = XNEWVEC (char, len + 1);
  memcpy (cmi_repo, r, len + 1);
  
  if (len > 1 && IS_DIR_SEPARATOR (cmi_repo[len-1]))
    len--;
  if (len == 1 && cmi_repo[0] == '.')
    len--;
  cmi_repo[len] = 0;
  cmi_repo_length = len;
}

/* TO is a repo-relative name.  Provide one that we may use from where
   we are.  */

static const char *
maybe_add_cmi_prefix (const char *to, size_t *len_p = NULL)
{
  size_t len = len_p || cmi_repo_length ? strlen (to) : 0;

  if (cmi_repo_length && !IS_ABSOLUTE_PATH (to))
    {
      if (cmi_path_alloc < cmi_repo_length + len + 2)
	{
	  XDELETEVEC (cmi_path);
	  cmi_path_alloc = cmi_repo_length + len * 2 + 2;
	  cmi_path = XNEWVEC (char, cmi_path_alloc);

	  memcpy (cmi_path, cmi_repo, cmi_repo_length);
	  cmi_path[cmi_repo_length] = DIR_SEPARATOR;
	}

      memcpy (&cmi_path[cmi_repo_length + 1], to, len + 1);
      len += cmi_repo_length + 1;
      to = cmi_path;
    }

  if (len_p)
    *len_p = len;

  return to;
}

/* Try and create the directories of PATH.  */

static void
create_dirs (char *path)
{
  /* Try and create the missing directories.  */
  for (char *base = path; *base; base++)
    if (IS_DIR_SEPARATOR (*base))
      {
	char sep = *base;
	*base = 0;
	int failed = mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO);
	dump () && dump ("Mkdir ('%s') errno:=%u", path, failed ? errno : 0);
	*base = sep;
	if (failed
	    /* Maybe racing with another creator (of a *different*
	       module).  */
	    && errno != EEXIST)
	  break;
      }
}

/* Given a CLASSTYPE_DECL_LIST VALUE get the the template friend decl,
   if that's what this is.  */

static tree
friend_from_decl_list (tree frnd)
{
  tree res = frnd;

  if (TREE_CODE (frnd) != TEMPLATE_DECL)
    {
      tree tmpl = NULL_TREE;
      if (TYPE_P (frnd))
	{
	  res = TYPE_NAME (frnd);
	  if (CLASSTYPE_TEMPLATE_INFO (frnd))
	    tmpl = CLASSTYPE_TI_TEMPLATE (frnd);
	}
      else if (DECL_TEMPLATE_INFO (frnd))
	{
	  tmpl = DECL_TI_TEMPLATE (frnd);
	  if (TREE_CODE (tmpl) != TEMPLATE_DECL)
	    tmpl = NULL_TREE;
	}

      if (tmpl && DECL_TEMPLATE_RESULT (tmpl) == res)
	res = tmpl;
    }

  return res;
}

static tree
find_enum_member (tree ctx, tree name)
{
  for (tree values = TYPE_VALUES (ctx);
       values; values = TREE_CHAIN (values))
    if (DECL_NAME (TREE_VALUE (values)) == name)
      return TREE_VALUE (values);

  return NULL_TREE;
}

/********************************************************************/
/* Instrumentation gathered writing bytes.  */

void
bytes_out::instrument ()
{
  dump ("Wrote %u bytes in %u blocks", lengths[3], spans[3]);
  dump ("Wrote %u bits in %u bytes", lengths[0] + lengths[1], lengths[2]);
  for (unsigned ix = 0; ix < 2; ix++)
    dump ("  %u %s spans of %R bits", spans[ix],
	  ix ? "one" : "zero", lengths[ix], spans[ix]);
  dump ("  %u blocks with %R bits padding", spans[2],
	lengths[2] * 8 - (lengths[0] + lengths[1]), spans[2]);
}

/* Instrumentation gathered writing trees.  */
void
trees_out::instrument ()
{
  if (dump (""))
    {
      bytes_out::instrument ();
      dump ("Wrote:");
      dump ("  %u decl trees", decl_val_count);
      dump ("  %u other trees", tree_val_count);
      dump ("  %u back references", back_ref_count);
      dump ("  %u null trees", null_count);
    }
}

/* Setup and teardown for a tree walk.  */

void
trees_out::begin ()
{
  gcc_assert (!streaming_p () || !tree_map.elements ());

  mark_trees ();
  if (streaming_p ())
    parent::begin ();
}

unsigned
trees_out::end (elf_out *sink, unsigned name, unsigned *crc_ptr)
{
  gcc_checking_assert (streaming_p ());

  unmark_trees ();
  return parent::end (sink, name, crc_ptr);
}

void
trees_out::end ()
{
  gcc_assert (!streaming_p ());

  unmark_trees ();
  /* Do not parent::end -- we weren't streaming.  */
}

void
trees_out::mark_trees ()
{
  if (size_t size = tree_map.elements ())
    {
      /* This isn't our first rodeo, destroy and recreate the
	 tree_map.  I'm a bad bad man.  Use the previous size as a
	 guess for the next one (so not all bad).  */
      tree_map.~ptr_int_hash_map ();
      new (&tree_map) ptr_int_hash_map (size);
    }

  /* Install the fixed trees, with +ve references.  */
  unsigned limit = fixed_trees->length ();
  for (unsigned ix = 0; ix != limit; ix++)
    {
      tree val = (*fixed_trees)[ix];
      bool existed = tree_map.put (val, ix + tag_fixed);
      gcc_checking_assert (!TREE_VISITED (val) && !existed);
      TREE_VISITED (val) = true;
    }

  ref_num = 0;
}

/* Unmark the trees we encountered  */

void
trees_out::unmark_trees ()
{
  ptr_int_hash_map::iterator end (tree_map.end ());
  for (ptr_int_hash_map::iterator iter (tree_map.begin ()); iter != end; ++iter)
    {
      tree node = reinterpret_cast<tree> ((*iter).first);
      int ref = (*iter).second;
      /* We should have visited the node, and converted its mergeable
	 reference to a regular reference.  */
      gcc_checking_assert (TREE_VISITED (node)
			   && (ref <= tag_backref || ref >= tag_fixed));
      TREE_VISITED (node) = false;
    }
}

/* Mark DECL for by-value walking.  We do this by inserting it into
   the tree map with a reference of zero.  May be called multiple
   times on the same node.  */

void
trees_out::mark_by_value (tree decl)
{
  gcc_checking_assert (DECL_P (decl)
		       /* Enum consts are INTEGER_CSTS.  */
		       || TREE_CODE (decl) == INTEGER_CST
		       || TREE_CODE (decl) == TREE_BINFO);

  if (TREE_VISITED (decl))
    /* Must already be forced or fixed.  */
    gcc_checking_assert (*tree_map.get (decl) >= tag_value);
  else
    {
      bool existed = tree_map.put (decl, tag_value);
      gcc_checking_assert (!existed);
      TREE_VISITED (decl) = true;
    }
}

int
trees_out::get_tag (tree t)
{
  gcc_checking_assert (TREE_VISITED (t));
  return *tree_map.get (t);
}

/* Insert T into the map, return its tag number.    */

int
trees_out::insert (tree t, walk_kind walk)
{
  gcc_checking_assert (walk != WK_normal || !TREE_VISITED (t));
  int tag = --ref_num;
  bool existed;
  int &slot = tree_map.get_or_insert (t, &existed);
  gcc_checking_assert (TREE_VISITED (t) == existed
		       && (!existed
			   || (walk == WK_value && slot == tag_value)));
  TREE_VISITED (t) = true;
  slot = tag;

  return tag;
}

/* Insert T into the backreference array.  Return its back reference
   number.  */

int
trees_in::insert (tree t)
{
  gcc_checking_assert (t || get_overrun ());
  back_refs.safe_push (t);
  return -(int)back_refs.length ();
}

/* A chained set of decls.  */

void
trees_out::chained_decls (tree decls)
{
  for (; decls; decls = DECL_CHAIN (decls))
    {
      if (VAR_OR_FUNCTION_DECL_P (decls)
	  && DECL_LOCAL_DECL_P (decls))
	{
	  /* Make sure this is the first encounter, and mark for
	     walk-by-value.  */
	  gcc_checking_assert (!TREE_VISITED (decls)
			       && !DECL_TEMPLATE_INFO (decls));
	  mark_by_value (decls);
	}
      tree_node (decls);
    }
  tree_node (NULL_TREE);
}

tree
trees_in::chained_decls ()
{
  tree decls = NULL_TREE;
  for (tree *chain = &decls;;)
    if (tree decl = tree_node ())
      {
	if (!DECL_P (decl) || DECL_CHAIN (decl))
	  {
	    set_overrun ();
	    break;
	  }
	*chain = decl;
	chain = &DECL_CHAIN (decl);
      }
    else
      break;

  return decls;
}

/* A vector of decls following DECL_CHAIN.  */

void
trees_out::vec_chained_decls (tree decls)
{
  if (streaming_p ())
    {
      unsigned len = 0;

      for (tree decl = decls; decl; decl = DECL_CHAIN (decl))
	len++;
      u (len);
    }

  for (tree decl = decls; decl; decl = DECL_CHAIN (decl))
    {
      if (DECL_IMPLICIT_TYPEDEF_P (decl)
	  && TYPE_NAME (TREE_TYPE (decl)) != decl)
	/* An anonynmous struct with a typedef name.  An odd thing to
	   write.  */
	tree_node (NULL_TREE);
      else
	tree_node (decl);
    }
}

vec<tree, va_heap> *
trees_in::vec_chained_decls ()
{
  vec<tree, va_heap> *v = NULL;

  if (unsigned len = u ())
    {
      vec_alloc (v, len);

      for (unsigned ix = 0; ix < len; ix++)
	{
	  tree decl = tree_node ();
	  if (decl && !DECL_P (decl))
	    {
	      set_overrun ();
	      break;
	    }
	  v->quick_push (decl);
	}

      if (get_overrun ())
	{
	  vec_free (v);
	  v = NULL;
	}
    }

  return v;
}

/* A vector of trees.  */

void
trees_out::tree_vec (vec<tree, va_gc> *v)
{
  unsigned len = vec_safe_length (v);
  if (streaming_p ())
    u (len);
  for (unsigned ix = 0; ix != len; ix++)
    tree_node ((*v)[ix]);
}

vec<tree, va_gc> *
trees_in::tree_vec ()
{
  vec<tree, va_gc> *v = NULL;
  if (unsigned len = u ())
    {
      vec_alloc (v, len);
      for (unsigned ix = 0; ix != len; ix++)
	v->quick_push (tree_node ());
    }
  return v;
}

/* A vector of tree pairs.  */

void
trees_out::tree_pair_vec (vec<tree_pair_s, va_gc> *v)
{
  unsigned len = vec_safe_length (v);
  if (streaming_p ())
    u (len);
  if (len)
    for (unsigned ix = 0; ix != len; ix++)
      {
	tree_pair_s const &s = (*v)[ix];
	tree_node (s.purpose);
	tree_node (s.value);
      }
}

vec<tree_pair_s, va_gc> *
trees_in::tree_pair_vec ()
{
  vec<tree_pair_s, va_gc> *v = NULL;
  if (unsigned len = u ())
    {
      vec_alloc (v, len);
      for (unsigned ix = 0; ix != len; ix++)
	{
	  tree_pair_s s;
	  s.purpose = tree_node ();
	  s.value = tree_node ();
	  v->quick_push (s);
      }
    }
  return v;
}

void
trees_out::tree_list (tree list, bool has_purpose)
{
  for (; list; list = TREE_CHAIN (list))
    {
      gcc_checking_assert (TREE_VALUE (list));
      tree_node (TREE_VALUE (list));
      if (has_purpose)
	tree_node (TREE_PURPOSE (list));
    }
  tree_node (NULL_TREE);
}

tree
trees_in::tree_list (bool has_purpose)
{
  tree res = NULL_TREE;

  for (tree *chain = &res; tree value = tree_node ();
       chain = &TREE_CHAIN (*chain))
    {
      tree purpose = has_purpose ? tree_node () : NULL_TREE;
      *chain = build_tree_list (purpose, value);
    }

  return res;
}
/* Start tree write.  Write information to allocate the receiving
   node.  */

void
trees_out::start (tree t, bool code_streamed)
{
  if (TYPE_P (t))
    {
      enum tree_code code = TREE_CODE (t);
      gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
      /* All these types are TYPE_NON_COMMON.  */
      gcc_checking_assert (code == RECORD_TYPE
			   || code == UNION_TYPE
			   || code == ENUMERAL_TYPE
			   || code == TEMPLATE_TYPE_PARM
			   || code == TEMPLATE_TEMPLATE_PARM
			   || code == BOUND_TEMPLATE_TEMPLATE_PARM);
    }

  if (!code_streamed)
    u (TREE_CODE (t));

  switch (TREE_CODE (t))
    {
    default:
      if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_vl_exp)
	u (VL_EXP_OPERAND_LENGTH (t));
      break;

    case INTEGER_CST:
      u (TREE_INT_CST_NUNITS (t));
      u (TREE_INT_CST_EXT_NUNITS (t));
      u (TREE_INT_CST_OFFSET_NUNITS (t));
      break;

    case OMP_CLAUSE:
      state->extensions |= SE_OPENMP;
      u (OMP_CLAUSE_CODE (t));
      break;

    case STRING_CST:
      str (TREE_STRING_POINTER (t), TREE_STRING_LENGTH (t));
      break;

    case VECTOR_CST:
      u (VECTOR_CST_LOG2_NPATTERNS (t));
      u (VECTOR_CST_NELTS_PER_PATTERN (t));
      break;

    case TREE_BINFO:
      u (BINFO_N_BASE_BINFOS (t));
      break;

    case TREE_VEC:
      u (TREE_VEC_LENGTH (t));
      break;

    case FIXED_CST:
    case POLY_INT_CST:
      gcc_unreachable (); /* Not supported in C++.  */
      break;

    case IDENTIFIER_NODE:
    case SSA_NAME:
    case TARGET_MEM_REF:
    case TRANSLATION_UNIT_DECL:
      /* We shouldn't meet these.  */
      gcc_unreachable ();
      break;
    }
}

/* Start tree read.  Allocate the receiving node.  */

tree
trees_in::start (unsigned code)
{
  tree t = NULL_TREE;

  if (!code)
    code = u ();

  switch (code)
    {
    default:
      if (code >= MAX_TREE_CODES)
	{
	fail:
	  set_overrun ();
	  return NULL_TREE;
	}
      else if (TREE_CODE_CLASS (code) == tcc_vl_exp)
	{
	  unsigned ops = u ();
	  t = build_vl_exp (tree_code (code), ops);
	}
      else
	t = make_node (tree_code (code));
      break;

    case INTEGER_CST:
      {
	unsigned n = u ();
	unsigned e = u ();
	t = make_int_cst (n, e);
	TREE_INT_CST_OFFSET_NUNITS(t) = u ();
      }
      break;

    case OMP_CLAUSE:
      {
	if (!(state->extensions & SE_OPENMP))
	  goto fail;

	unsigned omp_code = u ();
	t = build_omp_clause (UNKNOWN_LOCATION, omp_clause_code (omp_code));
      }
      break;

    case STRING_CST:
      {
	size_t l;
	const char *chars = str (&l);
	t = build_string (l, chars);
      }
      break;

    case VECTOR_CST:
      {
	unsigned log2_npats = u ();
	unsigned elts_per = u ();
	t = make_vector (log2_npats, elts_per);
      }
      break;

    case TREE_BINFO:
      t = make_tree_binfo (u ());
      break;

    case TREE_VEC:
      t = make_tree_vec (u ());
      break;

    case FIXED_CST:
    case IDENTIFIER_NODE:
    case POLY_INT_CST:
    case SSA_NAME:
    case TARGET_MEM_REF:
    case TRANSLATION_UNIT_DECL:
      goto fail;
    }

  return t;
}

/* The structure streamers access the raw fields, because the
   alternative, of using the accessor macros can require using
   different accessors for the same underlying field, depending on the
   tree code.  That's both confusing and annoying.  */

/* Read & write the core boolean flags.  */

void
trees_out::core_bools (tree t)
{
#define WB(X) (b (X))
  tree_code code = TREE_CODE (t);

  WB (t->base.side_effects_flag);
  WB (t->base.constant_flag);
  WB (t->base.addressable_flag);
  WB (t->base.volatile_flag);
  WB (t->base.readonly_flag);
  /* base.asm_written_flag is a property of the current TU's use of
     this decl.  */
  WB (t->base.nowarning_flag);
  /* base.visited read as zero (it's set for writer, because that's
     how we mark nodes).  */
  /* base.used_flag is not streamed.  Readers may set TREE_USED of
     decls they use.  */
  WB (t->base.nothrow_flag);
  WB (t->base.static_flag);
  if (TREE_CODE_CLASS (code) != tcc_type)
    /* This is TYPE_CACHED_VALUES_P for types.  */
    WB (t->base.public_flag);
  WB (t->base.private_flag);
  WB (t->base.protected_flag);
  WB (t->base.deprecated_flag);
  WB (t->base.default_def_flag);

  switch (code)
    {
    case CALL_EXPR:
    case INTEGER_CST:
    case SSA_NAME:
    case TARGET_MEM_REF:
    case TREE_VEC:
      /* These use different base.u fields.  */
      break;

    default:
      WB (t->base.u.bits.lang_flag_0);
      bool flag_1 = t->base.u.bits.lang_flag_1;
      if (!flag_1)
	;
      else if (code == TEMPLATE_INFO)
	/* This is TI_PENDING_TEMPLATE_FLAG, not relevant to reader.  */
	flag_1 = false;
      else if (code == VAR_DECL)
	{
	  /* This is DECL_INITIALIZED_P.  */
	  if (TREE_CODE (DECL_CONTEXT (t)) != FUNCTION_DECL)
	    /* We'll set this when reading the definition.  */
	    flag_1 = false;
	}
      WB (flag_1);
      WB (t->base.u.bits.lang_flag_2);
      WB (t->base.u.bits.lang_flag_3);
      WB (t->base.u.bits.lang_flag_4);
      WB (t->base.u.bits.lang_flag_5);
      WB (t->base.u.bits.lang_flag_6);
      WB (t->base.u.bits.saturating_flag);
      WB (t->base.u.bits.unsigned_flag);
      WB (t->base.u.bits.packed_flag);
      WB (t->base.u.bits.user_align);
      WB (t->base.u.bits.nameless_flag);
      WB (t->base.u.bits.atomic_flag);
      break;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      WB (t->type_common.no_force_blk_flag);
      WB (t->type_common.needs_constructing_flag);
      WB (t->type_common.transparent_aggr_flag);
      WB (t->type_common.restrict_flag);
      WB (t->type_common.string_flag);
      WB (t->type_common.lang_flag_0);
      WB (t->type_common.lang_flag_1);
      WB (t->type_common.lang_flag_2);
      WB (t->type_common.lang_flag_3);
      WB (t->type_common.lang_flag_4);
      WB (t->type_common.lang_flag_5);
      WB (t->type_common.lang_flag_6);
      WB (t->type_common.typeless_storage);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      WB (t->decl_common.nonlocal_flag);
      WB (t->decl_common.virtual_flag);
      WB (t->decl_common.ignored_flag);
      WB (t->decl_common.abstract_flag);
      WB (t->decl_common.artificial_flag);
      WB (t->decl_common.preserve_flag);
      WB (t->decl_common.debug_expr_is_from);
      WB (t->decl_common.lang_flag_0);
      WB (t->decl_common.lang_flag_1);
      WB (t->decl_common.lang_flag_2);
      WB (t->decl_common.lang_flag_3);
      WB (t->decl_common.lang_flag_4);
      WB (t->decl_common.lang_flag_5);
      WB (t->decl_common.lang_flag_6);
      WB (t->decl_common.lang_flag_7);
      WB (t->decl_common.lang_flag_8);
      WB (t->decl_common.decl_flag_0);

      {
	/* DECL_EXTERNAL -> decl_flag_1
	     == it is defined elsewhere
	   DECL_NOT_REALLY_EXTERN -> base.not_really_extern
	     == that was a lie, it is here  */

	bool is_external = t->decl_common.decl_flag_1;
	if (!is_external)
	  /* decl_flag_1 is DECL_EXTERNAL. Things we emit here, might
	     well be external from the POV of an importer.  */
	  // FIXME: Do we need to know if this is a TEMPLATE_RESULT --
	  // a flag from the caller?
	  switch (code)
	    {
	    default:
	      break;

	    case VAR_DECL:
	      if (TREE_PUBLIC (t)
		  && !DECL_VAR_DECLARED_INLINE_P (t))
		is_external = true;
	      break;

	    case FUNCTION_DECL:
	      if (TREE_PUBLIC (t)
		  && !DECL_DECLARED_INLINE_P (t))
		is_external = true;
	      break;
	    }
	WB (is_external);
      }

      WB (t->decl_common.decl_flag_2);
      WB (t->decl_common.decl_flag_3);
      WB (t->decl_common.not_gimple_reg_flag);
      WB (t->decl_common.decl_by_reference_flag);
      WB (t->decl_common.decl_read_flag);
      WB (t->decl_common.decl_nonshareable_flag);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      WB (t->decl_with_vis.defer_output);
      WB (t->decl_with_vis.hard_register);
      WB (t->decl_with_vis.common_flag);
      WB (t->decl_with_vis.in_text_section);
      WB (t->decl_with_vis.in_constant_pool);
      WB (t->decl_with_vis.dllimport_flag);
      WB (t->decl_with_vis.weak_flag);
      WB (t->decl_with_vis.seen_in_bind_expr);
      WB (t->decl_with_vis.comdat_flag);
      WB (t->decl_with_vis.visibility_specified);
      WB (t->decl_with_vis.init_priority_p);
      WB (t->decl_with_vis.shadowed_for_var_p);
      WB (t->decl_with_vis.cxx_constructor);
      WB (t->decl_with_vis.cxx_destructor);
      WB (t->decl_with_vis.final);
      WB (t->decl_with_vis.regdecl_flag);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    {
      WB (t->function_decl.static_ctor_flag);
      WB (t->function_decl.static_dtor_flag);
      WB (t->function_decl.uninlinable);
      WB (t->function_decl.possibly_inlined);
      WB (t->function_decl.novops_flag);
      WB (t->function_decl.returns_twice_flag);
      WB (t->function_decl.malloc_flag);
      WB (t->function_decl.declared_inline_flag);
      WB (t->function_decl.no_inline_warning_flag);
      WB (t->function_decl.no_instrument_function_entry_exit);
      WB (t->function_decl.no_limit_stack);
      WB (t->function_decl.disregard_inline_limits);
      WB (t->function_decl.pure_flag);
      WB (t->function_decl.looping_const_or_pure_flag);

      WB (t->function_decl.has_debug_args_flag);
      WB (t->function_decl.versioned_function);

      /* decl_type is a (misnamed) 2 bit discriminator.	 */
      unsigned kind = t->function_decl.decl_type;
      WB ((kind >> 0) & 1);
      WB ((kind >> 1) & 1);
    }
#undef WB
}

bool
trees_in::core_bools (tree t)
{
#define RB(X) ((X) = b ())
  tree_code code = TREE_CODE (t);

  RB (t->base.side_effects_flag);
  RB (t->base.constant_flag);
  RB (t->base.addressable_flag);
  RB (t->base.volatile_flag);
  RB (t->base.readonly_flag);
  /* base.asm_written_flag is not streamed.  */
  RB (t->base.nowarning_flag);
  /* base.visited is not streamed.  */
  /* base.used_flag is not streamed.  */
  RB (t->base.nothrow_flag);
  RB (t->base.static_flag);
  if (TREE_CODE_CLASS (code) != tcc_type)
    RB (t->base.public_flag);
  RB (t->base.private_flag);
  RB (t->base.protected_flag);
  RB (t->base.deprecated_flag);
  RB (t->base.default_def_flag);

  switch (code)
    {
    case CALL_EXPR:
    case INTEGER_CST:
    case SSA_NAME:
    case TARGET_MEM_REF:
    case TREE_VEC:
      /* These use different base.u fields.  */
      break;

    default:
      RB (t->base.u.bits.lang_flag_0);
      RB (t->base.u.bits.lang_flag_1);
      RB (t->base.u.bits.lang_flag_2);
      RB (t->base.u.bits.lang_flag_3);
      RB (t->base.u.bits.lang_flag_4);
      RB (t->base.u.bits.lang_flag_5);
      RB (t->base.u.bits.lang_flag_6);
      RB (t->base.u.bits.saturating_flag);
      RB (t->base.u.bits.unsigned_flag);
      RB (t->base.u.bits.packed_flag);
      RB (t->base.u.bits.user_align);
      RB (t->base.u.bits.nameless_flag);
      RB (t->base.u.bits.atomic_flag);
      break;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      RB (t->type_common.no_force_blk_flag);
      RB (t->type_common.needs_constructing_flag);
      RB (t->type_common.transparent_aggr_flag);
      RB (t->type_common.restrict_flag);
      RB (t->type_common.string_flag);
      RB (t->type_common.lang_flag_0);
      RB (t->type_common.lang_flag_1);
      RB (t->type_common.lang_flag_2);
      RB (t->type_common.lang_flag_3);
      RB (t->type_common.lang_flag_4);
      RB (t->type_common.lang_flag_5);
      RB (t->type_common.lang_flag_6);
      RB (t->type_common.typeless_storage);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      RB (t->decl_common.nonlocal_flag);
      RB (t->decl_common.virtual_flag);
      RB (t->decl_common.ignored_flag);
      RB (t->decl_common.abstract_flag);
      RB (t->decl_common.artificial_flag);
      RB (t->decl_common.preserve_flag);
      RB (t->decl_common.debug_expr_is_from);
      RB (t->decl_common.lang_flag_0);
      RB (t->decl_common.lang_flag_1);
      RB (t->decl_common.lang_flag_2);
      RB (t->decl_common.lang_flag_3);
      RB (t->decl_common.lang_flag_4);
      RB (t->decl_common.lang_flag_5);
      RB (t->decl_common.lang_flag_6);
      RB (t->decl_common.lang_flag_7);
      RB (t->decl_common.lang_flag_8);
      RB (t->decl_common.decl_flag_0);
      RB (t->decl_common.decl_flag_1);
      RB (t->decl_common.decl_flag_2);
      RB (t->decl_common.decl_flag_3);
      RB (t->decl_common.not_gimple_reg_flag);
      RB (t->decl_common.decl_by_reference_flag);
      RB (t->decl_common.decl_read_flag);
      RB (t->decl_common.decl_nonshareable_flag);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      RB (t->decl_with_vis.defer_output);
      RB (t->decl_with_vis.hard_register);
      RB (t->decl_with_vis.common_flag);
      RB (t->decl_with_vis.in_text_section);
      RB (t->decl_with_vis.in_constant_pool);
      RB (t->decl_with_vis.dllimport_flag);
      RB (t->decl_with_vis.weak_flag);
      RB (t->decl_with_vis.seen_in_bind_expr);
      RB (t->decl_with_vis.comdat_flag);
      RB (t->decl_with_vis.visibility_specified);
      RB (t->decl_with_vis.init_priority_p);
      RB (t->decl_with_vis.shadowed_for_var_p);
      RB (t->decl_with_vis.cxx_constructor);
      RB (t->decl_with_vis.cxx_destructor);
      RB (t->decl_with_vis.final);
      RB (t->decl_with_vis.regdecl_flag);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    {
      RB (t->function_decl.static_ctor_flag);
      RB (t->function_decl.static_dtor_flag);
      RB (t->function_decl.uninlinable);
      RB (t->function_decl.possibly_inlined);
      RB (t->function_decl.novops_flag);
      RB (t->function_decl.returns_twice_flag);
      RB (t->function_decl.malloc_flag);
      RB (t->function_decl.declared_inline_flag);
      RB (t->function_decl.no_inline_warning_flag);
      RB (t->function_decl.no_instrument_function_entry_exit);
      RB (t->function_decl.no_limit_stack);
      RB (t->function_decl.disregard_inline_limits);
      RB (t->function_decl.pure_flag);
      RB (t->function_decl.looping_const_or_pure_flag);
      
      RB (t->function_decl.has_debug_args_flag);
      RB (t->function_decl.versioned_function);

      /* decl_type is a (misnamed) 2 bit discriminator.	 */
      unsigned kind = 0;
      kind |= unsigned (b ()) << 0;
      kind |= unsigned (b ()) << 1;
      t->function_decl.decl_type = function_decl_type (kind);
    }
#undef RB
  return !get_overrun ();
}

void
trees_out::lang_decl_bools (tree t)
{
#define WB(X) (b (X))
  const struct lang_decl *lang = DECL_LANG_SPECIFIC (t);

  WB (lang->u.base.language == lang_cplusplus);
  WB ((lang->u.base.use_template >> 0) & 1);
  WB ((lang->u.base.use_template >> 1) & 1);
  /* Do not write lang->u.base.not_really_extern, importer will set
     when reading the definition (if any).  */
  WB (lang->u.base.initialized_in_class);
  WB (lang->u.base.threadprivate_or_deleted_p);
  /* Do not write lang->u.base.anticipated_p, it is a property of the
     current TU.  */
  WB (lang->u.base.friend_or_tls);
  WB (lang->u.base.unknown_bound_p);
  /* Do not write lang->u.base.odr_used, importer will recalculate if
     they do ODR use this decl.  */
  WB (lang->u.base.concept_p);
  WB (lang->u.base.var_declared_inline_p);
  WB (lang->u.base.dependent_init_p);
  /* When building a header unit, everthing is marked as purview, but
     that's the GM purview, so not what the importer will mean  */
  WB (lang->u.base.module_purview_p && !header_module_p ());
  if (VAR_OR_FUNCTION_DECL_P (t))
    WB (lang->u.base.module_attached_p);
  switch (lang->u.base.selector)
    {
    default:
      gcc_unreachable ();

    case lds_fn:  /* lang_decl_fn.  */
      WB (lang->u.fn.global_ctor_p);
      WB (lang->u.fn.global_dtor_p);
      WB (lang->u.fn.static_function);
      WB (lang->u.fn.pure_virtual);
      WB (lang->u.fn.defaulted_p);
      WB (lang->u.fn.has_in_charge_parm_p);
      WB (lang->u.fn.has_vtt_parm_p);
      /* There shouldn't be a pending inline at this point.  */
      gcc_assert (!lang->u.fn.pending_inline_p);
      WB (lang->u.fn.nonconverting);
      WB (lang->u.fn.thunk_p);
      WB (lang->u.fn.this_thunk_p);
      /* Do not stream lang->u.hidden_friend_p, it is a property of
	 the TU.  */
      WB (lang->u.fn.omp_declare_reduction_p);
      WB (lang->u.fn.has_dependent_explicit_spec_p);
      WB (lang->u.fn.immediate_fn_p);
      WB (lang->u.fn.maybe_deleted);
      goto lds_min;

    case lds_decomp:  /* lang_decl_decomp.  */
      /* No bools.  */
      goto lds_min;

    case lds_min:  /* lang_decl_min.  */
    lds_min:
      /* No bools.  */
      break;

    case lds_ns:  /* lang_decl_ns.  */
      /* No bools.  */
      break;

    case lds_parm:  /* lang_decl_parm.  */
      /* No bools.  */
      break;
    }
#undef WB
}

bool
trees_in::lang_decl_bools (tree t)
{
#define RB(X) ((X) = b ())
  struct lang_decl *lang = DECL_LANG_SPECIFIC (t);

  lang->u.base.language = b () ? lang_cplusplus : lang_c;
  unsigned v;
  v = b () << 0;
  v |= b () << 1;
  lang->u.base.use_template = v;
  /* lang->u.base.not_really_extern is not streamed.  */
  RB (lang->u.base.initialized_in_class);
  RB (lang->u.base.threadprivate_or_deleted_p);
  /* lang->u.base.anticipated_p is not streamed.  */
  RB (lang->u.base.friend_or_tls);
  RB (lang->u.base.unknown_bound_p);
  /* lang->u.base.odr_used is not streamed.  */
  RB (lang->u.base.concept_p);
  RB (lang->u.base.var_declared_inline_p);
  RB (lang->u.base.dependent_init_p);
  RB (lang->u.base.module_purview_p);
  if (VAR_OR_FUNCTION_DECL_P (t))
    RB (lang->u.base.module_attached_p);
  switch (lang->u.base.selector)
    {
    default:
      gcc_unreachable ();

    case lds_fn:  /* lang_decl_fn.  */
      RB (lang->u.fn.global_ctor_p);
      RB (lang->u.fn.global_dtor_p);
      RB (lang->u.fn.static_function);
      RB (lang->u.fn.pure_virtual);
      RB (lang->u.fn.defaulted_p);
      RB (lang->u.fn.has_in_charge_parm_p);
      RB (lang->u.fn.has_vtt_parm_p);
      RB (lang->u.fn.nonconverting);
      RB (lang->u.fn.thunk_p);
      RB (lang->u.fn.this_thunk_p);
      /* lang->u.fn.hidden_friend_p is not streamed.  */
      RB (lang->u.fn.omp_declare_reduction_p);
      RB (lang->u.fn.has_dependent_explicit_spec_p);
      RB (lang->u.fn.immediate_fn_p);
      RB (lang->u.fn.maybe_deleted);
      goto lds_min;

    case lds_decomp:  /* lang_decl_decomp.  */
      /* No bools.  */
      goto lds_min;

    case lds_min:  /* lang_decl_min.  */
    lds_min:
      /* No bools.  */
      break;

    case lds_ns:  /* lang_decl_ns.  */
      /* No bools.  */
      break;

    case lds_parm:  /* lang_decl_parm.  */
      /* No bools.  */
      break;
    }
#undef RB
  return !get_overrun ();
}

void
trees_out::lang_type_bools (tree t)
{
#define WB(X) (b (X))
  const struct lang_type *lang = TYPE_LANG_SPECIFIC (t);

  WB (lang->has_type_conversion);
  WB (lang->has_copy_ctor);
  WB (lang->has_default_ctor);
  WB (lang->const_needs_init);
  WB (lang->ref_needs_init);
  WB (lang->has_const_copy_assign);
  WB ((lang->use_template >> 0) & 1);
  WB ((lang->use_template >> 1) & 1);

  WB (lang->has_mutable);
  WB (lang->com_interface);
  WB (lang->non_pod_class);
  WB (lang->nearly_empty_p);
  WB (lang->user_align);
  WB (lang->has_copy_assign);
  WB (lang->has_new);
  WB (lang->has_array_new);

  WB ((lang->gets_delete >> 0) & 1);
  WB ((lang->gets_delete >> 1) & 1);
  // Interfaceness is recalculated upon reading.  May have to revisit?
  // How do dllexport and dllimport interact across a module?
  // lang->interface_only
  // lang->interface_unknown
  WB (lang->contains_empty_class_p);
  WB (lang->anon_aggr);
  WB (lang->non_zero_init);
  WB (lang->empty_p);

  WB (lang->vec_new_uses_cookie);
  WB (lang->declared_class);
  WB (lang->diamond_shaped);
  WB (lang->repeated_base);
  gcc_assert (!lang->being_defined);
  // lang->debug_requested
  WB (lang->fields_readonly);
  WB (lang->ptrmemfunc_flag);

  WB (lang->lazy_default_ctor);
  WB (lang->lazy_copy_ctor);
  WB (lang->lazy_copy_assign);
  WB (lang->lazy_destructor);
  WB (lang->has_const_copy_ctor);
  WB (lang->has_complex_copy_ctor);
  WB (lang->has_complex_copy_assign);
  WB (lang->non_aggregate);

  WB (lang->has_complex_dflt);
  WB (lang->has_list_ctor);
  WB (lang->non_std_layout);
  WB (lang->is_literal);
  WB (lang->lazy_move_ctor);
  WB (lang->lazy_move_assign);
  WB (lang->has_complex_move_ctor);
  WB (lang->has_complex_move_assign);

  WB (lang->has_constexpr_ctor);
  WB (lang->unique_obj_representations);
  WB (lang->unique_obj_representations_set);
#undef WB
}

bool
trees_in::lang_type_bools (tree t)
{
#define RB(X) ((X) = b ())
  struct lang_type *lang = TYPE_LANG_SPECIFIC (t);

  RB (lang->has_type_conversion);
  RB (lang->has_copy_ctor);
  RB (lang->has_default_ctor);
  RB (lang->const_needs_init);
  RB (lang->ref_needs_init);
  RB (lang->has_const_copy_assign);
  unsigned v;
  v = b () << 0;
  v |= b () << 1;
  lang->use_template = v;

  RB (lang->has_mutable);
  RB (lang->com_interface);
  RB (lang->non_pod_class);
  RB (lang->nearly_empty_p);
  RB (lang->user_align);
  RB (lang->has_copy_assign);
  RB (lang->has_new);
  RB (lang->has_array_new);

  v = b () << 0;
  v |= b () << 1;
  lang->gets_delete = v;
  // lang->interface_only
  // lang->interface_unknown
  lang->interface_unknown = true; // Redetermine interface
  RB (lang->contains_empty_class_p);
  RB (lang->anon_aggr);
  RB (lang->non_zero_init);
  RB (lang->empty_p);

  RB (lang->vec_new_uses_cookie);
  RB (lang->declared_class);
  RB (lang->diamond_shaped);
  RB (lang->repeated_base);
  gcc_assert (!lang->being_defined);
  gcc_assert (!lang->debug_requested);
  RB (lang->fields_readonly);
  RB (lang->ptrmemfunc_flag);

  RB (lang->lazy_default_ctor);
  RB (lang->lazy_copy_ctor);
  RB (lang->lazy_copy_assign);
  RB (lang->lazy_destructor);
  RB (lang->has_const_copy_ctor);
  RB (lang->has_complex_copy_ctor);
  RB (lang->has_complex_copy_assign);
  RB (lang->non_aggregate);

  RB (lang->has_complex_dflt);
  RB (lang->has_list_ctor);
  RB (lang->non_std_layout);
  RB (lang->is_literal);
  RB (lang->lazy_move_ctor);
  RB (lang->lazy_move_assign);
  RB (lang->has_complex_move_ctor);
  RB (lang->has_complex_move_assign);

  RB (lang->has_constexpr_ctor);
  RB (lang->unique_obj_representations);
  RB (lang->unique_obj_representations_set);
#undef RB
  return !get_overrun ();
}

/* Read & write the core values and pointers.  */

void
trees_out::core_vals (tree t)
{
#define WU(X) (u (X))
#define WT(X) (tree_node (X))
  tree_code code = TREE_CODE (t);

  /* First by shape of the tree.  */

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
    {
      /* Write this early, for better log information.  */
      WT (t->decl_minimal.name);
      if (!DECL_TEMPLATE_PARM_P (t))
	WT (t->decl_minimal.context);

      if (state)
	state->write_location (*this, t->decl_minimal.locus);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      /* The only types we write also have TYPE_NON_COMMON.  */
      gcc_checking_assert (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON));

      /* We only stream the main variant.  */
      gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);

      /* Stream the name & context first, for better log information  */
      WT (t->type_common.name);
      WT (t->type_common.context);

      /* By construction we want to make sure we have the canonical
	 and main variants already in the type table, so emit them
	 now.  */
      WT (t->type_common.main_variant);

      tree canonical = t->type_common.canonical;
      if (canonical && DECL_TEMPLATE_PARM_P (TYPE_NAME (t)))
	/* We do not want to wander into different templates.
	   Reconstructed on stream in.  */
	canonical = t;
      WT (canonical);

      /* type_common.next_variant is internally manipulated.  */
      /* type_common.pointer_to, type_common.reference_to.  */

      if (streaming_p ())
	{
	  WU (t->type_common.precision);
	  WU (t->type_common.contains_placeholder_bits);
	  WU (t->type_common.mode);
	  WU (t->type_common.align);
	}

      if (!RECORD_OR_UNION_CODE_P (code))
	{
	  WT (t->type_common.size);
	  WT (t->type_common.size_unit);
	}
      WT (t->type_common.attributes);

      WT (t->type_common.common.chain); /* TYPE_STUB_DECL.  */
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      if (streaming_p ())
	{
	  WU (t->decl_common.mode);
	  WU (t->decl_common.off_align);
	  WU (t->decl_common.align);
	}

      /* For templates these hold instantiation (partial and/or
	 specialization) information.  */
      if (code != TEMPLATE_DECL)
	{
	  WT (t->decl_common.size);
	  WT (t->decl_common.size_unit);
	}

      WT (t->decl_common.attributes);
      // FIXME: Does this introduce cross-decl links?  For instance
      // from instantiation to the template.  If so, we'll need more
      // deduplication logic.  I think we'll need to walk the blocks
      // of the owning function_decl's abstract origin in tandem, to
      // generate the locating data needed?
      WT (t->decl_common.abstract_origin);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      WT (t->decl_with_vis.assembler_name);
      if (streaming_p ())
	WU (t->decl_with_vis.visibility);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
    {
      /* Records and unions hold FIELDS, VFIELD & BINFO on these
	 things.  */
      if (!RECORD_OR_UNION_CODE_P (code) && code != ENUMERAL_TYPE)
	{
	  // FIXME: These are from tpl_parm_value's 'type' writing.
	  // Perhaps it should just be doing them directly?
	  gcc_checking_assert (code == TEMPLATE_TYPE_PARM
			       || code == TEMPLATE_TEMPLATE_PARM
			       || code == BOUND_TEMPLATE_TEMPLATE_PARM);
	  gcc_checking_assert (!TYPE_CACHED_VALUES_P (t));
	  WT (t->type_non_common.values);
	  WT (t->type_non_common.maxval);
	  WT (t->type_non_common.minval);
	}

      WT (t->type_non_common.lang_1);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
    {
      if (state)
	state->write_location (*this, t->exp.locus);

      /* Walk in forward order, as (for instance) REQUIRES_EXPR has a
         bunch of unscoped parms on its first operand.  It's safer to
         create those in order.  */
      bool vl = TREE_CODE_CLASS (code) == tcc_vl_exp;
      for (unsigned limit = (vl ? VL_EXP_OPERAND_LENGTH (t)
			     : TREE_OPERAND_LENGTH (t)),
	     ix = unsigned (vl); ix != limit; ix++)
	WT (TREE_OPERAND (t, ix));
    }
  else
    /* The CODE_CONTAINS tables were inaccurate when I started.  */
    gcc_checking_assert (TREE_CODE_CLASS (code) != tcc_expression
			 && TREE_CODE_CLASS (code) != tcc_binary
			 && TREE_CODE_CLASS (code) != tcc_unary
			 && TREE_CODE_CLASS (code) != tcc_reference
			 && TREE_CODE_CLASS (code) != tcc_comparison
			 && TREE_CODE_CLASS (code) != tcc_statement
			 && TREE_CODE_CLASS (code) != tcc_vl_exp);

  /* Then by CODE.  Special cases and/or 1:1 tree shape
     correspondance. */
  switch (code)
    {
    default:
      break;

    case ARGUMENT_PACK_SELECT:  /* Transient during instantiation.  */
    case DEFERRED_PARSE:	/* Expanded upon completion of
				   outermost class.  */
    case IDENTIFIER_NODE:	/* Streamed specially.  */
    case BINDING_VECTOR:		/* Only in namespace-scope symbol
				   table.  */
    case SSA_NAME:
    case TRANSLATION_UNIT_DECL: /* There is only one, it is a
				   global_tree.  */
    case USERDEF_LITERAL:  	/* Expanded during parsing.  */
      gcc_unreachable (); /* Should never meet.  */

      /* Constants.  */
    case COMPLEX_CST:
      WT (TREE_REALPART (t));
      WT (TREE_IMAGPART (t));
      break;

    case FIXED_CST:
      gcc_unreachable (); /* Not supported in C++.  */

    case INTEGER_CST:
      if (streaming_p ())
	{
	  unsigned num = TREE_INT_CST_EXT_NUNITS (t);
	  for (unsigned ix = 0; ix != num; ix++)
	    wu (TREE_INT_CST_ELT (t, ix));
	}
      break;

    case POLY_INT_CST:
      gcc_unreachable (); /* Not supported in C++.  */

    case REAL_CST:
      if (streaming_p ())
	buf (TREE_REAL_CST_PTR (t), sizeof (real_value));
      break;

    case STRING_CST:
      /* Streamed during start.  */
      break;

    case VECTOR_CST:
      for (unsigned ix = vector_cst_encoded_nelts (t); ix--;)
	WT (VECTOR_CST_ENCODED_ELT (t, ix));
      break;

      /* Decls.  */
    case VAR_DECL:
      if (DECL_CONTEXT (t)
	  && TREE_CODE (DECL_CONTEXT (t)) != FUNCTION_DECL)
	break;
      /* FALLTHROUGH  */

    case RESULT_DECL:
    case PARM_DECL:
      if (DECL_HAS_VALUE_EXPR_P (t))
	WT (DECL_VALUE_EXPR (t));
      /* FALLTHROUGH  */

    case CONST_DECL:
    case IMPORTED_DECL:
      WT (t->decl_common.initial);
      break;

    case FIELD_DECL:
      WT (t->field_decl.offset);
      WT (t->field_decl.bit_field_type);
      WT (t->field_decl.qualifier); /* bitfield unit.  */
      WT (t->field_decl.bit_offset);
      WT (t->field_decl.fcontext);
      WT (t->decl_common.initial);
      break;

    case LABEL_DECL:
      if (streaming_p ())
	{
	  WU (t->label_decl.label_decl_uid);
	  WU (t->label_decl.eh_landing_pad_nr);
	}
      break;

    case FUNCTION_DECL:
      if (streaming_p ())
	{
	  /* Builtins can be streamed by value when a header declares
	     them.  */
	  WU (DECL_BUILT_IN_CLASS (t));
	  if (DECL_BUILT_IN_CLASS (t) != NOT_BUILT_IN)
	    WU (DECL_UNCHECKED_FUNCTION_CODE (t));
	}

      WT (t->function_decl.personality);
      WT (t->function_decl.function_specific_target);
      WT (t->function_decl.function_specific_optimization);
      WT (t->function_decl.vindex);
      break;

    case USING_DECL:
      /* USING_DECL_DECLS  */
      WT (t->decl_common.initial);
      /* FALLTHROUGH  */

    case TYPE_DECL:
      /* USING_DECL: USING_DECL_SCOPE  */
      /* TYPE_DECL: DECL_ORIGINAL_TYPE */
      WT (t->decl_non_common.result);
      break;

      /* Miscellaneous common nodes.  */
    case BLOCK:
      if (state)
	{
	  state->write_location (*this, t->block.locus);
	  state->write_location (*this, t->block.end_locus);
	}

      /* DECL_LOCAL_DECL_P decls are first encountered here and
         streamed by value.  */
      chained_decls (t->block.vars);
      /* nonlocalized_vars is a middle-end thing.  */
      WT (t->block.subblocks);
      WT (t->block.supercontext);
      // FIXME: As for decl's abstract_origin, does this introduce crosslinks?
      WT (t->block.abstract_origin);
      /* fragment_origin, fragment_chain are middle-end things.  */
      WT (t->block.chain);
      /* nonlocalized_vars, block_num & die are middle endy/debug
	 things.  */
      break;

    case CALL_EXPR:
      if (streaming_p ())
	WU (t->base.u.ifn);
      break;

    case CONSTRUCTOR:
      {
	unsigned len = vec_safe_length (t->constructor.elts);
	if (streaming_p ())
	  WU (len);
	if (len)
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      const constructor_elt &elt = (*t->constructor.elts)[ix];

	      WT (elt.index);
	      WT (elt.value);
	    }
      }
      break;

    case OMP_CLAUSE:
      {
	/* The ompcode is serialized in start.  */
	if (streaming_p ())
	  WU (t->omp_clause.subcode.map_kind);
	if (state)
	  state->write_location (*this, t->omp_clause.locus);

	unsigned len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
	for (unsigned ix = 0; ix != len; ix++)
	  WT (t->omp_clause.ops[ix]);
      }
      break;

    case STATEMENT_LIST:
      for (tree_stmt_iterator iter = tsi_start (t);
	   !tsi_end_p (iter); tsi_next (&iter))
	if (tree stmt = tsi_stmt (iter))
	  WT (stmt);
      WT (NULL_TREE);
      break;

    case OPTIMIZATION_NODE:
    case TARGET_OPTION_NODE:
      // FIXME: Our representation for these two nodes is a cache of
      // the resulting set of options.  Not a record of the options
      // that got changed by a particular attribute or pragma.  Should
      // we record that, or should we record the diff from the command
      // line options?  The latter seems the right behaviour, but is
      // (a) harder, and I guess could introduce strangeness if the
      // importer has set some incompatible set of optimization flags?
      gcc_unreachable ();
      break;

    case TREE_BINFO:
      {
	WT (t->binfo.common.chain);
	WT (t->binfo.offset);
	WT (t->binfo.inheritance);
	WT (t->binfo.vptr_field);

	WT (t->binfo.vtable);
	WT (t->binfo.virtuals);
	WT (t->binfo.vtt_subvtt);
	WT (t->binfo.vtt_vptr);

	tree_vec (BINFO_BASE_ACCESSES (t));
	unsigned num = vec_safe_length (BINFO_BASE_ACCESSES (t));
	for (unsigned ix = 0; ix != num; ix++)
	  WT (BINFO_BASE_BINFO (t, ix));
      }
      break;

    case TREE_LIST:
      WT (t->list.purpose);
      WT (t->list.value);
      WT (t->list.common.chain);
      break;

    case TREE_VEC:
      for (unsigned ix = TREE_VEC_LENGTH (t); ix--;)
	WT (TREE_VEC_ELT (t, ix));
      /* We stash NON_DEFAULT_TEMPLATE_ARGS_COUNT on TREE_CHAIN!  */
      gcc_checking_assert (!t->type_common.common.chain
			   || (TREE_CODE (t->type_common.common.chain)
			       == INTEGER_CST));
      WT (t->type_common.common.chain);
      break;

      /* C++-specific nodes ...  */
    case BASELINK:
      WT (((lang_tree_node *)t)->baselink.binfo);
      WT (((lang_tree_node *)t)->baselink.functions);
      WT (((lang_tree_node *)t)->baselink.access_binfo);
      break;

    case CONSTRAINT_INFO:
      WT (((lang_tree_node *)t)->constraint_info.template_reqs);
      WT (((lang_tree_node *)t)->constraint_info.declarator_reqs);
      WT (((lang_tree_node *)t)->constraint_info.associated_constr);
      break;

    case DEFERRED_NOEXCEPT:
      WT (((lang_tree_node *)t)->deferred_noexcept.pattern);
      WT (((lang_tree_node *)t)->deferred_noexcept.args);
      break;

    case LAMBDA_EXPR:
      WT (((lang_tree_node *)t)->lambda_expression.capture_list);
      WT (((lang_tree_node *)t)->lambda_expression.this_capture);
      WT (((lang_tree_node *)t)->lambda_expression.extra_scope);
      /* pending_proxies is a parse-time thing.  */
      gcc_assert (!((lang_tree_node *)t)->lambda_expression.pending_proxies);
      if (state)
	state->write_location
	  (*this, ((lang_tree_node *)t)->lambda_expression.locus);
      if (streaming_p ())
	{
	  WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
	  WU (((lang_tree_node *)t)->lambda_expression.discriminator);
	}
      break;

    case OVERLOAD:
      WT (((lang_tree_node *)t)->overload.function);
      WT (t->common.chain);
      break;
      
    case PTRMEM_CST:
      WT (((lang_tree_node *)t)->ptrmem.member);
      break;

    case STATIC_ASSERT:
      WT (((lang_tree_node *)t)->static_assertion.condition);
      WT (((lang_tree_node *)t)->static_assertion.message);
      if (state)
	state->write_location
	  (*this, ((lang_tree_node *)t)->static_assertion.location);
      break;

    case TEMPLATE_DECL:
      /* Streamed with the template_decl node itself.  */
      gcc_checking_assert
      	(TREE_VISITED (((lang_tree_node *)t)->template_decl.arguments));
      gcc_checking_assert
	(TREE_VISITED (((lang_tree_node *)t)->template_decl.result)
	 || dep_hash->find_dependency (t)->is_alias_tmpl_inst ());
      if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (t))
	WT (DECL_CHAIN (t));
      break;

    case TEMPLATE_INFO:
      {
	WT (((lang_tree_node *)t)->template_info.tmpl);
	WT (((lang_tree_node *)t)->template_info.args);

	const auto *ac = (((lang_tree_node *)t)
			  ->template_info.deferred_access_checks);
	unsigned len = vec_safe_length (ac);
	if (streaming_p ())
	  u (len);
	if (len)
	  {
	    for (unsigned ix = 0; ix != len; ix++)
	      {
		const auto &m = (*ac)[ix];
		WT (m.binfo);
		WT (m.decl);
		WT (m.diag_decl);
		if (state)
		  state->write_location (*this, m.loc);
	      }
	  }
      }
      break;

    case TEMPLATE_PARM_INDEX:
      if (streaming_p ())
	{
	  WU (((lang_tree_node *)t)->tpi.index);
	  WU (((lang_tree_node *)t)->tpi.level);
	  WU (((lang_tree_node *)t)->tpi.orig_level);
	}
      WT (((lang_tree_node *)t)->tpi.decl);
      /* TEMPLATE_PARM_DESCENDANTS (AKA TREE_CHAIN) is an internal
	 cache, do not stream.  */
      break;
      
    case TRAIT_EXPR:
      WT (((lang_tree_node *)t)->trait_expression.type1);
      WT (((lang_tree_node *)t)->trait_expression.type2);
      if (streaming_p ())
	WU (((lang_tree_node *)t)->trait_expression.kind);
      break;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
    {
      /* We want to stream the type of a expression-like nodes /after/
         we've streamed the operands.  The type often contains (bits
         of the) types of the operands, and with things like decltype
         and noexcept in play, we really want to stream the decls
         defining the type before we try and stream the type on its
         own.  Otherwise we can find ourselves trying to read in a
         decl, when we're already partially reading in a component of
         its type.  And that's bad.  */
      tree type = t->typed.type;
      unsigned prec = 0;

      switch (code)
	{
	default:
	  break;

	case TEMPLATE_DECL:
	  /* We fill in the template's type separately.  */
	  type = NULL_TREE;
	  break;

	case TYPE_DECL:
	  if (DECL_ORIGINAL_TYPE (t) && t == TYPE_NAME (type))
	    /* This is a typedef.  We set its type separately.  */
	    type = NULL_TREE;
	  break;

	case ENUMERAL_TYPE:
	  if (type && !ENUM_FIXED_UNDERLYING_TYPE_P (t))
	    {
	      /* Type is a restricted range integer type derived from the
		 integer_types.  Find the right one.  */
	      prec = TYPE_PRECISION (type);
	      tree name = DECL_NAME (TYPE_NAME (type));

	      for (unsigned itk = itk_none; itk--;)
		if (integer_types[itk]
		    && DECL_NAME (TYPE_NAME (integer_types[itk])) == name)
		  {
		    type = integer_types[itk];
		    break;
		  }
	      gcc_assert (type != t->typed.type);
	    }
	  break;
	}

      WT (type);
      if (prec && streaming_p ())
	WU (prec);
    }

#undef WT
#undef WU
}

// Streaming in a reference to a decl can cause that decl to be
// TREE_USED, which is the mark_used behaviour we need most of the
// time.  The trees_in::unused can be incremented to inhibit this,
// which is at least needed for vtables.

bool
trees_in::core_vals (tree t)
{
#define RU(X) ((X) = u ())
#define RUC(T,X) ((X) = T (u ()))
#define RT(X) ((X) = tree_node ())
#define RTU(X) ((X) = tree_node (true))
  tree_code code = TREE_CODE (t);

  /* First by tree shape.  */
  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
    {
      RT (t->decl_minimal.name);
      if (!DECL_TEMPLATE_PARM_P (t))
	RT (t->decl_minimal.context);

      /* Don't zap the locus just yet, we don't record it correctly
	 and thus lose all location information.  */
      t->decl_minimal.locus = state->read_location (*this);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      RT (t->type_common.name);
      RT (t->type_common.context);

      RT (t->type_common.main_variant);
      RT (t->type_common.canonical);

      /* type_common.next_variant is internally manipulated.  */
      /* type_common.pointer_to, type_common.reference_to.  */

      RU (t->type_common.precision);
      RU (t->type_common.contains_placeholder_bits);
      RUC (machine_mode, t->type_common.mode);
      RU (t->type_common.align);

      if (!RECORD_OR_UNION_CODE_P (code))
	{
	  RT (t->type_common.size);
	  RT (t->type_common.size_unit);
	}
      RT (t->type_common.attributes);

      RT (t->type_common.common.chain); /* TYPE_STUB_DECL.  */
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      RUC (machine_mode, t->decl_common.mode);
      RU (t->decl_common.off_align);
      RU (t->decl_common.align);

      if (code != TEMPLATE_DECL)
	{
	  RT (t->decl_common.size);
	  RT (t->decl_common.size_unit);
	}

      RT (t->decl_common.attributes);
      RT (t->decl_common.abstract_origin);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      RT (t->decl_with_vis.assembler_name);
      RUC (symbol_visibility, t->decl_with_vis.visibility);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
    {
      /* Records and unions hold FIELDS, VFIELD & BINFO on these
	 things.  */
      if (!RECORD_OR_UNION_CODE_P (code) && code != ENUMERAL_TYPE)
	{
	  /* This is not clobbering TYPE_CACHED_VALUES, because this
	     is a type that doesn't have any.  */
	  gcc_checking_assert (!TYPE_CACHED_VALUES_P (t));
	  RT (t->type_non_common.values);
	  RT (t->type_non_common.maxval);
	  RT (t->type_non_common.minval);
	}

      RT (t->type_non_common.lang_1);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
    {
      t->exp.locus = state->read_location (*this);

      bool vl = TREE_CODE_CLASS (code) == tcc_vl_exp;
      for (unsigned limit = (vl ? VL_EXP_OPERAND_LENGTH (t)
			     : TREE_OPERAND_LENGTH (t)),
	     ix = unsigned (vl); ix != limit; ix++)
	RTU (TREE_OPERAND (t, ix));
    }

  /* Then by CODE.  Special cases and/or 1:1 tree shape
     correspondance. */
  switch (code)
    {
    default:
      break;

    case ARGUMENT_PACK_SELECT:
    case DEFERRED_PARSE:
    case IDENTIFIER_NODE:
    case BINDING_VECTOR:
    case SSA_NAME:
    case TRANSLATION_UNIT_DECL:
    case USERDEF_LITERAL:
      return false; /* Should never meet.  */

      /* Constants.  */
    case COMPLEX_CST:
      RT (TREE_REALPART (t));
      RT (TREE_IMAGPART (t));
      break;

    case FIXED_CST:
      /* Not suported in C++.  */
      return false;

    case INTEGER_CST:
      {
	unsigned num = TREE_INT_CST_EXT_NUNITS (t);
	for (unsigned ix = 0; ix != num; ix++)
	  TREE_INT_CST_ELT (t, ix) = wu ();
      }
      break;

    case POLY_INT_CST:
      /* Not suported in C++.  */
      return false;

    case REAL_CST:
      if (const void *bytes = buf (sizeof (real_value)))
	TREE_REAL_CST_PTR (t)
	  = reinterpret_cast<real_value *> (memcpy (ggc_alloc<real_value> (),
						    bytes, sizeof (real_value)));
      break;

    case STRING_CST:
      /* Streamed during start.  */
      break;

    case VECTOR_CST:
      for (unsigned ix = vector_cst_encoded_nelts (t); ix--;)
	RT (VECTOR_CST_ENCODED_ELT (t, ix));
      break;

      /* Decls.  */
    case VAR_DECL:
      if (DECL_CONTEXT (t)
	  && TREE_CODE (DECL_CONTEXT (t)) != FUNCTION_DECL)
	break;
      /* FALLTHROUGH  */

    case RESULT_DECL:
    case PARM_DECL:
      if (DECL_HAS_VALUE_EXPR_P (t))
	{
	  /* The DECL_VALUE hash table is a cache, thus if we're
	     reading a duplicate (which we end up discarding), the
	     value expr will also be cleaned up at the next gc.  */
	  tree val = tree_node ();
	  SET_DECL_VALUE_EXPR (t, val);
	}
      /* FALLTHROUGH  */

    case CONST_DECL:
    case IMPORTED_DECL:
      RT (t->decl_common.initial);
      break;

    case FIELD_DECL:
      RT (t->field_decl.offset);
      RT (t->field_decl.bit_field_type);
      RT (t->field_decl.qualifier);
      RT (t->field_decl.bit_offset);
      RT (t->field_decl.fcontext);
      RT (t->decl_common.initial);
      break;

    case LABEL_DECL:
      RU (t->label_decl.label_decl_uid);
      RU (t->label_decl.eh_landing_pad_nr);
      break;
  
    case FUNCTION_DECL:
      {
	unsigned bltin = u ();
	t->function_decl.built_in_class = built_in_class (bltin);
	if (bltin != NOT_BUILT_IN)
	  {
	    bltin = u ();
	    DECL_UNCHECKED_FUNCTION_CODE (t) = built_in_function (bltin);
	  }

	RT (t->function_decl.personality);
	RT (t->function_decl.function_specific_target);
	RT (t->function_decl.function_specific_optimization);
	RT (t->function_decl.vindex);
      }
      break;

    case USING_DECL:
      /* USING_DECL_DECLS  */
      RT (t->decl_common.initial);
      /* FALLTHROUGH  */

    case TYPE_DECL:
      /* USING_DECL: USING_DECL_SCOPE  */
      /* TYPE_DECL: DECL_ORIGINAL_TYPE */
      RT (t->decl_non_common.result);
      break;

      /* Miscellaneous common nodes.  */
    case BLOCK:
      t->block.locus = state->read_location (*this);
      t->block.end_locus = state->read_location (*this);
      t->block.vars = chained_decls ();
      /* nonlocalized_vars is middle-end.  */
      RT (t->block.subblocks);
      RT (t->block.supercontext);
      RT (t->block.abstract_origin);
      /* fragment_origin, fragment_chain are middle-end.  */
      RT (t->block.chain);
      /* nonlocalized_vars, block_num, die are middle endy/debug
	 things.  */
      break;

    case CALL_EXPR:
      RUC (internal_fn, t->base.u.ifn);
      break;

    case CONSTRUCTOR:
      if (unsigned len = u ())
	{
	  vec_alloc (t->constructor.elts, len);
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      constructor_elt elt;

	      RT (elt.index);
	      RTU (elt.value);
	      t->constructor.elts->quick_push (elt);
	    }
	}
      break;

    case OMP_CLAUSE:
      {
	RU (t->omp_clause.subcode.map_kind);
	t->omp_clause.locus = state->read_location (*this);

	unsigned len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
	for (unsigned ix = 0; ix != len; ix++)
	  RT (t->omp_clause.ops[ix]);
      }
      break;

    case STATEMENT_LIST:
      {
	tree_stmt_iterator iter = tsi_start (t);
	for (tree stmt; RT (stmt);)
	  tsi_link_after (&iter, stmt, TSI_CONTINUE_LINKING);
      }
      break;

    case OPTIMIZATION_NODE:
    case TARGET_OPTION_NODE:
      /* Not yet implemented, see trees_out::core_vals.  */
      gcc_unreachable ();
      break;

    case TREE_BINFO:
      RT (t->binfo.common.chain);
      RT (t->binfo.offset);
      RT (t->binfo.inheritance);
      RT (t->binfo.vptr_field);

      /* Do not mark the vtables as USED in the address expressions
	 here.  */
      unused++;
      RT (t->binfo.vtable);
      RT (t->binfo.virtuals);
      RT (t->binfo.vtt_subvtt);
      RT (t->binfo.vtt_vptr);
      unused--;

      BINFO_BASE_ACCESSES (t) = tree_vec ();
      if (!get_overrun ())
	{
	  unsigned num = vec_safe_length (BINFO_BASE_ACCESSES (t));
	  for (unsigned ix = 0; ix != num; ix++)
	    BINFO_BASE_APPEND (t, tree_node ());
	}
      break;

    case TREE_LIST:
      RT (t->list.purpose);
      RT (t->list.value);
      RT (t->list.common.chain);
      break;

    case TREE_VEC:
      for (unsigned ix = TREE_VEC_LENGTH (t); ix--;)
	RT (TREE_VEC_ELT (t, ix));
      RT (t->type_common.common.chain);
      break;

      /* C++-specific nodes ...  */
    case BASELINK:
      RT (((lang_tree_node *)t)->baselink.binfo);
      RTU (((lang_tree_node *)t)->baselink.functions);
      RT (((lang_tree_node *)t)->baselink.access_binfo);
      break;

    case CONSTRAINT_INFO:
      RT (((lang_tree_node *)t)->constraint_info.template_reqs);
      RT (((lang_tree_node *)t)->constraint_info.declarator_reqs);
      RT (((lang_tree_node *)t)->constraint_info.associated_constr);
      break;

    case DEFERRED_NOEXCEPT:
      RT (((lang_tree_node *)t)->deferred_noexcept.pattern);
      RT (((lang_tree_node *)t)->deferred_noexcept.args);
      break;

    case LAMBDA_EXPR:
      RT (((lang_tree_node *)t)->lambda_expression.capture_list);
      RT (((lang_tree_node *)t)->lambda_expression.this_capture);
      RT (((lang_tree_node *)t)->lambda_expression.extra_scope);
      /* lambda_expression.pending_proxies is NULL  */
      ((lang_tree_node *)t)->lambda_expression.locus
	= state->read_location (*this);
      RUC (cp_lambda_default_capture_mode_type,
	   ((lang_tree_node *)t)->lambda_expression.default_capture_mode);
      RU (((lang_tree_node *)t)->lambda_expression.discriminator);
      break;

    case OVERLOAD:
      RT (((lang_tree_node *)t)->overload.function);
      RT (t->common.chain);
      break;

    case PTRMEM_CST:
      RT (((lang_tree_node *)t)->ptrmem.member);
      break;

    case STATIC_ASSERT:
      RT (((lang_tree_node *)t)->static_assertion.condition);
      RT (((lang_tree_node *)t)->static_assertion.message);
      ((lang_tree_node *)t)->static_assertion.location
	= state->read_location (*this);
      break;

    case TEMPLATE_DECL:
      /* Streamed when reading the raw template decl itself.  */
      gcc_assert (((lang_tree_node *)t)->template_decl.arguments);
      gcc_assert (((lang_tree_node *)t)->template_decl.result);
      if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (t))
	RT (DECL_CHAIN (t));
      break;

    case TEMPLATE_INFO:
      RT (((lang_tree_node *)t)->template_info.tmpl);
      RT (((lang_tree_node *)t)->template_info.args);
      if (unsigned len = u ())
	{
	  auto &ac = (((lang_tree_node *)t)
		      ->template_info.deferred_access_checks);
	  vec_alloc (ac, len);
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      deferred_access_check m;

	      RT (m.binfo);
	      RT (m.decl);
	      RT (m.diag_decl);
	      m.loc = state->read_location (*this);
	      ac->quick_push (m);
	    }
	}
      break;

    case TEMPLATE_PARM_INDEX:
      RU (((lang_tree_node *)t)->tpi.index);
      RU (((lang_tree_node *)t)->tpi.level);
      RU (((lang_tree_node *)t)->tpi.orig_level);
      RT (((lang_tree_node *)t)->tpi.decl);
      break;

    case TRAIT_EXPR:
      RT (((lang_tree_node *)t)->trait_expression.type1);
      RT (((lang_tree_node *)t)->trait_expression.type2);
      RUC (cp_trait_kind, ((lang_tree_node *)t)->trait_expression.kind);
      break;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
    {
      tree type = tree_node ();

      if (type && code == ENUMERAL_TYPE && !ENUM_FIXED_UNDERLYING_TYPE_P (t))
	{
	  unsigned precision = u ();

	  type = build_distinct_type_copy (type);
	  TYPE_PRECISION (type) = precision;
	  set_min_and_max_values_for_integral_type (type, precision,
						    TYPE_SIGN (type));
	}

      if (code != TEMPLATE_DECL)
	t->typed.type = type;
    }

#undef RT
#undef RM
#undef RU
  return !get_overrun ();
}

void
trees_out::lang_decl_vals (tree t)
{
  const struct lang_decl *lang = DECL_LANG_SPECIFIC (t);
#define WU(X) (u (X))
#define WT(X) (tree_node (X))
  /* Module index already written.  */
  switch (lang->u.base.selector)
    {
    default:
      gcc_unreachable ();

    case lds_fn:  /* lang_decl_fn.  */
      if (streaming_p ())
	{
	  if (DECL_NAME (t) && IDENTIFIER_OVL_OP_P (DECL_NAME (t)))
	    WU (lang->u.fn.ovl_op_code);
	}

      if (DECL_CLASS_SCOPE_P (t))
	WT (lang->u.fn.context);

      if (lang->u.fn.thunk_p)
	{
	  /* The thunked-to function.  */
	  WT (lang->u.fn.befriending_classes);
	  if (streaming_p ())
	    wi (lang->u.fn.u5.fixed_offset);
	}
      else
	WT (lang->u.fn.u5.cloned_function);

      if (FNDECL_USED_AUTO (t))
	WT (lang->u.fn.u.saved_auto_return_type);

      goto lds_min;

    case lds_decomp:  /* lang_decl_decomp.  */
      WT (lang->u.decomp.base);
      goto lds_min;

    case lds_min:  /* lang_decl_min.  */
    lds_min:
      WT (lang->u.min.template_info);
      {
	tree access = lang->u.min.access;

	/* DECL_ACCESS needs to be maintained by the definition of the
	   (derived) class that changes the access.  The other users
	   of DECL_ACCESS need to write it here.  */
	if (!DECL_THUNK_P (t)
	    && (DECL_CONTEXT (t) && TYPE_P (DECL_CONTEXT (t))))
	  access = NULL_TREE;

	WT (access);
      }
      break;

    case lds_ns:  /* lang_decl_ns.  */
      break;

    case lds_parm:  /* lang_decl_parm.  */
      if (streaming_p ())
	{
	  WU (lang->u.parm.level);
	  WU (lang->u.parm.index);
	}
      break;
    }
#undef WU
#undef WT
}

bool
trees_in::lang_decl_vals (tree t)
{
  struct lang_decl *lang = DECL_LANG_SPECIFIC (t);
#define RU(X) ((X) = u ())
#define RT(X) ((X) = tree_node ())

  /* Module index already read.  */
  switch (lang->u.base.selector)
    {
    default:
      gcc_unreachable ();

    case lds_fn:  /* lang_decl_fn.  */
      if (DECL_NAME (t) && IDENTIFIER_OVL_OP_P (DECL_NAME (t)))
	{
	  unsigned code = u ();

	  /* Check consistency.  */
	  if (code >= OVL_OP_MAX
	      || (ovl_op_info[IDENTIFIER_ASSIGN_OP_P (DECL_NAME (t))][code]
		  .ovl_op_code) == OVL_OP_ERROR_MARK)
	    set_overrun ();
	  else
	    lang->u.fn.ovl_op_code = code;
	}

      if (DECL_CLASS_SCOPE_P (t))
	RT (lang->u.fn.context);

      if (lang->u.fn.thunk_p)
	{
	  RT (lang->u.fn.befriending_classes);
	  lang->u.fn.u5.fixed_offset = wi ();
	}
      else
	RT (lang->u.fn.u5.cloned_function);

      if (FNDECL_USED_AUTO (t))
	RT (lang->u.fn.u.saved_auto_return_type);
      goto lds_min;

    case lds_decomp:  /* lang_decl_decomp.  */
      RT (lang->u.decomp.base);
      goto lds_min;

    case lds_min:  /* lang_decl_min.  */
    lds_min:
      RT (lang->u.min.template_info);
      RT (lang->u.min.access);
      break;

    case lds_ns:  /* lang_decl_ns.  */
      break;

    case lds_parm:  /* lang_decl_parm.  */
      RU (lang->u.parm.level);
      RU (lang->u.parm.index);
      break;
    }
#undef RU
#undef RT
  return !get_overrun ();
}

/* Most of the value contents of lang_type is streamed in
   define_class.  */

void
trees_out::lang_type_vals (tree t)
{
  const struct lang_type *lang = TYPE_LANG_SPECIFIC (t);
#define WU(X) (u (X))
#define WT(X) (tree_node (X))
  if (streaming_p ())
    WU (lang->align);
#undef WU
#undef WT
}

bool
trees_in::lang_type_vals (tree t)
{
  struct lang_type *lang = TYPE_LANG_SPECIFIC (t);
#define RU(X) ((X) = u ())
#define RT(X) ((X) = tree_node ())
  RU (lang->align);
#undef RU
#undef RT
  return !get_overrun ();
}

/* Write out the bools of T, including information about any
   LANG_SPECIFIC information.  Including allocation of any lang
   specific object.  */

void
trees_out::tree_node_bools (tree t)
{
  gcc_checking_assert (streaming_p ());

  /* We should never stream a namespace.  */
  gcc_checking_assert (TREE_CODE (t) != NAMESPACE_DECL
		       || DECL_NAMESPACE_ALIAS (t));

  core_bools (t);

  switch (TREE_CODE_CLASS (TREE_CODE (t)))
    {
    case tcc_declaration:
      {
	bool specific = DECL_LANG_SPECIFIC (t) != NULL;
	b (specific);
	if (specific && VAR_P (t))
	  b (DECL_DECOMPOSITION_P (t));
	if (specific)
	  lang_decl_bools (t);
      }
      break;

    case tcc_type:
      {
	bool specific = (TYPE_MAIN_VARIANT (t) == t
			 && TYPE_LANG_SPECIFIC (t) != NULL);
	gcc_assert (TYPE_LANG_SPECIFIC (t)
		    == TYPE_LANG_SPECIFIC (TYPE_MAIN_VARIANT (t)));

	b (specific);
	if (specific)
	  lang_type_bools (t);
      }
      break;

    default:
      break;
    }

  bflush ();
}

bool
trees_in::tree_node_bools (tree t)
{
  bool ok = core_bools (t);

  if (ok)
    switch (TREE_CODE_CLASS (TREE_CODE (t)))
      {
      case tcc_declaration:
	if (b ())
	  {
	    bool decomp = VAR_P (t) && b ();

	    ok = maybe_add_lang_decl_raw (t, decomp);
	    if (ok)
	      ok = lang_decl_bools (t);
	}
	break;

      case tcc_type:
	if (b ())
	  {
	    ok = maybe_add_lang_type_raw (t);
	    if (ok)
	      ok = lang_type_bools (t);
	  }
	break;

      default:
	break;
      }

  bflush ();
  if (!ok || get_overrun ())
    return false;

  return true;
}


/* Write out the lang-specifc vals of node T.  */

void
trees_out::lang_vals (tree t)
{
  switch (TREE_CODE_CLASS (TREE_CODE (t)))
    {
    case tcc_declaration:
      if (DECL_LANG_SPECIFIC (t))
	lang_decl_vals (t);
      break;

    case tcc_type:
      if (TYPE_MAIN_VARIANT (t) == t && TYPE_LANG_SPECIFIC (t))
	lang_type_vals (t);
      break;

    default:
      break;
    }
}

bool
trees_in::lang_vals (tree t)
{
  bool ok = true;

  switch (TREE_CODE_CLASS (TREE_CODE (t)))
    {
    case tcc_declaration:
      if (DECL_LANG_SPECIFIC (t))
	ok = lang_decl_vals (t);
      break;

    case tcc_type:
      if (TYPE_LANG_SPECIFIC (t))
	ok = lang_type_vals (t);
      else
	TYPE_LANG_SPECIFIC (t) = TYPE_LANG_SPECIFIC (TYPE_MAIN_VARIANT (t));
      break;

    default:
      break;
    }

  return ok;
}

/* Write out the value fields of node T.  */

void
trees_out::tree_node_vals (tree t)
{
  core_vals (t);
  lang_vals (t);
}

bool
trees_in::tree_node_vals (tree t)
{
  bool ok = core_vals (t);
  if (ok)
    ok = lang_vals (t);

  return ok;
}


/* If T is a back reference, fixed reference or NULL, write out it's
   code and return WK_none.  Otherwise return WK_value if we must write
   by value, or WK_normal otherwise.  */

walk_kind
trees_out::ref_node (tree t)
{
  if (!t)
    {
      if (streaming_p ())
	{
	  /* NULL_TREE -> tt_null.  */
	  null_count++;
	  i (tt_null);
	}
      return WK_none;
    }

  if (!TREE_VISITED (t))
    return WK_normal;

  /* An already-visited tree.  It must be in the map.  */
  int val = get_tag (t);

  if (val == tag_value)
    /* An entry we should walk into.  */
    return WK_value;

  const char *kind;

  if (val <= tag_backref)
    {
      /* Back reference -> -ve number  */
      if (streaming_p ())
	i (val);
      kind = "backref";
    }
  else if (val >= tag_fixed)
    {
      /* Fixed reference -> tt_fixed */
      val -= tag_fixed;
      if (streaming_p ())
	i (tt_fixed), u (val);
      kind = "fixed";
    }

  if (streaming_p ())
    {
      back_ref_count++;
      dump (dumper::TREE)
	&& dump ("Wrote %s:%d %C:%N%S", kind, val, TREE_CODE (t), t, t);
    }
  return WK_none;
}

tree
trees_in::back_ref (int tag)
{
  tree res = NULL_TREE;

  if (tag < 0 && unsigned (~tag) < back_refs.length ())
    res = back_refs[~tag];

  if (!res
      /* Checking TREE_CODE is a dereference, so we know this is not a
	 wild pointer.  Checking the code provides evidence we've not
	 corrupted something.  */
      || TREE_CODE (res) >= MAX_TREE_CODES)
    set_overrun ();
  else
    dump (dumper::TREE) && dump ("Read backref:%d found %C:%N%S", tag,
				 TREE_CODE (res), res, res);
  return res;
}

unsigned
trees_out::add_indirect_tpl_parms (tree parms)
{
  unsigned len = 0;
  for (; parms; parms = TREE_CHAIN (parms), len++)
    {
      if (TREE_VISITED (parms))
	break;

      int tag = insert (parms);
      if (streaming_p ())
	dump (dumper::TREE)
	  && dump ("Indirect:%d template's parameter %u %C:%N",
		   tag, len, TREE_CODE (parms), parms);
    }

  if (streaming_p ())
    u (len);

  return len;
}

unsigned
trees_in::add_indirect_tpl_parms (tree parms)
{
  unsigned len = u ();
  for (unsigned ix = 0; ix != len; parms = TREE_CHAIN (parms), ix++)
    {
      int tag = insert (parms);
      dump (dumper::TREE)
	&& dump ("Indirect:%d template's parameter %u %C:%N",
		 tag, ix, TREE_CODE (parms), parms);
    }

  return len;
}

/* We've just found DECL by name.  Insert nodes that come with it, but
   cannot be found by name, so we'll not accidentally walk into them.  */

void
trees_out::add_indirects (tree decl)
{
  unsigned count = 0;

  // FIXME:OPTIMIZATION We'll eventually want default fn parms of
  // templates and perhaps default template parms too.  The former can
  // be referenced from instantiations (as they are lazily
  // instantiated).  Also (deferred?) exception specifications of
  // templates.  See the note about PARM_DECLs in trees_out::decl_node.
  tree inner = decl;
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      count += add_indirect_tpl_parms (DECL_TEMPLATE_PARMS (decl));

      inner = DECL_TEMPLATE_RESULT (decl);
      int tag = insert (inner);
      if (streaming_p ())
	dump (dumper::TREE)
	  && dump ("Indirect:%d template's result %C:%N",
		   tag, TREE_CODE (inner), inner);
      count++;
    }

  if (TREE_CODE (inner) == TYPE_DECL)
    {
      /* Make sure the type is in the map too.  Otherwise we get
	 different RECORD_TYPEs for the same type, and things go
	 south.  */
      tree type = TREE_TYPE (inner);
      gcc_checking_assert (DECL_ORIGINAL_TYPE (inner)
			   || TYPE_NAME (type) == inner);
      int tag = insert (type);
      if (streaming_p ())
	dump (dumper::TREE) && dump ("Indirect:%d decl's type %C:%N", tag,
				     TREE_CODE (type), type);
      count++;
    }

  if (streaming_p ())
    {
      u (count);
      dump (dumper::TREE) && dump ("Inserted %u indirects", count);
    }
}

bool
trees_in::add_indirects (tree decl)
{
  unsigned count = 0;
	    
  tree inner = decl;
  if (TREE_CODE (inner) == TEMPLATE_DECL)
    {
      count += add_indirect_tpl_parms (DECL_TEMPLATE_PARMS (decl));

      inner = DECL_TEMPLATE_RESULT (decl);
      int tag = insert (inner);
      dump (dumper::TREE)
	&& dump ("Indirect:%d templates's result %C:%N", tag,
		 TREE_CODE (inner), inner);
      count++;
    }

  if (TREE_CODE (inner) == TYPE_DECL)
    {
      tree type = TREE_TYPE (inner);
      gcc_checking_assert (DECL_ORIGINAL_TYPE (inner)
			   || TYPE_NAME (type) == inner);
      int tag = insert (type);
      dump (dumper::TREE)
	&& dump ("Indirect:%d decl's type %C:%N", tag, TREE_CODE (type), type);
      count++;
    }

  dump (dumper::TREE) && dump ("Inserted %u indirects", count);
  return count == u ();
}

/* Stream a template parameter.  There are 4.5 kinds of parameter:
   a) Template - TEMPLATE_DECL->TYPE_DECL->TEMPLATE_TEMPLATE_PARM
   	TEMPLATE_TYPE_PARM_INDEX TPI
   b) Type - TYPE_DECL->TEMPLATE_TYPE_PARM TEMPLATE_TYPE_PARM_INDEX TPI
   c.1) NonTYPE - PARM_DECL DECL_INITIAL TPI We meet this first
   c.2) NonTYPE - CONST_DECL DECL_INITIAL Same TPI
   d) BoundTemplate - TYPE_DECL->BOUND_TEMPLATE_TEMPLATE_PARM
       TEMPLATE_TYPE_PARM_INDEX->TPI
       TEMPLATE_TEMPLATE_PARM_INFO->TEMPLATE_INFO

   All of these point to a TEMPLATE_PARM_INDEX, and #B also has a TEMPLATE_INFO
*/

void
trees_out::tpl_parm_value (tree parm)
{
  gcc_checking_assert (DECL_P (parm) && DECL_TEMPLATE_PARM_P (parm));

  int parm_tag = insert (parm);
  if (streaming_p ())
    {
      i (tt_tpl_parm);
      dump (dumper::TREE) && dump ("Writing template parm:%d %C:%N",
				   parm_tag, TREE_CODE (parm), parm);
      start (parm);
      tree_node_bools (parm);
    }

  tree inner = parm;
  if (TREE_CODE (inner) == TEMPLATE_DECL)
    {
      inner = DECL_TEMPLATE_RESULT (inner);
      int inner_tag = insert (inner);
      if (streaming_p ())
	{
	  dump (dumper::TREE) && dump ("Writing inner template parm:%d %C:%N",
				       inner_tag, TREE_CODE (inner), inner);
	  start (inner);
	  tree_node_bools (inner);
	}
    }

  tree type = NULL_TREE;
  if (TREE_CODE (inner) == TYPE_DECL)
    {
      type = TREE_TYPE (inner);
      int type_tag = insert (type);
      if (streaming_p ())
	{
	  dump (dumper::TREE) && dump ("Writing template parm type:%d %C:%N",
				       type_tag, TREE_CODE (type), type);
	  start (type);
	  tree_node_bools (type);
	}
    }

  if (inner != parm)
    {
      /* This is a template-template parameter.  */
      unsigned tpl_levels = 0;
      tpl_header (parm, &tpl_levels);
      tpl_parms_fini (parm, tpl_levels);
    }

  tree_node_vals (parm);
  if (inner != parm)
    tree_node_vals (inner);
  if (type)
    {
      tree_node_vals (type);
      if (DECL_NAME (inner) == auto_identifier
	  || DECL_NAME (inner) == decltype_auto_identifier)
	{
	  /* Placeholder auto.  */
	  tree_node (DECL_INITIAL (inner));
	  tree_node (DECL_SIZE_UNIT (inner));
	}
    }

  if (streaming_p ())
    dump (dumper::TREE) && dump ("Wrote template parm:%d %C:%N",
				 parm_tag, TREE_CODE (parm), parm);
}

tree
trees_in::tpl_parm_value ()
{
  tree parm = start ();
  if (!parm || !tree_node_bools (parm))
    return NULL_TREE;

  int parm_tag = insert (parm);
  dump (dumper::TREE) && dump ("Reading template parm:%d %C:%N",
			       parm_tag, TREE_CODE (parm), parm);

  tree inner = parm;
  if (TREE_CODE (inner) == TEMPLATE_DECL)
    {
      inner = start ();
      if (!inner || !tree_node_bools (inner))
	return NULL_TREE;
      int inner_tag = insert (inner);
      dump (dumper::TREE) && dump ("Reading inner template parm:%d %C:%N",
				   inner_tag, TREE_CODE (inner), inner);
      DECL_TEMPLATE_RESULT (parm) = inner;
    }

  tree type = NULL_TREE;
  if (TREE_CODE (inner) == TYPE_DECL)
    {
      type = start ();
      if (!type || !tree_node_bools (type))
	return NULL_TREE;
      int type_tag = insert (type);
      dump (dumper::TREE) && dump ("Reading template parm type:%d %C:%N",
				   type_tag, TREE_CODE (type), type);

      TREE_TYPE (inner) = TREE_TYPE (parm) = type;
      TYPE_NAME (type) = parm;
    }

  if (inner != parm)
    {
      /* A template template parameter.  */
      unsigned tpl_levels = 0;
      tpl_header (parm, &tpl_levels);
      tpl_parms_fini (parm, tpl_levels);
    }

  tree_node_vals (parm);
  if (inner != parm)
    tree_node_vals (inner);
  if (type)
    {
      tree_node_vals (type);
      if (DECL_NAME (inner) == auto_identifier
	  || DECL_NAME (inner) == decltype_auto_identifier)
	{
	  /* Placeholder auto.  */
	  DECL_INITIAL (inner) = tree_node ();
	  DECL_SIZE_UNIT (inner) = tree_node ();
	}
      if (TYPE_CANONICAL (type))
	{
	  gcc_checking_assert (TYPE_CANONICAL (type) == type);
	  TYPE_CANONICAL (type) = canonical_type_parameter (type);
	}
    }

  dump (dumper::TREE) && dump ("Read template parm:%d %C:%N",
			       parm_tag, TREE_CODE (parm), parm);

  return parm;
}

void
trees_out::install_entity (tree decl, depset *dep)
{
  gcc_checking_assert (streaming_p ());
  
  /* Write the entity index, so we can insert it as soon as we
     know this is new.  */
  u (dep ? dep->cluster + 1 : 0);
  if (CHECKING_P && dep)
    {
      /* Add it to the entity map, such that we can tell it is
	 part of us.  */
      bool existed;
      unsigned *slot = &entity_map->get_or_insert
	(DECL_UID (decl), &existed);
      if (existed)
	/* If it existed, it should match.  */
	gcc_checking_assert (decl == (*entity_ary)[*slot]);
      *slot = ~dep->cluster;
    }
}

bool
trees_in::install_entity (tree decl)
{
  unsigned entity_index = u ();
  if (!entity_index)
    return false;

  if (entity_index > state->entity_num)
    {
      set_overrun ();
      return false;
    }

  /* Insert the real decl into the entity ary.  */
  unsigned ident = state->entity_lwm + entity_index - 1;
  (*entity_ary)[ident] = decl;

  /* And into the entity map, if it's not already there.  */
  tree not_tmpl = STRIP_TEMPLATE (decl);
  if (!DECL_LANG_SPECIFIC (not_tmpl)
      || !DECL_MODULE_ENTITY_P (not_tmpl))
    {
      retrofit_lang_decl (not_tmpl);
      DECL_MODULE_ENTITY_P (not_tmpl) = true;

      /* Insert into the entity hash (it cannot already be there).  */
      bool existed;
      unsigned &slot = entity_map->get_or_insert (DECL_UID (decl), &existed);
      gcc_checking_assert (!existed);
      slot = ident;
    }

  return true;
}

static bool has_definition (tree decl);

/* DECL is a decl node that must be written by value.  DEP is the
   decl's depset.  */

void
trees_out::decl_value (tree decl, depset *dep)
{
  /* We should not be writing clones or template parms.  */
  gcc_checking_assert (DECL_P (decl)
		       && !DECL_CLONED_FUNCTION_P (decl)
		       && !DECL_TEMPLATE_PARM_P (decl));

  /* We should never be writing non-typedef ptrmemfuncs by value.  */
  gcc_checking_assert (TREE_CODE (decl) != TYPE_DECL
		       || DECL_ORIGINAL_TYPE (decl)
		       || !TYPE_PTRMEMFUNC_P (TREE_TYPE (decl)));

  merge_kind mk = get_merge_kind (decl, dep);

  if (CHECKING_P)
    {
      /* Never start in the middle of a template.  */
      int use_tpl = -1;
      if (tree ti = node_template_info (decl, use_tpl))
	gcc_checking_assert (TREE_CODE (TI_TEMPLATE (ti)) == OVERLOAD
			     || TREE_CODE (TI_TEMPLATE (ti)) == FIELD_DECL
			     || (DECL_TEMPLATE_RESULT (TI_TEMPLATE (ti))
				 != decl));
    }

  if (streaming_p ())
    {
      /* A new node -> tt_decl.  */
      decl_val_count++;
      i (tt_decl);
      u (mk);
      start (decl);

      if (mk != MK_unique)
	{
	  if (!(mk & MK_template_mask) && !state->is_header ())
	    {
	      /* Tell the importer whether this is a global module entity,
		 or a module entity.  This bool merges into the next block
		 of bools.  Sneaky.  */
	      tree o = get_originating_module_decl (decl);
	      bool is_mod = false;

	      tree not_tmpl = STRIP_TEMPLATE (o);
	      if (DECL_LANG_SPECIFIC (not_tmpl)
		  && DECL_MODULE_PURVIEW_P (not_tmpl))
		is_mod = true;

	      b (is_mod);
	    }
	  b (dep && dep->has_defn ());
	}
      tree_node_bools (decl);
    }

  int tag = insert (decl, WK_value);
  if (streaming_p ())
    dump (dumper::TREE)
      && dump ("Writing %s:%d %C:%N%S", merge_kind_name[mk], tag,
	       TREE_CODE (decl), decl, decl);

  tree inner = decl;
  int inner_tag = 0;
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      inner = DECL_TEMPLATE_RESULT (decl);
      inner_tag = insert (inner, WK_value);

      if (streaming_p ())
	{
	  int code = TREE_CODE (inner);
	  u (code);
	  start (inner, true);
	  tree_node_bools (inner);
	  dump (dumper::TREE)
	    && dump ("Writing %s:%d %C:%N%S", merge_kind_name[mk], inner_tag,
		     TREE_CODE (inner), inner, inner);
	}
    }

  tree type = NULL_TREE;
  int type_tag = 0;
  tree stub_decl = NULL_TREE;
  int stub_tag = 0;
  if (TREE_CODE (inner) == TYPE_DECL)
    {
      type = TREE_TYPE (inner);
      bool has_type = (type == TYPE_MAIN_VARIANT (type)
		       && TYPE_NAME (type) == inner);

      if (streaming_p ())
	u (has_type ? TREE_CODE (type) : 0);

      if (has_type)
	{
	  type_tag = insert (type, WK_value);
	  if (streaming_p ())
	    {
	      start (type, true);
	      tree_node_bools (type);
	      dump (dumper::TREE)
		&& dump ("Writing type:%d %C:%N", type_tag,
			 TREE_CODE (type), type);
	    }

	  stub_decl = TYPE_STUB_DECL (type);
	  bool has_stub = inner != stub_decl;
	  if (streaming_p ())
	    u (has_stub ? TREE_CODE (stub_decl) : 0);
	  if (has_stub)
	    {
	      stub_tag = insert (stub_decl);
	      if (streaming_p ())
		{
		  start (stub_decl, true);
		  tree_node_bools (stub_decl);
		  dump (dumper::TREE)
		    && dump ("Writing stub_decl:%d %C:%N", stub_tag,
			     TREE_CODE (stub_decl), stub_decl);
		}
	    }
	  else
	    stub_decl = NULL_TREE;
	}
      else
	/* Regular typedef.  */
	type = NULL_TREE;
    }

  /* Stream the container, we want it correctly canonicalized before
     we start emitting keys for this decl.  */
  tree container = decl_container (decl);

  unsigned tpl_levels = 0;
  if (decl != inner)
    tpl_header (decl, &tpl_levels);
  if (TREE_CODE (inner) == FUNCTION_DECL)
    fn_parms_init (inner);

  /* Now write out the merging information, and then really
     install the tag values.  */
  key_mergeable (tag, mk, decl, inner, container, dep);

  if (streaming_p ())
    dump (dumper::MERGE)
      && dump ("Wrote:%d's %s merge key %C:%N", tag,
	       merge_kind_name[mk], TREE_CODE (decl), decl);

  if (TREE_CODE (inner) == FUNCTION_DECL)
    fn_parms_fini (inner);

  if (!is_key_order ())
    tree_node_vals (decl);

  if (inner_tag)
    {
      if (!is_key_order ())
	tree_node_vals (inner);
      tpl_parms_fini (decl, tpl_levels);
    }

  if (type && !is_key_order ())
    {
      tree_node_vals (type);
      if (stub_decl)
	tree_node_vals (stub_decl);
    }

  if (!is_key_order ())
    {
      if (mk & MK_template_mask
	  || mk == MK_partial
	  || mk == MK_friend_spec)
	{
	  if (mk != MK_partial)
	    {
	      // FIXME: We should make use of the merge-key by
	      // exposing it outside of key_mergeable.  But this gets
	      // the job done.
	      auto *entry = reinterpret_cast <spec_entry *> (dep->deps[0]);

	      if (streaming_p ())
		u (get_mergeable_specialization_flags (entry->tmpl, decl));
	      tree_node (entry->tmpl);
	      tree_node (entry->args);
	    }
	  else
	    {
	      tree_node (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner)));
	      tree_node (CLASSTYPE_TI_ARGS (TREE_TYPE (inner)));
	    }
	}
      tree_node (get_constraints (decl));
    }

  if (streaming_p ())
    {
      /* Do not stray outside this section.  */
      gcc_checking_assert (!dep || dep->section == dep_hash->section);

      /* Write the entity index, so we can insert it as soon as we
	 know this is new.  */
      install_entity (decl, dep);
    }

  if (VAR_OR_FUNCTION_DECL_P (inner)
      && DECL_LANG_SPECIFIC (inner)
      && DECL_MODULE_ATTACHMENTS_P (inner)
      && !is_key_order ())
    {
      /* Stream the attached entities.  */
      auto *attach_vec = attached_table->get (inner);
      unsigned num = attach_vec->length ();
      if (streaming_p ())
	u (num);
      for (unsigned ix = 0; ix != num; ix++)
	{
	  tree attached = (*attach_vec)[ix];
	  tree_node (attached);
	  if (streaming_p ())
	    dump (dumper::MERGE)
	      && dump ("Written %d[%u] attached decl %N", tag, ix, attached);
	}
    }

  bool is_typedef = false;
  if (!type && TREE_CODE (inner) == TYPE_DECL)
    {
      tree t = TREE_TYPE (inner);
      unsigned tdef_flags = 0;
      if (DECL_ORIGINAL_TYPE (inner)
	  && TYPE_NAME (TREE_TYPE (inner)) == inner)
	{
	  tdef_flags |= 1;
	  if (TYPE_STRUCTURAL_EQUALITY_P (t)
	      && TYPE_DEPENDENT_P_VALID (t)
	      && TYPE_DEPENDENT_P (t))
	    tdef_flags |= 2;
	}
      if (streaming_p ())
	u (tdef_flags);

      if (tdef_flags & 1)
	{
	  /* A typedef type.  */
	  int type_tag = insert (t);
	  if (streaming_p ())
	    dump (dumper::TREE)
	      && dump ("Cloned:%d %s %C:%N", type_tag,
		       tdef_flags & 2 ? "depalias" : "typedef",
		       TREE_CODE (t), t);

	  is_typedef = true;
	}
    }

  if (streaming_p () && DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
    {
      bool cloned_p
	= (DECL_CHAIN (decl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)));
      bool needs_vtt_parm_p
	= (cloned_p && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (decl)));
      bool omit_inherited_parms_p
	= (cloned_p && DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
	   && base_ctor_omit_inherited_parms (decl));
      unsigned flags = (int (cloned_p) << 0
			| int (needs_vtt_parm_p) << 1
			| int (omit_inherited_parms_p) << 2);
      u (flags);
      dump (dumper::TREE) && dump ("CDTOR %N is %scloned",
				   decl, cloned_p ? "" : "not ");
    }

  if (streaming_p ())
    dump (dumper::TREE) && dump ("Written decl:%d %C:%N", tag,
				 TREE_CODE (decl), decl);

  if (NAMESPACE_SCOPE_P (inner))
    gcc_checking_assert (!dep == (VAR_OR_FUNCTION_DECL_P (inner)
				  && DECL_LOCAL_DECL_P (inner)));
  else if ((TREE_CODE (inner) == TYPE_DECL
	    && !is_typedef
	    && TYPE_NAME (TREE_TYPE (inner)) == inner)
	   || TREE_CODE (inner) == FUNCTION_DECL)
    {
      bool write_defn = !dep && has_definition (decl);
      if (streaming_p ())
	u (write_defn);
      if (write_defn)
	write_definition (decl);
    }
}

tree
trees_in::decl_value ()
{
  int tag = 0;
  bool is_mod = false;
  bool has_defn = false;
  unsigned mk_u = u ();
  if (mk_u >= MK_hwm || !merge_kind_name[mk_u])
    {
      set_overrun ();
      return NULL_TREE;
    }

  unsigned saved_unused = unused;
  unused = 0;
  
  merge_kind mk = merge_kind (mk_u);

  tree decl = start ();
  if (decl)
    {
      if (mk != MK_unique)
	{
	  if (!(mk & MK_template_mask) && !state->is_header ())
	    /* See note in trees_out about where this bool is sequenced.  */
	    is_mod = b ();

	  has_defn = b ();
	}

      if (!tree_node_bools (decl))
	decl = NULL_TREE;
    }
  
  /* Insert into map.  */
  tag = insert (decl);
  if (decl)
    dump (dumper::TREE)
      && dump ("Reading:%d %C", tag, TREE_CODE (decl));

  tree inner = decl;
  int inner_tag = 0;
  if (decl && TREE_CODE (decl) == TEMPLATE_DECL)
    {
      int code = u ();
      inner = start (code);
      if (inner && tree_node_bools (inner))
	DECL_TEMPLATE_RESULT (decl) = inner;
      else
	decl = NULL_TREE;

      inner_tag = insert (inner);
      if (decl)
	dump (dumper::TREE)
	  && dump ("Reading:%d %C", inner_tag, TREE_CODE (inner));
    }

  tree type = NULL_TREE;
  int type_tag = 0;
  tree stub_decl = NULL_TREE;
  int stub_tag = 0;
  if (decl && TREE_CODE (inner) == TYPE_DECL)
    {
      if (unsigned type_code = u ())
	{
	  type = start (type_code);
	  if (type && tree_node_bools (type))
	    {
	      TREE_TYPE (inner) = type;
	      TYPE_NAME (type) = inner;
	    }
	  else
	    decl = NULL_TREE;

	  type_tag = insert (type);
	  if (decl)
	    dump (dumper::TREE)
	      && dump ("Reading type:%d %C", type_tag, TREE_CODE (type));

	  if (unsigned stub_code = u ())
	    {
	      stub_decl = start (stub_code);
	      if (stub_decl && tree_node_bools (stub_decl))
		{
		  TREE_TYPE (stub_decl) = type;
		  TYPE_STUB_DECL (type) = stub_decl;
		}
	      else
		decl = NULL_TREE;

	      stub_tag = insert (stub_decl);
	      if (decl)
		dump (dumper::TREE)
		  && dump ("Reading stub_decl:%d %C", stub_tag,
			   TREE_CODE (stub_decl));
	    }
	}
    }

  if (!decl)
    {
    bail:
      if (inner_tag != 0)
	back_refs[~inner_tag] = NULL_TREE;
      if (type_tag != 0)
	back_refs[~type_tag] = NULL_TREE;
      if (stub_tag != 0)
	back_refs[~stub_tag] = NULL_TREE;
      if (tag != 0)
	back_refs[~tag] = NULL_TREE;
      set_overrun ();
      /* Bail.  */
      unused = saved_unused;
      return NULL_TREE;
    }

  /* Read the container, to ensure it's already been streamed in.  */
  tree container = decl_container ();
  unsigned tpl_levels = 0;

  /* Figure out if this decl is already known about.  */
  int parm_tag = 0;

  if (decl != inner)
    if (!tpl_header (decl, &tpl_levels))
      goto bail;
  if (TREE_CODE (inner) == FUNCTION_DECL)
    parm_tag = fn_parms_init (inner);

  tree existing = key_mergeable (tag, mk, decl, inner, type, container, is_mod);
  tree existing_inner = existing;
  if (existing)
    {
      if (existing == error_mark_node)
	goto bail;

      if (TREE_CODE (STRIP_TEMPLATE (existing)) == TYPE_DECL)
	{
	  tree etype = TREE_TYPE (existing);
	  if (TYPE_LANG_SPECIFIC (etype)
	      && COMPLETE_TYPE_P (etype)
	      && !CLASSTYPE_MEMBER_VEC (etype))
	    /* Give it a member vec, we're likely gonna be looking
	       inside it.  */
	    set_class_bindings (etype, -1);
	}

      /* Install the existing decl into the back ref array.  */
      register_duplicate (decl, existing);
      back_refs[~tag] = existing;
      if (inner_tag != 0)
	{
	  existing_inner = DECL_TEMPLATE_RESULT (existing);
	  back_refs[~inner_tag] = existing_inner;
	}

      if (type_tag != 0)
	{
	  tree existing_type = TREE_TYPE (existing);
	  back_refs[~type_tag] = existing_type;
	  if (stub_tag != 0)
	    back_refs[~stub_tag] = TYPE_STUB_DECL (existing_type);
	}
    }

  if (parm_tag)
    fn_parms_fini (parm_tag, inner, existing_inner, has_defn);

  if (!tree_node_vals (decl))
    goto bail;

  if (inner_tag)
    {
      gcc_checking_assert (DECL_TEMPLATE_RESULT (decl) == inner);

      if (!tree_node_vals (inner))
	goto bail;

      if (!tpl_parms_fini (decl, tpl_levels))
	goto bail;
    }

  if (type && (!tree_node_vals (type)
	       || (stub_decl && !tree_node_vals (stub_decl))))
    goto bail;

  spec_entry spec;
  unsigned spec_flags = 0;
  if (mk & MK_template_mask
      || mk == MK_partial
      || mk == MK_friend_spec)
    {
      if (mk == MK_partial)
	spec_flags = 2;
      else
	spec_flags = u ();

      spec.tmpl = tree_node ();
      spec.args = tree_node ();
    }
  /* Hold constraints on the spec field, for a short while.  */
  spec.spec = tree_node ();

  dump (dumper::TREE) && dump ("Read:%d %C:%N", tag, TREE_CODE (decl), decl);

  existing = back_refs[~tag];
  bool installed = install_entity (existing);
  bool is_new = existing == decl;

  if (VAR_OR_FUNCTION_DECL_P (inner)
      && DECL_LANG_SPECIFIC (inner)
      && DECL_MODULE_ATTACHMENTS_P (inner))
    {
      /* Read and maybe install the attached entities.  */
      bool existed;
      auto &set = attached_table->get_or_insert (STRIP_TEMPLATE (existing),
						 &existed);
      unsigned num = u ();
      if (is_new == existed)
	set_overrun ();
      if (is_new)
	set.reserve (num);
      for (unsigned ix = 0; !get_overrun () && ix != num; ix++)
	{
	  tree attached = tree_node ();
	  dump (dumper::MERGE)
	    && dump ("Read %d[%u] %s attached decl %N", tag, ix,
		     is_new ? "new" : "matched", attached);
	  if (is_new)
	    set.quick_push (attached);
	  else if (set[ix] != attached)
	    set_overrun ();
	}
    }

  /* Regular typedefs will have a NULL TREE_TYPE at this point.  */
  unsigned tdef_flags = 0;
  bool is_typedef = false;
  if (!type && TREE_CODE (inner) == TYPE_DECL)
    {
      tdef_flags = u ();
      if (tdef_flags & 1)
	is_typedef = true;
    }

  if (is_new)
    {
      /* A newly discovered node.  */
      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
	/* Mark this identifier as naming a virtual function --
	   lookup_overrides relies on this optimization.  */
	IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = true;

      if (installed)
	{
	  /* Mark the entity as imported.  */
	  retrofit_lang_decl (inner);
	  DECL_MODULE_IMPORT_P (inner) = true;
	}

      if (spec.spec)
	set_constraints (decl, spec.spec);

      if (TREE_CODE (decl) == INTEGER_CST && !TREE_OVERFLOW (decl))
	{
	  decl = cache_integer_cst (decl, true);
	  back_refs[~tag] = decl;
	}

      if (is_typedef)
	{
	  /* Frob it to be ready for cloning.  */
	  TREE_TYPE (inner) = DECL_ORIGINAL_TYPE (inner);
	  DECL_ORIGINAL_TYPE (inner) = NULL_TREE;
	  set_underlying_type (inner);
	  if (tdef_flags & 2)
	    {
	      /* Match instantiate_alias_template's handling.  */
	      tree type = TREE_TYPE (inner);
	      TYPE_DEPENDENT_P (type) = true;
	      TYPE_DEPENDENT_P_VALID (type) = true;
	      SET_TYPE_STRUCTURAL_EQUALITY (type);
	    }
	}

      if (inner_tag)
	/* Set the TEMPLATE_DECL's type.  */
	TREE_TYPE (decl) = TREE_TYPE (inner);

      if (mk & MK_template_mask
	  || mk == MK_partial)
	{
	  /* Add to specialization tables now that constraints etc are
	     added.  */
	  bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask);

	  spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl;
	  add_mergeable_specialization (!is_type,
					!is_type && mk & MK_tmpl_alias_mask,
					&spec, decl, spec_flags);
	}

      if (NAMESPACE_SCOPE_P (decl)
	  && (mk == MK_named || mk == MK_unique
	      || mk == MK_enum || mk == MK_friend_spec)
	  && !(VAR_OR_FUNCTION_DECL_P (decl) && DECL_LOCAL_DECL_P (decl)))
	add_module_namespace_decl (CP_DECL_CONTEXT (decl), decl);

      if (DECL_ARTIFICIAL (decl)
	  && TREE_CODE (decl) == FUNCTION_DECL
	  && !DECL_TEMPLATE_INFO (decl)
	  && DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
	  && TYPE_SIZE (DECL_CONTEXT (decl))
	  && !DECL_THUNK_P (decl))
	/* A new implicit member function, when the class is
	   complete.  This means the importee declared it, and
	   we must now add it to the class.  Note that implicit
	   member fns of template instantiations do not themselves
	   look like templates.  */
	if (!install_implicit_member (inner))
	  set_overrun ();
    }
  else
    {
      /* DECL is the to-be-discarded decl.  Its internal pointers will
	 be to the EXISTING's structure.  Frob it to point to its
	 own other structures, so loading its definition will alter
	 it, and not the existing decl.  */
      dump (dumper::MERGE) && dump ("Deduping %N", existing);

      if (inner_tag)
	DECL_TEMPLATE_RESULT (decl) = inner;

      if (type)
	{
	  /* Point at the to-be-discarded type & decl.  */
	  TYPE_NAME (type) = inner;
	  TREE_TYPE (inner) = type;

	  TYPE_STUB_DECL (type) = stub_decl ? stub_decl : inner;
	  if (stub_decl)
	    TREE_TYPE (stub_decl) = type;
	}

      if (inner_tag)
	/* Set the TEMPLATE_DECL's type.  */
	TREE_TYPE (decl) = TREE_TYPE (inner);

      if (!is_matching_decl (existing, decl, is_typedef))
	unmatched_duplicate (existing);

      if (TREE_CODE (inner) == FUNCTION_DECL)
	{
	  tree e_inner = STRIP_TEMPLATE (existing);
	  for (auto parm = DECL_ARGUMENTS (inner);
	       parm; parm = DECL_CHAIN (parm))
	    DECL_CONTEXT (parm) = e_inner;
	}

      /* And our result is the existing node.  */
      decl = existing;
    }

  if (mk == MK_friend_spec)
    {
      tree e = match_mergeable_specialization (true, &spec);
      if (!e)
	{
	  spec.spec = inner;
	  add_mergeable_specialization (true, false, &spec, decl, spec_flags);
	}
      else if (e != existing)
	set_overrun ();
    }

  if (is_typedef)
    {
      /* Insert the type into the array now.  */
      tag = insert (TREE_TYPE (decl));
      dump (dumper::TREE)
	&& dump ("Cloned:%d typedef %C:%N",
		 tag, TREE_CODE (TREE_TYPE (decl)), TREE_TYPE (decl));
    }

  unused = saved_unused;

  if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
    {
      unsigned flags = u ();

      if (is_new)
	{
	  bool cloned_p = flags & 1;
	  dump (dumper::TREE) && dump ("CDTOR %N is %scloned",
				       decl, cloned_p ? "" : "not ");
	  if (cloned_p)
	    build_cdtor_clones (decl, flags & 2, flags & 4,
				/* Update the member vec, if there is
				   one (we're in a different cluster
				   to the class defn).  */
				CLASSTYPE_MEMBER_VEC (DECL_CONTEXT (decl)));
	}
    }

  if (!NAMESPACE_SCOPE_P (inner)
      && ((TREE_CODE (inner) == TYPE_DECL
	   && !is_typedef
	   && TYPE_NAME (TREE_TYPE (inner)) == inner)
	  || TREE_CODE (inner) == FUNCTION_DECL)
      && u ())
    read_definition (decl);

  return decl;
}

/* DECL is an unnameable member of CTX.  Return a suitable identifying
   index.  */

static unsigned
get_field_ident (tree ctx, tree decl)
{
  gcc_checking_assert (TREE_CODE (decl) == USING_DECL
		       || !DECL_NAME (decl)
		       || IDENTIFIER_ANON_P (DECL_NAME (decl)));

  unsigned ix = 0;
  for (tree fields = TYPE_FIELDS (ctx);
       fields; fields = DECL_CHAIN (fields))
    {
      if (fields == decl)
	return ix;

      if (DECL_CONTEXT (fields) == ctx
	  && (TREE_CODE (fields) == USING_DECL
	      || (TREE_CODE (fields) == FIELD_DECL
		  && (!DECL_NAME (fields)
		      || IDENTIFIER_ANON_P (DECL_NAME (fields))))))
	/* Count this field.  */
	ix++;
    }
  gcc_unreachable ();
}

static tree
lookup_field_ident (tree ctx, unsigned ix)
{
  for (tree fields = TYPE_FIELDS (ctx);
       fields; fields = DECL_CHAIN (fields))
    if (DECL_CONTEXT (fields) == ctx
	&& (TREE_CODE (fields) == USING_DECL
	    || (TREE_CODE (fields) == FIELD_DECL
		&& (!DECL_NAME (fields)
		    || IDENTIFIER_ANON_P (DECL_NAME (fields))))))
      if (!ix--)
	return fields;

  return NULL_TREE;
}

/* Reference DECL.  REF indicates the walk kind we are performing.
   Return true if we should write this decl by value.  */

bool
trees_out::decl_node (tree decl, walk_kind ref)
{
  gcc_checking_assert (DECL_P (decl) && !DECL_TEMPLATE_PARM_P (decl)
		       && DECL_CONTEXT (decl));

  if (ref == WK_value)
    {
      depset *dep = dep_hash->find_dependency (decl);
      decl_value (decl, dep);
      return false;
    }

  switch (TREE_CODE (decl))
    {
    default:
      break;

    case FUNCTION_DECL:
      gcc_checking_assert (!DECL_LOCAL_DECL_P (decl));
      break;

    case RESULT_DECL:
      /* Unlike PARM_DECLs, RESULT_DECLs are only generated and
         referenced when we're inside the function itself.  */
      return true;

    case PARM_DECL:
      {
	if (streaming_p ())
	  i (tt_parm);
	tree_node (DECL_CONTEXT (decl));
	if (streaming_p ())
	  {
	    /* That must have put this in the map.  */
	    walk_kind ref = ref_node (decl);
	    if (ref != WK_none)
	      // FIXME:OPTIMIZATION We can wander into bits of the
	      // template this was instantiated from.  For instance
	      // deferred noexcept and default parms.  Currently we'll
	      // end up cloning those bits of tree.  It would be nice
	      // to reference those specific nodes.  I think putting
	      // those things in the map when we reference their
	      // template by name.  See the note in add_indirects.
	      return true;

	    dump (dumper::TREE)
	      && dump ("Wrote %s reference %N",
		       TREE_CODE (decl) == PARM_DECL ? "parameter" : "result",
		       decl);
	  }
      }
      return false;

    case IMPORTED_DECL:
      /* This describes a USING_DECL to the ME's debug machinery.  It
	 originates from the fortran FE, and has nothing to do with
	 C++ modules.  */
      return true;

    case LABEL_DECL:
      return true;

    case CONST_DECL:
      {
	/* If I end up cloning enum decls, implementing C++20 using
	   E::v, this will need tweaking.   */
	if (streaming_p ())
	  i (tt_enum_decl);
	tree ctx = DECL_CONTEXT (decl);
	gcc_checking_assert (TREE_CODE (ctx) == ENUMERAL_TYPE);
	tree_node (ctx);
	tree_node (DECL_NAME (decl));

	int tag = insert (decl);
	if (streaming_p ())
	  dump (dumper::TREE)
	    && dump ("Wrote enum decl:%d %C:%N", tag, TREE_CODE (decl), decl);
	return false;
      }
      break;

    case USING_DECL:
      if (TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
	break;
      /* FALLTHROUGH  */

    case FIELD_DECL:
      {
	if (streaming_p ())
	  i (tt_data_member);

	tree ctx = DECL_CONTEXT (decl);
	tree_node (ctx);

	tree name = NULL_TREE;

	if (TREE_CODE (decl) == USING_DECL)
	  ;
	else
	  {
	    name = DECL_NAME (decl);
	    if (name && IDENTIFIER_ANON_P (name))
	      name = NULL_TREE;
	  }

	tree_node (name);
	if (!name && streaming_p ())
	  {
	    unsigned ix = get_field_ident (ctx, decl);
	    u (ix);
	  }

	int tag = insert (decl);
	if (streaming_p ())
	  dump (dumper::TREE)
	    && dump ("Wrote member:%d %C:%N", tag, TREE_CODE (decl), decl);
	return false;
      }
      break;

    case VAR_DECL:
      gcc_checking_assert (!DECL_LOCAL_DECL_P (decl));
      if (DECL_VTABLE_OR_VTT_P (decl))
	{
	  /* VTT or VTABLE, they are all on the vtables list.  */
	  tree ctx = CP_DECL_CONTEXT (decl);
	  tree vtable = CLASSTYPE_VTABLES (ctx);
	  for (unsigned ix = 0; ; vtable = DECL_CHAIN (vtable), ix++)
	    if (vtable == decl)
	      {
		gcc_checking_assert (DECL_VIRTUAL_P (decl));
		if (streaming_p ())
		  {
		    u (tt_vtable);
		    u (ix);
		    dump (dumper::TREE)
		      && dump ("Writing vtable %N[%u]", ctx, ix);
		  }
		tree_node (ctx);
		return false;
	      }
	  gcc_unreachable ();
	}

      if (DECL_TINFO_P (decl))
	{
	tinfo:
	  /* A typeinfo, tt_tinfo_typedef or tt_tinfo_var.  */
	  bool is_var = TREE_CODE (decl) == VAR_DECL;
	  tree type = TREE_TYPE (decl);
	  unsigned ix = get_pseudo_tinfo_index (type);
	  if (streaming_p ())
	    {
	      i (is_var ? tt_tinfo_var : tt_tinfo_typedef);
	      u (ix);
	    }

	  if (is_var)
	    {
	      /* We also need the type it is for and mangled name, so
		 the reader doesn't need to complete the type (which
		 would break section ordering).  The type it is for is
		 stashed on the name's TREE_TYPE.  */
	      tree name = DECL_NAME (decl);
	      tree_node (name);
	      type = TREE_TYPE (name);
	      tree_node (type);
	    }

	  int tag = insert (decl);
	  if (streaming_p ())
	    dump (dumper::TREE)
	      && dump ("Wrote tinfo_%s:%d %u %N", is_var ? "var" : "type",
		       tag, ix, type);

	  if (!is_var)
	    {
	      tag = insert (type);
	      if (streaming_p ())
		dump (dumper::TREE)
		  && dump ("Wrote tinfo_type:%d %u %N", tag, ix, type);
	    }
	  return false;
	}
      break;

    case TYPE_DECL:
      if (DECL_TINFO_P (decl))
	goto tinfo;
      break;
    }

  if (DECL_THUNK_P (decl))
    {
      /* Thunks are similar to binfos -- write the thunked-to decl and
	 then thunk-specific key info.  */
      if (streaming_p ())
	{
	  i (tt_thunk);
	  i (THUNK_FIXED_OFFSET (decl));
	}

      tree target = decl;
      while (DECL_THUNK_P (target))
	target = THUNK_TARGET (target);
      tree_node (target);
      tree_node (THUNK_VIRTUAL_OFFSET (decl));
      int tag = insert (decl);
      if (streaming_p ())
	dump (dumper::TREE)
	  && dump ("Wrote:%d thunk %N to %N", tag, DECL_NAME (decl), target);
      return false;
    }

  if (DECL_CLONED_FUNCTION_P (decl))
    {
      tree target = get_clone_target (decl);
      if (streaming_p ())
	i (tt_clone_ref);

      tree_node (target);
      tree_node (DECL_NAME (decl));
      int tag = insert (decl);
      if (streaming_p ())
	dump (dumper::TREE)
	  && dump ("Wrote:%d clone %N of %N", tag, DECL_NAME (decl), target);
      return false;
    }

  /* Everything left should be a thing that is in the entity table.
     Mostly things that can be defined outside of their (original
     declaration) context.  */
  gcc_checking_assert (TREE_CODE (decl) == TEMPLATE_DECL
		       || TREE_CODE (decl) == VAR_DECL
		       || TREE_CODE (decl) == FUNCTION_DECL
		       || TREE_CODE (decl) == TYPE_DECL
		       || TREE_CODE (decl) == USING_DECL
		       || TREE_CODE (decl) == CONCEPT_DECL
		       || TREE_CODE (decl) == NAMESPACE_DECL);

  int use_tpl = -1;
  tree ti = node_template_info (decl, use_tpl);
  tree tpl = NULL_TREE;

  /* If this is the TEMPLATE_DECL_RESULT of a TEMPLATE_DECL, get the
     TEMPLATE_DECL.  Note TI_TEMPLATE is not a TEMPLATE_DECL for
     (some) friends, so we need to check that.  */
  // FIXME: Should local friend template specializations be by value?
  // They don't get idents so we'll never know they're imported, but I
  // think we can only reach them from the TU that defines the
  // befriending class?
  if (ti && TREE_CODE (TI_TEMPLATE (ti)) == TEMPLATE_DECL
      && DECL_TEMPLATE_RESULT (TI_TEMPLATE (ti)) == decl)
    {
      tpl = TI_TEMPLATE (ti);
    partial_template:
      if (streaming_p ())
	{
	  i (tt_template);
	  dump (dumper::TREE)
	    && dump ("Writing implicit template %C:%N%S",
		     TREE_CODE (tpl), tpl, tpl);
	}
      tree_node (tpl);

      /* Streaming TPL caused us to visit DECL and maybe its type.  */
      gcc_checking_assert (TREE_VISITED (decl));
      if (DECL_IMPLICIT_TYPEDEF_P (decl))
	gcc_checking_assert (TREE_VISITED (TREE_TYPE (decl)));
      return false;
    }

  tree ctx = CP_DECL_CONTEXT (decl);
  depset *dep = NULL;
  if (streaming_p ())
    dep = dep_hash->find_dependency (decl);
  else if (TREE_CODE (ctx) != FUNCTION_DECL
	   || TREE_CODE (decl) == TEMPLATE_DECL
	   || (dep_hash->sneakoscope && DECL_IMPLICIT_TYPEDEF_P (decl))
	   || (DECL_LANG_SPECIFIC (decl)
	       && DECL_MODULE_IMPORT_P (decl)))
    {
      auto kind = (TREE_CODE (decl) == NAMESPACE_DECL
		   && !DECL_NAMESPACE_ALIAS (decl)
		   ? depset::EK_NAMESPACE : depset::EK_DECL);
      dep = dep_hash->add_dependency (decl, kind);
    }

  if (!dep)
    {
      /* Some internal entity of context.  Do by value.  */
      decl_value (decl, NULL);
      return false;
    }

  if (dep->get_entity_kind () == depset::EK_REDIRECT)
    {
      /* The DECL_TEMPLATE_RESULT of a partial specialization.
	 Write the partial specialization's template.  */
      depset *redirect = dep->deps[0];
      gcc_checking_assert (redirect->get_entity_kind () == depset::EK_PARTIAL);
      tpl = redirect->get_entity ();
      goto partial_template;
    }

  if (streaming_p ())
    {
      /* Locate the entity.  */
      unsigned index = dep->cluster;
      unsigned import = 0;

      if (dep->is_import ())
	import = dep->section;
      else if (CHECKING_P)
	/* It should be what we put there.  */
	gcc_checking_assert (index == ~import_entity_index (decl));

#if CHECKING_P
      gcc_assert (!import || importedness >= 0);
#endif
      i (tt_entity);
      u (import);
      u (index);
    }

  int tag = insert (decl);
  if (streaming_p () && dump (dumper::TREE))
    {
      char const *kind = "import";
      module_state *from = (*modules)[0];
      if (dep->is_import ())
	/* Rediscover the unremapped index.  */
	from = import_entity_module (import_entity_index (decl));
      else
	{
	  tree o = get_originating_module_decl (decl);
	  o = STRIP_TEMPLATE (o);
	  kind = (DECL_LANG_SPECIFIC (o) && DECL_MODULE_PURVIEW_P (o)
		  ? "purview" : "GMF");
	}
      dump ("Wrote %s:%d %C:%N@%M", kind,
	    tag, TREE_CODE (decl), decl, from);
    }

  add_indirects (decl);

  return false;
}

void
trees_out::type_node (tree type)
{
  gcc_assert (TYPE_P (type));

  tree root = (TYPE_NAME (type)
	       ? TREE_TYPE (TYPE_NAME (type)) : TYPE_MAIN_VARIANT (type));

  if (type != root)
    {
      if (streaming_p ())
	i (tt_variant_type);
      tree_node (root);

      int flags = -1;

      if (TREE_CODE (type) == FUNCTION_TYPE
	  || TREE_CODE (type) == METHOD_TYPE)
	{
	  int quals = type_memfn_quals (type);
	  int rquals = type_memfn_rqual (type);
	  tree raises = TYPE_RAISES_EXCEPTIONS (type);
	  bool late = TYPE_HAS_LATE_RETURN_TYPE (type);

	  if (raises != TYPE_RAISES_EXCEPTIONS (root)
	      || rquals != type_memfn_rqual (root)
	      || quals != type_memfn_quals (root)
	      || late != TYPE_HAS_LATE_RETURN_TYPE (root))
	    flags = rquals | (int (late) << 2) | (quals << 3);
	}
      else
	{
	  if (TYPE_USER_ALIGN (type))
	    flags = TYPE_ALIGN_RAW (type);
	}

      if (streaming_p ())
	i (flags);

      if (flags < 0)
	;
      else if (TREE_CODE (type) == FUNCTION_TYPE
	       || TREE_CODE (type) == METHOD_TYPE)
	{
	  tree raises = TYPE_RAISES_EXCEPTIONS (type);
	  if (raises == TYPE_RAISES_EXCEPTIONS (root))
	    raises = error_mark_node;
	  tree_node (raises);
	}

      tree_node (TYPE_ATTRIBUTES (type));

      if (streaming_p ())
	{
	  /* Qualifiers.  */
	  int rquals = cp_type_quals (root);
	  int quals = cp_type_quals (type);
	  if (quals == rquals)
	    quals = -1;
	  i (quals);
	}

      if (ref_node (type) != WK_none)
	{
	  int tag = insert (type);
	  if (streaming_p ())
	    {
	      i (0);
	      dump (dumper::TREE)
		&& dump ("Wrote:%d variant type %C", tag, TREE_CODE (type));
	    }
	}
      return;
    }

  if (tree name = TYPE_NAME (type))
    if ((TREE_CODE (name) == TYPE_DECL && DECL_ORIGINAL_TYPE (name))
	|| DECL_TEMPLATE_PARM_P (name)
	|| TREE_CODE (type) == RECORD_TYPE
	|| TREE_CODE (type) == UNION_TYPE
	|| TREE_CODE (type) == ENUMERAL_TYPE)
      {
	/* We can meet template parms that we didn't meet in the
	   tpl_parms walk, because we're referring to a derived type
	   that was previously constructed from equivalent template
	   parms. */
	if (streaming_p ())
	  {
	    i (tt_typedef_type);
	    dump (dumper::TREE)
	      && dump ("Writing %stypedef %C:%N",
		       DECL_IMPLICIT_TYPEDEF_P (name) ? "implicit " : "",
		       TREE_CODE (name), name);
	  }
	tree_node (name);
	if (streaming_p ())
	  dump (dumper::TREE) && dump ("Wrote typedef %C:%N%S",
				       TREE_CODE (name), name, name);
	gcc_checking_assert (TREE_VISITED (type));
	return;
      }

  if (TYPE_PTRMEMFUNC_P (type))
    {
      /* This is a distinct type node, masquerading as a structure. */
      tree fn_type = TYPE_PTRMEMFUNC_FN_TYPE (type);
      if (streaming_p ())
	i (tt_ptrmem_type);
      tree_node (fn_type);
      int tag = insert (type);
      if (streaming_p ())
	dump (dumper::TREE) && dump ("Written:%d ptrmem type", tag);
      return;
    }

  if (streaming_p ())
    {
      u (tt_derived_type);
      u (TREE_CODE (type));
    }

  tree_node (TREE_TYPE (type));
  switch (TREE_CODE (type))
    {
    default:
      /* We should never meet a type here that is indescribable in
	 terms of other types.  */
      gcc_unreachable ();

    case ARRAY_TYPE:
      tree_node (TYPE_DOMAIN (type));
      if (streaming_p ())
	/* Dependent arrays are constructed with TYPE_DEPENENT_P
	   already set.  */
	u (TYPE_DEPENDENT_P (type));
      break;

    case COMPLEX_TYPE:
      /* No additional data.  */
      break;

    case BOOLEAN_TYPE:
      /* A non-standard boolean type.  */
      if (streaming_p ())
	u (TYPE_PRECISION (type));
      break;

    case INTEGER_TYPE:
      if (TREE_TYPE (type))
	{
	  /* A range type (representing an array domain).  */
	  tree_node (TYPE_MIN_VALUE (type));
	  tree_node (TYPE_MAX_VALUE (type));
	}
      else
	{
	  /* A new integral type (representing a bitfield).  */
	  if (streaming_p ())
	    {
	      unsigned prec = TYPE_PRECISION (type);
	      bool unsigned_p = TYPE_UNSIGNED (type);

	      u ((prec << 1) | unsigned_p);
	    }
	}
      break;

    case METHOD_TYPE:
    case FUNCTION_TYPE:
      {
	gcc_checking_assert (type_memfn_rqual (type) == REF_QUAL_NONE);

	tree arg_types = TYPE_ARG_TYPES (type);
	if (TREE_CODE (type) == METHOD_TYPE)
	  {
	    tree_node (TREE_TYPE (TREE_VALUE (arg_types)));
	    arg_types = TREE_CHAIN (arg_types);
	  }
	tree_node (arg_types);
      }
      break;

    case OFFSET_TYPE:
      tree_node (TYPE_OFFSET_BASETYPE (type));
      break;

    case POINTER_TYPE:
      /* No additional data.  */
      break;

    case REFERENCE_TYPE:
      if (streaming_p ())
	u (TYPE_REF_IS_RVALUE (type));
      break;

    case DECLTYPE_TYPE:
    case TYPEOF_TYPE:
    case UNDERLYING_TYPE:
      tree_node (TYPE_VALUES_RAW (type));
      if (TREE_CODE (type) == DECLTYPE_TYPE)
	/* We stash a whole bunch of things into decltype's
	   flags.  */
	if (streaming_p ())
	  tree_node_bools (type);
      break;

    case TYPE_ARGUMENT_PACK:
      /* No additional data.  */
      break;

    case TYPE_PACK_EXPANSION:
      if (streaming_p ())
	u (PACK_EXPANSION_LOCAL_P (type));
      tree_node (PACK_EXPANSION_PARAMETER_PACKS (type));
      break;

    case TYPENAME_TYPE:
      {
	tree_node (TYPE_CONTEXT (type));
	tree_node (DECL_NAME (TYPE_NAME (type)));
	tree_node (TYPENAME_TYPE_FULLNAME (type));
	if (streaming_p ())
	  {
	    enum tag_types tag_type = none_type;
	    if (TYPENAME_IS_ENUM_P (type))
	      tag_type = enum_type;
	    else if (TYPENAME_IS_CLASS_P (type))
	      tag_type = class_type;
	    u (int (tag_type));
	  }
	}
      break;

    case UNBOUND_CLASS_TEMPLATE:
      {
	tree decl = TYPE_NAME (type);
	tree_node (DECL_CONTEXT (decl));
	tree_node (DECL_NAME (decl));
	tree_node (DECL_TEMPLATE_PARMS (decl));
      }
      break;

    case VECTOR_TYPE:
      if (streaming_p ())
	{
	  poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type);
	  /* to_constant asserts that only coeff[0] is of interest.  */
	  wu (static_cast<unsigned HOST_WIDE_INT> (nunits.to_constant ()));
	}
      break;
    }

  /* We may have met the type during emitting the above.  */
  if (ref_node (type) != WK_none)
    {
      int tag = insert (type);
      if (streaming_p ())
	{
	  i (0);
	  dump (dumper::TREE)
	    && dump ("Wrote:%d derived type %C", tag, TREE_CODE (type));
	}
    }

  return;
}

/* T is (mostly*) a non-mergeable node that must be written by value.
   The mergeable case is a BINFO, which are as-if DECLSs.   */

void
trees_out::tree_value (tree t)
{
  /* We should never be writing a type by value.  tree_type should
     have streamed it, or we're going via its TYPE_DECL.  */
  gcc_checking_assert (!TYPE_P (t));

  if (DECL_P (t))
    /* No template, type, var or function, except anonymous
       non-context vars.  */
    gcc_checking_assert ((TREE_CODE (t) != TEMPLATE_DECL
			  && TREE_CODE (t) != TYPE_DECL
			  && (TREE_CODE (t) != VAR_DECL
			      || (!DECL_NAME (t) && !DECL_CONTEXT (t)))
			  && TREE_CODE (t) != FUNCTION_DECL));

  if (streaming_p ())
    {
      /* A new node -> tt_node.  */
      tree_val_count++;
      i (tt_node);
      start (t);
      tree_node_bools (t);
    }

  if  (TREE_CODE (t) == TREE_BINFO)
    /* Binfos are decl-like and need merging information.  */
    binfo_mergeable (t);

  int tag = insert (t, WK_value);
  if (streaming_p ())
    dump (dumper::TREE)
      && dump ("Writing tree:%d %C:%N", tag, TREE_CODE (t), t);

  tree_node_vals (t);

  if (streaming_p ())
    dump (dumper::TREE) && dump ("Written tree:%d %C:%N", tag, TREE_CODE (t), t);
}

tree
trees_in::tree_value ()
{
  tree t = start ();
  if (!t || !tree_node_bools (t))
    return NULL_TREE;

  tree existing = t;
  if (TREE_CODE (t) == TREE_BINFO)
    {
      tree type;
      unsigned ix = binfo_mergeable (&type);
      if (TYPE_BINFO (type))
	{
	  /* We already have a definition, this must be a duplicate.  */
	  dump (dumper::MERGE)
	    && dump ("Deduping binfo %N[%u]", type, ix);
	  existing = TYPE_BINFO (type);
	  while (existing && ix)
	    existing = TREE_CHAIN (existing);
	  if (existing)
	    register_duplicate (t, existing);
	  else
	    /* Error, mismatch -- diagnose in read_class_def's
	       checking.  */
	    existing = t;
	}
    }

  /* Insert into map.  */
  int tag = insert (existing);
  dump (dumper::TREE)
    && dump ("Reading tree:%d %C", tag, TREE_CODE (t));

  if (!tree_node_vals (t))
    {
      back_refs[~tag] = NULL_TREE;
      set_overrun ();
      /* Bail.  */
      return NULL_TREE;
    }

  dump (dumper::TREE) && dump ("Read tree:%d %C:%N", tag, TREE_CODE (t), t);

  if (TREE_CODE (existing) == INTEGER_CST && !TREE_OVERFLOW (existing))
    {
      existing = cache_integer_cst (t, true);
      back_refs[~tag] = existing;
    }

  return existing;
}

/* Stream out tree node T.  We automatically create local back
   references, which is essentially a single pass lisp
   self-referential structure pretty-printer.  */

void
trees_out::tree_node (tree t)
{
  dump.indent ();
  walk_kind ref = ref_node (t);
  if (ref == WK_none)
    goto done;

  if (ref != WK_normal)
    goto skip_normal;

  if (TREE_CODE (t) == IDENTIFIER_NODE)
    {
      /* An identifier node -> tt_id, tt_conv_id, tt_anon_id, tt_lambda_id.  */
      int code = tt_id;
      if (IDENTIFIER_ANON_P (t))
	code = IDENTIFIER_LAMBDA_P (t) ? tt_lambda_id : tt_anon_id;
      else if (IDENTIFIER_CONV_OP_P (t))
	code = tt_conv_id;

      if (streaming_p ())
	i (code);

      if (code == tt_conv_id)
	{
	  tree type = TREE_TYPE (t);
	  gcc_checking_assert (type || t == conv_op_identifier);
	  tree_node (type);
	}
      else if (code == tt_id && streaming_p ())
	str (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));

      int tag = insert (t);
      if (streaming_p ())
	{
	  /* We know the ordering of the 4 id tags.  */
	  static const char *const kinds[] = 
	    {"", "conv_op ", "anon ", "lambda "};
	  dump (dumper::TREE)
	    && dump ("Written:%d %sidentifier:%N", tag,
		     kinds[code - tt_id],
		     code == tt_conv_id ? TREE_TYPE (t) : t);
	}
      goto done;
    }

  if (TREE_CODE (t) == TREE_BINFO)
    {
      /* A BINFO -> tt_binfo.
	 We must do this by reference.  We stream the binfo tree
	 itself when streaming its owning RECORD_TYPE.  That we got
	 here means the dominating type is not in this SCC.  */
      if (streaming_p ())
	i (tt_binfo);
      binfo_mergeable (t);
      gcc_checking_assert (!TREE_VISITED (t));
      int tag = insert (t);
      if (streaming_p ())
	dump (dumper::TREE) && dump ("Inserting binfo:%d %N", tag, t);
      goto done;
    }

  if (TREE_CODE (t) == INTEGER_CST
      && !TREE_OVERFLOW (t)
      && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
    {
      /* An integral constant of enumeral type.  See if it matches one
	 of the enumeration values.  */
      for (tree values = TYPE_VALUES (TREE_TYPE (t));
	   values; values = TREE_CHAIN (values))
	{
	  tree decl = TREE_VALUE (values);
	  if (tree_int_cst_equal (DECL_INITIAL (decl), t))
	    {
	      if (streaming_p ())
		u (tt_enum_value);
	      tree_node (decl);
	      dump (dumper::TREE) && dump ("Written enum value %N", decl);
	      goto done;
	    }
	}
      /* It didn't match.  We'll write it a an explicit INTEGER_CST
	 node.  */
    }

  if (TYPE_P (t))
    {
      type_node (t);
      goto done;
    }

  if (DECL_P (t))
    {
      if (DECL_TEMPLATE_PARM_P (t))
	{
	  tpl_parm_value (t);
	  goto done;
	}

      if (!DECL_CONTEXT (t))
	{
	  /* There are a few cases of decls with no context.  We'll write
	     these by value, but first assert they are cases we expect.  */
	  gcc_checking_assert (ref == WK_normal);
	  switch (TREE_CODE (t))
	    {
	    default: gcc_unreachable ();

	    case LABEL_DECL:
	      /* CASE_LABEL_EXPRs contain uncontexted LABEL_DECLs.  */
	      gcc_checking_assert (!DECL_NAME (t));
	      break;

	    case VAR_DECL:
	      /* AGGR_INIT_EXPRs cons up anonymous uncontexted VAR_DECLs.  */
	      gcc_checking_assert (!DECL_NAME (t)
				   && DECL_ARTIFICIAL (t));
	      break;

	    case PARM_DECL:
	      /* REQUIRES_EXPRs have a tree list of uncontexted
		 PARM_DECLS.  It'd be nice if they had a
		 distinguishing flag to double check.  */
	      break;
	    }
	  goto by_value;
	}
    }

 skip_normal:
  if (DECL_P (t) && !decl_node (t, ref))
    goto done;

  /* Otherwise by value */
 by_value:
  tree_value (t);

 done:
  /* And, breath out.  */
  dump.outdent ();
}

/* Stream in a tree node.  */

tree
trees_in::tree_node (bool is_use)
{
  if (get_overrun ())
    return NULL_TREE;

  dump.indent ();
  int tag = i ();
  tree res = NULL_TREE;
  switch (tag)
    {
    default:
      /* backref, pull it out of the map.  */
      res = back_ref (tag);
      break;

    case tt_null:
      /* NULL_TREE.  */
      break;

    case tt_fixed:
      /* A fixed ref, find it in the fixed_ref array.   */
      {
	unsigned fix = u ();
	if (fix < (*fixed_trees).length ())
	  {
	    res = (*fixed_trees)[fix];
	    dump (dumper::TREE) && dump ("Read fixed:%u %C:%N%S", fix,
					 TREE_CODE (res), res, res);
	  }

	if (!res)
	  set_overrun ();
      }
      break;

    case tt_parm:
      {
	tree fn = tree_node ();
	if (fn && TREE_CODE (fn) == FUNCTION_DECL)
	  res = tree_node ();
	if (res)
	  dump (dumper::TREE)
	    && dump ("Read %s reference %N",
		     TREE_CODE (res) == PARM_DECL ? "parameter" : "result",
		     res);
      }
      break;

    case tt_node:
      /* A new node.  Stream it in.  */
      res = tree_value ();
      break;

    case tt_decl:
      /* A new decl.  Stream it in.  */
      res = decl_value ();
      break;

    case tt_tpl_parm:
      /* A template parameter.  Stream it in.  */
      res = tpl_parm_value ();
      break;

    case tt_id:
      /* An identifier node.  */
      {
	size_t l;
	const char *chars = str (&l);
	res = get_identifier_with_length (chars, l);
	int tag = insert (res);
	dump (dumper::TREE)
	  && dump ("Read identifier:%d %N", tag, res);
      }
      break;

    case tt_conv_id:
      /* A conversion operator.  Get the type and recreate the
	 identifier.  */
      {
	tree type = tree_node ();
	if (!get_overrun ())
	  {
	    res = type ? make_conv_op_name (type) : conv_op_identifier;
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("Created conv_op:%d %S for %N", tag, res, type);
	  }
      }
      break;

    case tt_anon_id:
    case tt_lambda_id:
      /* An anonymous or lambda id.  */
      {
	res = make_anon_name ();
	if (tag == tt_lambda_id)
	  IDENTIFIER_LAMBDA_P (res) = true;
	int tag = insert (res);
	dump (dumper::TREE)
	  && dump ("Read %s identifier:%d %N",
		   IDENTIFIER_LAMBDA_P (res) ? "lambda" : "anon", tag, res);
      }
      break;

    case tt_typedef_type:
      res = tree_node ();
      if (res)
	{
	  dump (dumper::TREE)
	    && dump ("Read %stypedef %C:%N",
		     DECL_IMPLICIT_TYPEDEF_P (res) ? "implicit " : "",
		     TREE_CODE (res), res);
	  res = TREE_TYPE (res);
	}
      break;

    case tt_derived_type:
      /* A type derived from some other type.  */
      {
	enum tree_code code = tree_code (u ());
	res = tree_node ();

	switch (code)
	  {
	  default:
	    set_overrun ();
	    break;

	  case ARRAY_TYPE:
	    {
	      tree domain = tree_node ();
	      int dep = u ();
	      if (!get_overrun ())
		res = build_cplus_array_type (res, domain, dep);
	    }
	    break;

	  case COMPLEX_TYPE:
	    if (!get_overrun ())
	      res = build_complex_type (res);
	    break;

	  case BOOLEAN_TYPE:
	    {
	      unsigned precision = u ();
	      if (!get_overrun ())
		res = build_nonstandard_boolean_type (precision);
	    }
	    break;

	  case INTEGER_TYPE:
	    if (res)
	      {
		/* A range type (representing an array domain).  */
		tree min = tree_node ();
		tree max = tree_node ();

		if (!get_overrun ())
		  res = build_range_type (res, min, max);
	      }
	    else
	      {
		/* A new integral type (representing a bitfield).  */
		unsigned enc = u ();
		if (!get_overrun ())
		  res = build_nonstandard_integer_type (enc >> 1, enc & 1);
	      }
	    break;

	  case FUNCTION_TYPE:
	  case METHOD_TYPE:
	    {
	      tree klass =  code == METHOD_TYPE ? tree_node () : NULL_TREE;
	      tree args = tree_node ();
	      if (!get_overrun ())
		{
		  if (klass)
		    res = build_method_type_directly (klass, res, args);
		  else
		    res = build_function_type (res, args);
		}
	    }
	    break;

	  case OFFSET_TYPE:
	    {
	      tree base = tree_node ();
	      if (!get_overrun ())
		res = build_offset_type (base, res);
	    }
	    break;

	  case POINTER_TYPE:
	    if (!get_overrun ())
	      res = build_pointer_type (res);
	    break;

	  case REFERENCE_TYPE:
	    {
	      bool rval = bool (u ());
	      if (!get_overrun ())
		res = cp_build_reference_type (res, rval);
	    }
	    break;

	  case DECLTYPE_TYPE:
	  case TYPEOF_TYPE:
	  case UNDERLYING_TYPE:
	    {
	      tree expr = tree_node ();
	      if (!get_overrun ())
		{
		  res = cxx_make_type (code);
		  TYPE_VALUES_RAW (res) = expr;
		  if (code == DECLTYPE_TYPE)
		    tree_node_bools (res);
		  SET_TYPE_STRUCTURAL_EQUALITY (res);
		}
	    }
	    break;

	  case TYPE_ARGUMENT_PACK:
	    if (!get_overrun ())
	      {
		tree pack = cxx_make_type (TYPE_ARGUMENT_PACK);
		SET_ARGUMENT_PACK_ARGS (pack, res);
		res = pack;
	      }
	    break;

	  case TYPE_PACK_EXPANSION:
	    {
	      bool local = u ();
	      tree param_packs = tree_node ();
	      if (!get_overrun ())
		{
		  tree expn = cxx_make_type (TYPE_PACK_EXPANSION);
		  SET_TYPE_STRUCTURAL_EQUALITY (expn);
		  SET_PACK_EXPANSION_PATTERN (expn, res);
		  PACK_EXPANSION_PARAMETER_PACKS (expn) = param_packs;
		  PACK_EXPANSION_LOCAL_P (expn) = local;
		  res = expn;
		}
	    }
	    break;

	  case TYPENAME_TYPE:
	    {
	      tree ctx = tree_node ();
	      tree name = tree_node ();
	      tree fullname = tree_node ();
	      enum tag_types tag_type = tag_types (u ());

	      if (!get_overrun ())
		res = build_typename_type (ctx, name, fullname, tag_type);
	    }
	    break;

	  case UNBOUND_CLASS_TEMPLATE:
	    {
	      tree ctx = tree_node ();
	      tree name = tree_node ();
	      tree parms = tree_node ();

	      if (!get_overrun ())
		res = make_unbound_class_template_raw (ctx, name, parms);
	    }
	    break;

	  case VECTOR_TYPE:
	    {
	      unsigned HOST_WIDE_INT nunits = wu ();
	      if (!get_overrun ())
		res = build_vector_type (res, static_cast<poly_int64> (nunits));
	    }
	    break;
	  }

	int tag = i ();
	if (!tag)
	  {
	    tag = insert (res);
	    if (res)
	      dump (dumper::TREE)
		&& dump ("Created:%d derived type %C", tag, code);
	  }
	else
	  res = back_ref (tag);
      }
      break;

    case tt_variant_type:
      /* Variant of some type.  */
      {
	res = tree_node ();
	int flags = i ();
	if (get_overrun ())
	  ;
	else if (flags < 0)
	  /* No change.  */;
	else if (TREE_CODE (res) == FUNCTION_TYPE
		 || TREE_CODE (res) == METHOD_TYPE)
	  {
	    cp_ref_qualifier rqual = cp_ref_qualifier (flags & 3);
	    bool late = (flags >> 2) & 1;
	    cp_cv_quals quals = cp_cv_quals (flags >> 3);

	    tree raises = tree_node ();
	    if (raises == error_mark_node)
	      raises = TYPE_RAISES_EXCEPTIONS (res);

	    res = build_cp_fntype_variant (res, rqual, raises, late);
	    if (TREE_CODE (res) == FUNCTION_TYPE)
	      res = apply_memfn_quals (res, quals, rqual);
	  }
	else
	  {
	    res = build_aligned_type (res, (1u << flags) >> 1);
	    TYPE_USER_ALIGN (res) = true;
	  }

	if (tree attribs = tree_node ())
	  res = cp_build_type_attribute_variant (res, attribs);

	int quals = i ();
	if (quals >= 0 && !get_overrun ())
	  res = cp_build_qualified_type (res, quals);

	int tag = i ();
	if (!tag)
	  {
	    tag = insert (res);
	    if (res)
	      dump (dumper::TREE)
		&& dump ("Created:%d variant type %C", tag, TREE_CODE (res));
	  }
	else
	  res = back_ref (tag);
      }
      break;

    case tt_tinfo_var:
    case tt_tinfo_typedef:
      /* A tinfo var or typedef.  */
      {
	bool is_var = tag == tt_tinfo_var;
	unsigned ix = u ();
	tree type = NULL_TREE;

	if (is_var)
	  {
	    tree name = tree_node ();
	    type = tree_node ();

	    if (!get_overrun ())
	      res = get_tinfo_decl_direct (type, name, int (ix));
	  }
	else
	  {
	    if (!get_overrun ())
	      {
		type = get_pseudo_tinfo_type (ix);
		res = TYPE_NAME (type);
	      }
	  }
	if (res)
	  {
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("Created tinfo_%s:%d %S:%u for %N",
		       is_var ? "var" : "decl", tag, res, ix, type);
	    if (!is_var)
	      {
		tag = insert (type);
		dump (dumper::TREE)
		  && dump ("Created tinfo_type:%d %u %N", tag, ix, type);
	      }
	  }
      }
      break;

    case tt_ptrmem_type:
      /* A pointer to member function.  */
      {
	tree type = tree_node ();
	if (type && TREE_CODE (type) == POINTER_TYPE
	    && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
	  {
	    res = build_ptrmemfunc_type (type);
	    int tag = insert (res);
	    dump (dumper::TREE) && dump ("Created:%d ptrmem type", tag);
	  }
	else
	  set_overrun ();
      }
      break;

    case tt_enum_value:
      /* An enum const value.  */
      {
	if (tree decl = tree_node ())
	  {
	    dump (dumper::TREE) && dump ("Read enum value %N", decl);
	    res = DECL_INITIAL (decl);
	  }

	if (!res)
	  set_overrun ();
      }
      break;

    case tt_enum_decl:
      /* An enum decl.  */
      {
	tree ctx = tree_node ();
	tree name = tree_node ();

	if (!get_overrun ()
	    && TREE_CODE (ctx) == ENUMERAL_TYPE)
	  res = find_enum_member (ctx, name);

	if (!res)
	  set_overrun ();
	else
	  {
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("Read enum decl:%d %C:%N", tag, TREE_CODE (res), res);
	  }
      }
      break;

    case tt_data_member:
      /* A data member.  */
      {
	tree ctx = tree_node ();
	tree name = tree_node ();

	if (!get_overrun ()
	    && RECORD_OR_UNION_TYPE_P (ctx))
	  {
	    if (name)
	      res = lookup_class_binding (ctx, name);
	    else
	      res = lookup_field_ident (ctx, u ());

	    if (!res
		|| TREE_CODE (res) != FIELD_DECL
		|| DECL_CONTEXT (res) != ctx)
	      res = NULL_TREE;
	  }

	if (!res)
	  set_overrun ();
	else
	  {
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("Read member:%d %C:%N", tag, TREE_CODE (res), res);
	  }
      }
      break;

    case tt_binfo:
      /* A BINFO.  Walk the tree of the dominating type.  */
      {
	tree type;
	unsigned ix = binfo_mergeable (&type);
	if (type)
	  {
	    res = TYPE_BINFO (type);
	    for (; ix && res; res = TREE_CHAIN (res))
	      ix--;
	    if (!res)
	      set_overrun ();
	  }

	if (get_overrun ())
	  break;

	/* Insert binfo into backreferences.  */
	tag = insert (res);
	dump (dumper::TREE) && dump ("Read binfo:%d %N", tag, res);
      }
      break;

    case tt_vtable:
      {
	unsigned ix = u ();
	tree ctx = tree_node ();
	dump (dumper::TREE) && dump ("Reading vtable %N[%u]", ctx, ix);
	if (TREE_CODE (ctx) == RECORD_TYPE && TYPE_LANG_SPECIFIC (ctx))
	  for (res = CLASSTYPE_VTABLES (ctx); res; res = DECL_CHAIN (res))
	    if (!ix--)
	      break;
	if (!res)
	  set_overrun ();
      }
      break;

    case tt_thunk:
      {
	int fixed = i ();
	tree target = tree_node ();
	tree virt = tree_node ();

	for (tree thunk = DECL_THUNKS (target);
	     thunk; thunk = DECL_CHAIN (thunk))
	  if (THUNK_FIXED_OFFSET (thunk) == fixed
	      && !THUNK_VIRTUAL_OFFSET (thunk) == !virt
	      && (!virt
		  || tree_int_cst_equal (virt, THUNK_VIRTUAL_OFFSET (thunk))))
	    {
	      res = thunk;
	      break;
	    }

	int tag = insert (res);
	if (res)
	  dump (dumper::TREE)
	    && dump ("Read:%d thunk %N to %N", tag, DECL_NAME (res), target);
	else
	  set_overrun ();
      }
      break;

    case tt_clone_ref:
      {
	tree target = tree_node ();
	tree name = tree_node ();

	if (DECL_P (target) && DECL_MAYBE_IN_CHARGE_CDTOR_P (target))
	  {
	    tree clone;
	    FOR_EVERY_CLONE (clone, target)
	      if (DECL_NAME (clone) == name)
		{
		  res = clone;
		  break;
		}
	  }

	if (!res)
	  set_overrun ();
	int tag = insert (res);
	if (res)
	  dump (dumper::TREE)
	    && dump ("Read:%d clone %N of %N", tag, DECL_NAME (res), target);
	else
	  set_overrun ();
       }
      break;

    case tt_entity:
      /* Index into the entity table.  Perhaps not loaded yet!  */
      {
	unsigned origin = state->slurp->remap_module (u ());
	unsigned ident = u ();
	module_state *from = (*modules)[origin];

	if (!origin || ident >= from->entity_num)
	  set_overrun ();
	if (!get_overrun ())
	  {
	    binding_slot *slot = &(*entity_ary)[from->entity_lwm + ident];
	    if (slot->is_lazy ())
	      if (!from->lazy_load (ident, slot))
		set_overrun ();
	    res = *slot;
	  }

	if (res)
	  {
	    const char *kind = (origin != state->mod ? "Imported" : "Named");
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("%s:%d %C:%N@%M", kind, tag, TREE_CODE (res),
		       res, (*modules)[origin]);

	    if (!add_indirects (res))
	      {
		set_overrun ();
		res = NULL_TREE;
	      }
	  }
      }
      break;

    case tt_template:
      /* A template.  */
      if (tree tpl = tree_node ())
	{
	  res = DECL_TEMPLATE_RESULT (tpl);
	  dump (dumper::TREE)
	    && dump ("Read template %C:%N", TREE_CODE (res), res);
	}
      break;
    }

  if (is_use && !unused && res && DECL_P (res) && !TREE_USED (res))
    {
      /* Mark decl used as mark_used does -- we cannot call
	 mark_used in the middle of streaming, we only need a subset
	 of its functionality.   */
      TREE_USED (res) = true;

      /* And for structured bindings also the underlying decl.  */
      if (DECL_DECOMPOSITION_P (res) && DECL_DECOMP_BASE (res))
	TREE_USED (DECL_DECOMP_BASE (res)) = true;

      if (DECL_CLONED_FUNCTION_P (res))
	TREE_USED (DECL_CLONED_FUNCTION (res)) = true;
    }

  dump.outdent ();
  return res;
}

void
trees_out::tpl_parms (tree parms, unsigned &tpl_levels)
{
  if (!parms)
    return;

  if (TREE_VISITED (parms))
    {
      ref_node (parms);
      return;
    }

  tpl_parms (TREE_CHAIN (parms), tpl_levels);

  tree vec = TREE_VALUE (parms);
  unsigned len = TREE_VEC_LENGTH (vec);
  /* Depth.  */
  int tag = insert (parms);
  if (streaming_p ())
    {
      i (len + 1);
      dump (dumper::TREE)
	&& dump ("Writing template parms:%d level:%N length:%d",
		 tag, TREE_PURPOSE (parms), len);
    }
  tree_node (TREE_PURPOSE (parms));

  for (unsigned ix = 0; ix != len; ix++)
    {
      tree parm = TREE_VEC_ELT (vec, ix);
      tree decl = TREE_VALUE (parm);

      gcc_checking_assert (DECL_TEMPLATE_PARM_P (decl));
      if (CHECKING_P)
	switch (TREE_CODE (decl))
	  {
	  default: gcc_unreachable ();

	  case TEMPLATE_DECL:
	    gcc_assert ((TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
			&& (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL)
			&& (TYPE_NAME (TREE_TYPE (decl)) == decl));
	    break;

	  case TYPE_DECL:
	    gcc_assert ((TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TYPE_PARM)
			&& (TYPE_NAME (TREE_TYPE (decl)) == decl));
	    break;

	  case PARM_DECL:
	    gcc_assert ((TREE_CODE (DECL_INITIAL (decl)) == TEMPLATE_PARM_INDEX)
			&& (TREE_CODE (TEMPLATE_PARM_DECL (DECL_INITIAL (decl)))
			    == CONST_DECL)
			&& (DECL_TEMPLATE_PARM_P
			    (TEMPLATE_PARM_DECL (DECL_INITIAL (decl)))));
	    break;
	  }

      tree_node (decl);
      tree_node (TEMPLATE_PARM_CONSTRAINTS (parm));
    }

  tpl_levels++;
}

tree
trees_in::tpl_parms (unsigned &tpl_levels)
{
  tree parms = NULL_TREE;

  while (int len = i ())
    {
      if (len < 0)
	{
	  parms = back_ref (len);
	  continue;
	}

      len -= 1;
      parms = tree_cons (NULL_TREE, NULL_TREE, parms);
      int tag = insert (parms);
      TREE_PURPOSE (parms) = tree_node ();

      dump (dumper::TREE)
	&& dump ("Reading template parms:%d level:%N length:%d",
		 tag, TREE_PURPOSE (parms), len);

      tree vec = make_tree_vec (len);
      for (int ix = 0; ix != len; ix++)
	{
	  tree decl = tree_node ();
	  if (!decl)
	    return NULL_TREE;

	  tree parm = build_tree_list (NULL, decl);
	  TEMPLATE_PARM_CONSTRAINTS (parm) = tree_node ();

	  TREE_VEC_ELT (vec, ix) = parm;
	}

      TREE_VALUE (parms) = vec;
      tpl_levels++;
    }

  return parms;
}

void
trees_out::tpl_parms_fini (tree tmpl, unsigned tpl_levels)
{
  for (tree parms = DECL_TEMPLATE_PARMS (tmpl);
       tpl_levels--; parms = TREE_CHAIN (parms))
    {
      tree vec = TREE_VALUE (parms);

      tree_node (TREE_TYPE (vec));
      tree dflt = error_mark_node;
      for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
	{
	  tree parm = TREE_VEC_ELT (vec, ix);
	  if (dflt)
	    {
	      dflt = TREE_PURPOSE (parm);
	      tree_node (dflt);
	    }

	  if (streaming_p ())
	    {
	      tree decl = TREE_VALUE (parm);
	      if (TREE_CODE (decl) == TEMPLATE_DECL)
		{
		  tree ctx = DECL_CONTEXT (decl);
		  tree inner = DECL_TEMPLATE_RESULT (decl);
		  tree tpi = (TREE_CODE (inner) == TYPE_DECL
			      ? TEMPLATE_TYPE_PARM_INDEX (TREE_TYPE (decl))
			      : DECL_INITIAL (inner));
		  bool original = (TEMPLATE_PARM_LEVEL (tpi)
				   == TEMPLATE_PARM_ORIG_LEVEL (tpi));
		  /* Original template template parms have a context
		     of their owning template.  Reduced ones do not.  */
		  gcc_checking_assert (original ? ctx == tmpl : !ctx);
		}
	    }
	}
    }
}

bool
trees_in::tpl_parms_fini (tree tmpl, unsigned tpl_levels)
{
  for (tree parms = DECL_TEMPLATE_PARMS (tmpl);
       tpl_levels--; parms = TREE_CHAIN (parms))
    {
      tree vec = TREE_VALUE (parms);
      tree dflt = error_mark_node;

      TREE_TYPE (vec) = tree_node ();
      for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
	{
	  tree parm = TREE_VEC_ELT (vec, ix);
	  if (dflt)
	    {
	      dflt = tree_node ();
	      if (get_overrun ())
		return false;
	      TREE_PURPOSE (parm) = dflt;
	    }

	  tree decl = TREE_VALUE (parm);
	  if (TREE_CODE (decl) == TEMPLATE_DECL)
	    {
	      tree inner = DECL_TEMPLATE_RESULT (decl);
	      tree tpi = (TREE_CODE (inner) == TYPE_DECL
			  ? TEMPLATE_TYPE_PARM_INDEX (TREE_TYPE (decl))
			  : DECL_INITIAL (inner));
	      bool original = (TEMPLATE_PARM_LEVEL (tpi)
			       == TEMPLATE_PARM_ORIG_LEVEL (tpi));
	      /* Original template template parms have a context
		 of their owning template.  Reduced ones do not.  */
	      if (original)
		DECL_CONTEXT (decl) = tmpl;
	    }
	}
    }
  return true;
}

/* PARMS is a LIST, one node per level.
   TREE_VALUE is a TREE_VEC of parm info for that level.
   each ELT is a TREE_LIST
   TREE_VALUE is PARM_DECL, TYPE_DECL or TEMPLATE_DECL
   TREE_PURPOSE is the default value.  */

void
trees_out::tpl_header (tree tpl, unsigned *tpl_levels)
{
  tree parms = DECL_TEMPLATE_PARMS (tpl);
  tpl_parms (parms, *tpl_levels);

  /* Mark end.  */
  if (streaming_p ())
    u (0);

  if (*tpl_levels)
    tree_node (TEMPLATE_PARMS_CONSTRAINTS (parms));
}

bool
trees_in::tpl_header (tree tpl, unsigned *tpl_levels)
{
  tree parms = tpl_parms (*tpl_levels);
  if (!parms)
    return false;

  DECL_TEMPLATE_PARMS (tpl) = parms;

  if (*tpl_levels)
    TEMPLATE_PARMS_CONSTRAINTS (parms) = tree_node ();

  return true;
}

/* Stream skeleton parm nodes, with their flags, type & parm indices.
   All the parms will have consecutive tags.  */

void
trees_out::fn_parms_init (tree fn)
{
  /* First init them.  */
  int base_tag = ref_num - 1;
  int ix = 0;
  for (tree parm = DECL_ARGUMENTS (fn);
       parm; parm = DECL_CHAIN (parm), ix++)
    {
      if (streaming_p ())
	{
	  start (parm);
	  tree_node_bools (parm);
	}
      int tag = insert (parm);
      gcc_checking_assert (base_tag - ix == tag);
    }
  /* Mark the end.  */
  if (streaming_p ())
    u (0);

  /* Now stream their contents.  */
  ix = 0;
  for (tree parm = DECL_ARGUMENTS (fn);
       parm; parm = DECL_CHAIN (parm), ix++)
    {
      if (streaming_p ())
	dump (dumper::TREE)
	  && dump ("Writing parm:%d %u (%N) of %N",
		   base_tag - ix, ix, parm, fn);
      tree_node_vals (parm);
    }
}

/* Build skeleton parm nodes, read their flags, type & parm indices.  */

int
trees_in::fn_parms_init (tree fn)
{
  int base_tag = ~(int)back_refs.length ();

  tree *parm_ptr = &DECL_ARGUMENTS (fn);
  int ix = 0;
  for (; int code = u (); ix++)
    {
      tree parm = start (code);
      if (!tree_node_bools (parm))
	return 0;

      int tag = insert (parm);
      gcc_checking_assert (base_tag - ix == tag);
      *parm_ptr = parm;
      parm_ptr = &DECL_CHAIN (parm);
    }

  ix = 0;
  for (tree parm = DECL_ARGUMENTS (fn);
       parm; parm = DECL_CHAIN (parm), ix++)
    {
      dump (dumper::TREE)
	&& dump ("Reading parm:%d %u (%N) of %N",
		 base_tag - ix, ix, parm, fn);
      if (!tree_node_vals (parm))
	return 0;
    }

  return base_tag;
}

/* Read the remaining parm node data.  Replace with existing (if
   non-null) in the map.  */

void
trees_in::fn_parms_fini (int tag, tree fn, tree existing, bool is_defn)
{
  tree existing_parm = existing ? DECL_ARGUMENTS (existing) : NULL_TREE;
  tree parms = DECL_ARGUMENTS (fn);
  unsigned ix = 0;
  for (tree parm = parms; parm; parm = DECL_CHAIN (parm), ix++)
    {
      if (existing_parm)
	{
	  if (is_defn && !DECL_SAVED_TREE (existing))
	    {
	      /* If we're about to become the definition, set the
		 names of the parms from us.  */
	      DECL_NAME (existing_parm) = DECL_NAME (parm);
	      DECL_SOURCE_LOCATION (existing_parm) = DECL_SOURCE_LOCATION (parm);
	    }

	  back_refs[~tag] = existing_parm;
	  existing_parm = DECL_CHAIN (existing_parm);
	}
      tag--;
    }
}

/* DEP is the depset of some decl we're streaming by value.  Determine
   the merging behaviour.  */

merge_kind
trees_out::get_merge_kind (tree decl, depset *dep)
{
  if (!dep)
    {
      if (VAR_OR_FUNCTION_DECL_P (decl))
	{
	  /* Any var or function with template info should have DEP.  */
	  gcc_checking_assert (!DECL_LANG_SPECIFIC (decl)
			       || !DECL_TEMPLATE_INFO (decl));
	  if (DECL_LOCAL_DECL_P (decl))
	    return MK_unique;
	}

      /* Either unique, or some member of a class that cannot have an
	 out-of-class definition.  For instance a FIELD_DECL.  */
      tree ctx = CP_DECL_CONTEXT (decl);
      if (TREE_CODE (ctx) == FUNCTION_DECL)
	{
	  /* USING_DECLs cannot have DECL_TEMPLATE_INFO -- this isn't
	     permitting them to have one.   */
	  gcc_checking_assert (TREE_CODE (decl) == USING_DECL
			       || !DECL_LANG_SPECIFIC (decl)
			       || !DECL_TEMPLATE_INFO (decl));

	  return MK_unique;
	}

      if (TREE_CODE (decl) == TEMPLATE_DECL
	  && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
	return MK_local_friend;

      gcc_checking_assert (TYPE_P (ctx));
      if (TREE_CODE (decl) == USING_DECL)
	return MK_field;

      if (TREE_CODE (decl) == FIELD_DECL)
	{
	  if (DECL_NAME (decl))
	    {
	      /* Anonymous FIELD_DECLs have a NULL name.  */
	      gcc_checking_assert (!IDENTIFIER_ANON_P (DECL_NAME (decl)));
	      return MK_named;
	    }

	  if (!DECL_NAME (decl)
	      && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
	      && !DECL_BIT_FIELD_REPRESENTATIVE (decl))
	    {
	      /* The underlying storage unit for a bitfield.  We do not
		 need to dedup it, because it's only reachable through
		 the bitfields it represents.  And those are deduped.  */
	      // FIXME: Is that assertion correct -- do we ever fish it
	      // out and put it in an expr?
	      gcc_checking_assert ((TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
				    ? TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
				    : TREE_CODE (TREE_TYPE (decl)))
				   == INTEGER_TYPE);
	      return MK_unique;
	    }

	  return MK_field;
	}

      if (TREE_CODE (decl) == CONST_DECL)
	return MK_named;

      if (TREE_CODE (decl) == VAR_DECL
	  && DECL_VTABLE_OR_VTT_P (decl))
	return MK_vtable;

      if (DECL_THUNK_P (decl))
	/* Thunks are unique-enough, because they're only referenced
	   from the vtable.  And that's either new (so we want the
	   thunks), or it's a duplicate (so it will be dropped).  */
	return MK_unique;

      /* There should be no other cases.  */
      gcc_unreachable ();
    }

  gcc_checking_assert (TREE_CODE (decl) != FIELD_DECL
		       && TREE_CODE (decl) != USING_DECL
		       && TREE_CODE (decl) != CONST_DECL);

  if (is_key_order ())
    {
      /* When doing the mergeablilty graph, there's an indirection to
	 the actual depset.  */
      gcc_assert (dep->is_special ());
      dep = dep->deps[0];
    }

  gcc_checking_assert (decl == dep->get_entity ());

  merge_kind mk = MK_named;
  switch (dep->get_entity_kind ())
    {
    default:
      gcc_unreachable ();

    case depset::EK_PARTIAL:
      mk = MK_partial;
      break;

    case depset::EK_DECL:
      {
	tree ctx = CP_DECL_CONTEXT (decl);

	switch (TREE_CODE (ctx))
	  {
	  default:
	    gcc_unreachable ();

	  case FUNCTION_DECL:
	    // FIXME: This can occur for (a) voldemorty TYPE_DECLS
	    // (which are returned from a function), or (b)
	    // block-scope class definitions in template functions.
	    // These are as unique as the containing function.  While
	    // on read-back we can discover if the CTX was a
	    // duplicate, we don't have a mechanism to get from the
	    // existing CTX to the existing version of this decl.
	    gcc_checking_assert
	      (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl)));

	    mk = MK_unique;
	    break;

	  case RECORD_TYPE:
	  case UNION_TYPE:
	    if (DECL_NAME (decl) == as_base_identifier)
	      mk = MK_as_base;
	    else if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
	      mk = MK_field;
	    break;

	  case NAMESPACE_DECL:
	    if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
		&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
	      if (tree scope
		  = LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR
					     (TREE_TYPE (decl))))
		if (TREE_CODE (scope) == VAR_DECL
		    && DECL_MODULE_ATTACHMENTS_P (scope))
		  {
		    mk = MK_attached;
		    break;
		  }

	    if (TREE_CODE (decl) == TEMPLATE_DECL
		&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
	      mk = MK_local_friend;
	    else if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
	      {
		if (DECL_IMPLICIT_TYPEDEF_P (decl)
		    && UNSCOPED_ENUM_P (TREE_TYPE (decl))
		    && TYPE_VALUES (TREE_TYPE (decl)))
		  /* Keyed by first enum value, and underlying type.  */
		  mk = MK_enum;
		else
		  /* No way to merge it, it is an ODR land-mine.  */
		  mk = MK_unique;
	      }
	  }
      }
      break;

    case depset::EK_SPECIALIZATION:
      {
	gcc_checking_assert (dep->is_special ());

	if (TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
	  /* An block-scope classes of templates are themselves
	     templates.  */
	  gcc_checking_assert (DECL_IMPLICIT_TYPEDEF_P (decl));

	if (dep->is_friend_spec ())
	  mk = MK_friend_spec;
	else if (dep->is_type_spec ())
	  mk = MK_type_spec;
	else if (dep->is_alias ())
	  mk = MK_alias_spec;
	else
	  mk = MK_decl_spec;

	if (TREE_CODE (decl) == TEMPLATE_DECL)
	  {
	    spec_entry *entry = reinterpret_cast <spec_entry *> (dep->deps[0]);
	    if (TREE_CODE (entry->spec) != TEMPLATE_DECL)
	      mk = merge_kind (mk | MK_tmpl_tmpl_mask);
	  }
      }
      break;
    }

  return mk;
}


/* The container of DECL -- not necessarily its context!  */

tree
trees_out::decl_container (tree decl)
{
  int use_tpl;
  tree tpl = NULL_TREE;
  if (tree template_info = node_template_info (decl, use_tpl))
    tpl = TI_TEMPLATE (template_info);
  if (tpl == decl)
    tpl = nullptr;

  /* Stream the template we're instantiated from.  */
  tree_node (tpl);

  tree container = NULL_TREE;
  if (TREE_CODE (decl) == TEMPLATE_DECL
      && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
    container = DECL_CHAIN (decl);
  else
    container = CP_DECL_CONTEXT (decl);

  if (TYPE_P (container))
    container = TYPE_NAME (container);

  tree_node (container);

  return container;
}

tree
trees_in::decl_container ()
{
  /* The maybe-template.  */
  (void)tree_node ();

  tree container = tree_node ();

  return container;
}

/* Write out key information about a mergeable DEP.  Does not write
   the contents of DEP itself.  The context has already been
   written.  The container has already been streamed.  */

void
trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
			  tree container, depset *dep)
{
  if (dep && is_key_order ())
    {
      gcc_checking_assert (dep->is_special ());
      dep = dep->deps[0];
    }

  if (streaming_p ())
    dump (dumper::MERGE)
      && dump ("Writing:%d's %s merge key (%s) %C:%N", tag, merge_kind_name[mk],
	       dep ? dep->entity_kind_name () : "contained",
	       TREE_CODE (decl), decl);

  /* Now write the locating information. */
  if (mk & MK_template_mask)
    {
      /* Specializations are located via their originating template,
	 and the set of template args they specialize.  */
      gcc_checking_assert (dep && dep->is_special ());
      spec_entry *entry = reinterpret_cast <spec_entry *> (dep->deps[0]);

      tree_node (entry->tmpl);
      tree_node (entry->args);
      if (mk & MK_tmpl_decl_mask)
	if (flag_concepts && TREE_CODE (inner) == VAR_DECL)
	  {
	    /* Variable template partial specializations might need
	       constraints (see spec_hasher::equal).  It's simpler to
	       write NULL when we don't need them.  */
	    tree constraints = NULL_TREE;

	    if (uses_template_parms (entry->args))
	      constraints = get_constraints (inner);
	    tree_node (constraints);
	  }

      if (CHECKING_P)
	{
	  /* Make sure we can locate the decl.  */
	  tree existing = match_mergeable_specialization
	    (bool (mk & MK_tmpl_decl_mask), entry);

	  gcc_assert (existing);
	  if (mk & MK_tmpl_decl_mask)
	    {
	      if (mk & MK_tmpl_alias_mask)
		/* It should be in both tables.  */
		gcc_checking_assert
		  (same_type_p (match_mergeable_specialization (false, entry),
				TREE_TYPE (existing)));
	      if (mk & MK_tmpl_tmpl_mask)
		existing = DECL_TI_TEMPLATE (existing);
	    }
	  else
	    {
	      if (mk & MK_tmpl_tmpl_mask)
		existing = CLASSTYPE_TI_TEMPLATE (existing);
	      else
		existing = TYPE_NAME (existing);
	    }

	  /* The walkabout should have found ourselves.  */
	  gcc_checking_assert (TREE_CODE (decl) == TYPE_DECL
			       ? same_type_p (TREE_TYPE (decl),
					      TREE_TYPE (existing))
			       : existing == decl);
	}
    }
  else if (mk != MK_unique)
    {
      merge_key key;
      tree name = DECL_NAME (decl);

      switch (mk)
	{
	default:
	  gcc_unreachable ();

	case MK_named:
	case MK_friend_spec:
	  if (IDENTIFIER_CONV_OP_P (name))
	    name = conv_op_identifier;

	  if (TREE_CODE (inner) == FUNCTION_DECL)
	    {
	      /* Functions are distinguished by parameter types.  */
	      tree fn_type = TREE_TYPE (inner);

	      key.ref_q = type_memfn_rqual (fn_type);
	      key.args = TYPE_ARG_TYPES (fn_type);

	      if (tree reqs = get_constraints (inner))
		{
		  if (cxx_dialect < cxx20)
		    reqs = CI_ASSOCIATED_CONSTRAINTS (reqs);
		  else
		    reqs = CI_DECLARATOR_REQS (reqs);
		  key.constraints = reqs;
		}

	      if (IDENTIFIER_CONV_OP_P (name)
		  || (decl != inner
		      && !(name == fun_identifier
			   /* In case the user names something _FUN  */
			   && LAMBDA_TYPE_P (DECL_CONTEXT (inner)))))
		/* And a function template, or conversion operator needs
		   the return type.  Except for the _FUN thunk of a
		   generic lambda, which has a recursive decl_type'd
		   return type.  */
		// FIXME: What if the return type is a voldemort?
		key.ret = fndecl_declared_return_type (inner);
	    }
	  break;

	case MK_field:
	  {
	    unsigned ix = 0;
	    if (TREE_CODE (inner) != FIELD_DECL)
	      name = NULL_TREE;
	    else
	      gcc_checking_assert (!name || !IDENTIFIER_ANON_P (name));

	    for (tree field = TYPE_FIELDS (TREE_TYPE (container));
		 ; field = DECL_CHAIN (field))
	      {
		tree finner = STRIP_TEMPLATE (field);
		if (TREE_CODE (finner) == TREE_CODE (inner))
		  {
		    if (finner == inner)
		      break;
		    ix++;
		  }
	      }
	    key.index = ix;
	  }
	  break;

	case MK_vtable:
	  {
	    tree vtable = CLASSTYPE_VTABLES (TREE_TYPE (container));
	    for (unsigned ix = 0; ; vtable = DECL_CHAIN (vtable), ix++)
	      if (vtable == decl)
		{
		  key.index = ix;
		  break;
		}
	    name = NULL_TREE;
	  }
	  break;

	case MK_as_base:
	  gcc_checking_assert
	    (decl == TYPE_NAME (CLASSTYPE_AS_BASE (TREE_TYPE (container))));
	  break;

	case MK_local_friend:
	  {
	    /* Find by index on the class's DECL_LIST  */
	    unsigned ix = 0;
	    for (tree decls = CLASSTYPE_DECL_LIST (TREE_CHAIN (decl));
		 decls; decls = TREE_CHAIN (decls))
	      if (!TREE_PURPOSE (decls))
		{
		  tree frnd = friend_from_decl_list (TREE_VALUE (decls));
		  if (frnd == decl)
		    break;
		  ix++;
		}
	    key.index = ix;
	    name = NULL_TREE;
	  }
	  break;

	case MK_enum:
	  {
	    /* Anonymous enums are located by their first identifier,
	       and underlying type.  */
	    tree type = TREE_TYPE (decl);

	    gcc_checking_assert (UNSCOPED_ENUM_P (type));
	    /* Using the type name drops the bit precision we might
	       have been using on the enum.  */
	    key.ret = TYPE_NAME (ENUM_UNDERLYING_TYPE (type));
	    if (tree values = TYPE_VALUES (type))
	      name = DECL_NAME (TREE_VALUE (values));
	  }
	  break;

	case MK_attached:
	  {
	    gcc_checking_assert (LAMBDA_TYPE_P (TREE_TYPE (inner)));
	    tree scope = LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR
						  (TREE_TYPE (inner)));
	    gcc_checking_assert (TREE_CODE (scope) == VAR_DECL);
	    auto *root = attached_table->get (scope);
	    unsigned ix = root->length ();
	    /* If we don't find it, we'll write a really big number
	       that the reader will ignore.  */
	    while (ix--)
	      if ((*root)[ix] == inner)
		break;

	    /* Use the attached-to decl as the 'name'.  */
	    name = scope;
	    key.index = ix;
	  }
	  break;

	case MK_partial:
	  {
	    key.constraints = get_constraints (inner);
	    key.ret = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner));
	    key.args = CLASSTYPE_TI_ARGS (TREE_TYPE (inner));
	  }
	  break;
	}

      tree_node (name);
      if (streaming_p ())
	{
	  unsigned code = (key.ref_q << 0) | (key.index << 2);
	  u (code);
	}

      if (mk == MK_enum)
	tree_node (key.ret);
      else if (mk == MK_partial
	       || (mk == MK_named && inner
		   && TREE_CODE (inner) == FUNCTION_DECL))
	{
	  tree_node (key.ret);
	  tree arg = key.args;
	  if (mk == MK_named)
	    while (arg && arg != void_list_node)
	      {
		tree_node (TREE_VALUE (arg));
		arg = TREE_CHAIN (arg);
	      }
	  tree_node (arg);
	  tree_node (key.constraints);
	}
    }
}

/* DECL is a new declaration that may be duplicated in OVL.  Use RET &
   ARGS to find its clone, or NULL.  If DECL's DECL_NAME is NULL, this
   has been found by a proxy.  It will be an enum type located by it's
   first member.

   We're conservative with matches, so ambiguous decls will be
   registered as different, then lead to a lookup error if the two
   modules are both visible.  Perhaps we want to do something similar
   to duplicate decls to get ODR errors on loading?  We already have
   some special casing for namespaces.  */

static tree
check_mergeable_decl (merge_kind mk, tree decl, tree ovl, merge_key const &key)
{
  tree found = NULL_TREE;
  for (ovl_iterator iter (ovl); !found && iter; ++iter)
    {
      tree match = *iter;

      tree d_inner = decl;
      tree m_inner = match;

    again:
      if (TREE_CODE (d_inner) != TREE_CODE (m_inner))
	{
	  if (TREE_CODE (match) == NAMESPACE_DECL
	      && !DECL_NAMESPACE_ALIAS (match))
	    /* Namespaces are never overloaded.  */
	    found = match;

	  continue;
	}

      switch (TREE_CODE (d_inner))
	{
	case TEMPLATE_DECL:
	  if (template_heads_equivalent_p (d_inner, m_inner))
	    {
	      d_inner = DECL_TEMPLATE_RESULT (d_inner);
	      m_inner = DECL_TEMPLATE_RESULT (m_inner);
	      if (d_inner == error_mark_node
		  && TYPE_DECL_ALIAS_P (m_inner))
		{
		  found = match;
		  break;
		}
	      goto again;
	    }
	  break;

	case FUNCTION_DECL:
	  if (tree m_type = TREE_TYPE (m_inner))
	    if ((!key.ret
		 || same_type_p (key.ret, fndecl_declared_return_type (m_inner)))
		&& type_memfn_rqual (m_type) == key.ref_q
		&& compparms (key.args, TYPE_ARG_TYPES (m_type))
		/* Reject if old is a "C" builtin and new is not "C".
		   Matches decls_match behaviour.  */
		&& (!DECL_IS_UNDECLARED_BUILTIN (m_inner)
		    || !DECL_EXTERN_C_P (m_inner)
		    || DECL_EXTERN_C_P (d_inner)))
	      {
		tree m_reqs = get_constraints (m_inner);
		if (m_reqs)
		  {
		    if (cxx_dialect < cxx20)
		      m_reqs = CI_ASSOCIATED_CONSTRAINTS (m_reqs);
		    else
		      m_reqs = CI_DECLARATOR_REQS (m_reqs);
		  }

		if (cp_tree_equal (key.constraints, m_reqs))
		  found = match;
	      }
	  break;

	case TYPE_DECL:
	  if (DECL_IMPLICIT_TYPEDEF_P (d_inner)
	      == DECL_IMPLICIT_TYPEDEF_P (m_inner))
	    {
	      if (!IDENTIFIER_ANON_P (DECL_NAME (m_inner)))
		return match;
	      else if (mk == MK_enum
		       && (TYPE_NAME (ENUM_UNDERLYING_TYPE (TREE_TYPE (m_inner)))
			   == key.ret))
		found = match;
	    }
	  break;

	default:
	  found = match;
	  break;
	}
    }

  return found;
}

/* DECL, INNER & TYPE are a skeleton set of nodes for a decl.  Only
   the bools have been filled in.  Read its merging key and merge it.
   Returns the existing decl if there is one.  */

tree
trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
			 tree type, tree container, bool is_mod)
{
  const char *kind = "new";
  tree existing = NULL_TREE;

  if (mk & MK_template_mask)
    {
      // FIXME: We could stream the specialization hash?
      spec_entry spec;
      spec.tmpl = tree_node ();
      spec.args = tree_node ();

      if (get_overrun ())
	return error_mark_node;

      DECL_NAME (decl) = DECL_NAME (spec.tmpl);
      DECL_CONTEXT (decl) = DECL_CONTEXT (spec.tmpl);
      DECL_NAME (inner) = DECL_NAME (decl);
      DECL_CONTEXT (inner) = DECL_CONTEXT (decl);

      tree constr = NULL_TREE;
      bool is_decl = mk & MK_tmpl_decl_mask;
      if (is_decl)
	{
	  if (flag_concepts && TREE_CODE (inner) == VAR_DECL)
	    {
	      constr = tree_node ();
	      if (constr)
		set_constraints (inner, constr);
	    }
	  spec.spec = (mk & MK_tmpl_tmpl_mask) ? inner : decl;
	}
      else
	spec.spec = type;
      existing = match_mergeable_specialization (is_decl, &spec);
      if (constr)
	/* We'll add these back later, if this is the new decl.  */
	remove_constraints (inner);

      if (!existing)
	; /* We'll add to the table once read.  */
      else if (mk & MK_tmpl_decl_mask)
	{
	  /* A declaration specialization.  */
	  if (mk & MK_tmpl_tmpl_mask)
	    existing = DECL_TI_TEMPLATE (existing);
	}
      else
	{
	  /* A type specialization.  */
	  if (mk & MK_tmpl_tmpl_mask)
	    existing = CLASSTYPE_TI_TEMPLATE (existing);
	  else
	    existing = TYPE_NAME (existing);
	}
    }
  else if (mk == MK_unique)
    kind = "unique";
  else
    {
      tree name = tree_node ();

      merge_key key;
      unsigned code = u ();
      key.ref_q = cp_ref_qualifier ((code >> 0) & 3);
      key.index = code >> 2;

      if (mk == MK_enum)
	key.ret = tree_node ();
      else if (mk == MK_partial
	       || ((mk == MK_named || mk == MK_friend_spec)
		   && TREE_CODE (inner) == FUNCTION_DECL))
	{
	  key.ret = tree_node ();
	  tree arg, *arg_ptr = &key.args;
	  while ((arg = tree_node ())
		 && arg != void_list_node
		 && mk != MK_partial)
	    {
	      *arg_ptr = tree_cons (NULL_TREE, arg, NULL_TREE);
	      arg_ptr = &TREE_CHAIN (*arg_ptr);
	    }
	  *arg_ptr = arg;
	  key.constraints = tree_node ();
	}

      if (get_overrun ())
	return error_mark_node;

      if (mk < MK_indirect_lwm)
	{
	  DECL_NAME (decl) = name;
	  DECL_CONTEXT (decl) = FROB_CONTEXT (container);
	}
      DECL_NAME (inner) = DECL_NAME (decl);
      DECL_CONTEXT (inner) = DECL_CONTEXT (decl);

      if (mk == MK_partial)
	{
	  for (tree spec = DECL_TEMPLATE_SPECIALIZATIONS (key.ret);
	       spec; spec = TREE_CHAIN (spec))
	    {
	      tree tmpl = TREE_VALUE (spec);
	      if (template_args_equal (key.args,
				       CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)))
		  && cp_tree_equal (key.constraints,
				    get_constraints
				    (DECL_TEMPLATE_RESULT (tmpl))))
		{
		  existing = tmpl;
		  break;
		}
	    }
	}
      else
	switch (TREE_CODE (container))
	  {
	  default:
	    gcc_unreachable ();

	  case NAMESPACE_DECL:
	    if (mk == MK_attached)
	      {
		if (DECL_LANG_SPECIFIC (name)
		    && VAR_OR_FUNCTION_DECL_P (name)
		    && DECL_MODULE_ATTACHMENTS_P (name))
		  if (auto *set = attached_table->get (name))
		    if (key.index < set->length ())
		      {
			existing = (*set)[key.index];
			if (existing)
			  {
			    gcc_checking_assert
			      (DECL_IMPLICIT_TYPEDEF_P (existing));
			    if (inner != decl)
			      existing
				= CLASSTYPE_TI_TEMPLATE (TREE_TYPE (existing));
			  }
		      }
	      }
	    else if (is_mod && !(state->is_module () || state->is_partition ()))
	      kind = "unique";
	    else
	      {
		gcc_checking_assert (mk == MK_named || mk == MK_enum);
		tree mvec;
		tree *vslot = mergeable_namespace_slots (container, name,
							 !is_mod, &mvec);
		existing = check_mergeable_decl (mk, decl, *vslot, key);
		if (!existing)
		  add_mergeable_namespace_entity (vslot, decl);
		else
		  {
		    /* Note that we now have duplicates to deal with in
		       name lookup.  */
		    if (is_mod)
		      BINDING_VECTOR_PARTITION_DUPS_P (mvec) = true;
		    else
		      BINDING_VECTOR_GLOBAL_DUPS_P (mvec) = true;
		  }
	      }
	    break;

	  case FUNCTION_DECL:
	    // FIXME: What about a voldemort? how do we find what it
	    // duplicates? Do we have to number vmorts relative to
	    // their containing function?  But how would that work
	    // when matching an in-TU declaration?
	    kind = "unique";
	    break;

	  case TYPE_DECL:
	    if (is_mod && !(state->is_module () || state->is_partition ())
		/* Implicit member functions can come from
		   anywhere.  */
		&& !(DECL_ARTIFICIAL (decl)
		     && TREE_CODE (decl) == FUNCTION_DECL
		     && !DECL_THUNK_P (decl)))
	      kind = "unique";
	    else
	      {
		tree ctx = TREE_TYPE (container);

		/* For some reason templated enumeral types are not marked
		   as COMPLETE_TYPE_P, even though they have members.
		   This may well be a bug elsewhere.  */
		if (TREE_CODE (ctx) == ENUMERAL_TYPE)
		  existing = find_enum_member (ctx, name);
		else if (COMPLETE_TYPE_P (ctx))
		  {
		    switch (mk)
		      {
		      default:
			gcc_unreachable ();

		      case MK_named:
			existing = lookup_class_binding (ctx, name);
			if (existing)
			  {
			    tree inner = decl;
			    if (TREE_CODE (inner) == TEMPLATE_DECL
				&& !DECL_MEMBER_TEMPLATE_P (inner))
			      inner = DECL_TEMPLATE_RESULT (inner);

			    existing = check_mergeable_decl
			      (mk, inner, existing, key);
			    
			    if (!existing && DECL_ALIAS_TEMPLATE_P (decl))
			      {} // FIXME: Insert into specialization
			    // tables, we'll need the arguments for that!
			  }
			break;

		      case MK_field:
			{
			  unsigned ix = key.index;
			  for (tree field = TYPE_FIELDS (ctx);
			       field; field = DECL_CHAIN (field))
			    {
			      tree finner = STRIP_TEMPLATE (field);
			      if (TREE_CODE (finner) == TREE_CODE (inner))
				if (!ix--)
				  {
				    existing = field;
				    break;
				  }
			    }
			}
			break;

		      case MK_vtable:
			{
			  unsigned ix = key.index;
			  for (tree vtable = CLASSTYPE_VTABLES (ctx);
			       vtable; vtable = DECL_CHAIN (vtable))
			    if (!ix--)
			      {
				existing = vtable;
				break;
			      }
			}
			break;

		      case MK_as_base:
			{
			  tree as_base = CLASSTYPE_AS_BASE (ctx);
			  if (as_base && as_base != ctx)
			    existing = TYPE_NAME (as_base);
			}
			break;

		      case MK_local_friend:
			{
			  unsigned ix = key.index;
			  for (tree decls = CLASSTYPE_DECL_LIST (ctx);
			       decls; decls = TREE_CHAIN (decls))
			    if (!TREE_PURPOSE (decls) && !ix--)
			      {
				existing
				  = friend_from_decl_list (TREE_VALUE (decls));
				break;
			      }
			}
			break;
		      }

		    if (existing && mk < MK_indirect_lwm && mk != MK_partial
			&& TREE_CODE (decl) == TEMPLATE_DECL
			&& !DECL_MEMBER_TEMPLATE_P (decl))
		      {
			tree ti;
			if (DECL_IMPLICIT_TYPEDEF_P (existing))
			  ti = TYPE_TEMPLATE_INFO (TREE_TYPE (existing));
			else
			  ti = DECL_TEMPLATE_INFO (existing);
			existing = TI_TEMPLATE (ti);
		      }
		  }
	      }
	  }
    }

  dump (dumper::MERGE)
    && dump ("Read:%d's %s merge key (%s) %C:%N", tag, merge_kind_name[mk],
	     existing ? "matched" : kind, TREE_CODE (decl), decl);

  return existing;
}

void
trees_out::binfo_mergeable (tree binfo)
{
  tree dom = binfo;
  while (tree parent = BINFO_INHERITANCE_CHAIN (dom))
    dom = parent;
  tree type = BINFO_TYPE (dom);
  gcc_checking_assert (TYPE_BINFO (type) == dom);
  tree_node (type);
  if (streaming_p ())
    {
      unsigned ix = 0;
      for (; dom != binfo; dom = TREE_CHAIN (dom))
	ix++;
      u (ix);
    }
}

unsigned
trees_in::binfo_mergeable (tree *type)
{
  *type = tree_node ();
  return u ();
}

/* DECL is a just streamed mergeable decl that should match EXISTING.  Check
   it does and issue an appropriate diagnostic if not.  Merge any
   bits from DECL to EXISTING.  This is stricter matching than
   decls_match, because we can rely on ODR-sameness, and we cannot use
   decls_match because it can cause instantiations of constraints.  */

bool
trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
{
  // FIXME: We should probably do some duplicate decl-like stuff here
  // (beware, default parms should be the same?)  Can we just call
  // duplicate_decls and teach it how to handle the module-specific
  // permitted/required duplications?

  // We know at this point that the decls have matched by key, so we
  // can elide some of the checking
  gcc_checking_assert (TREE_CODE (existing) == TREE_CODE (decl));

  tree d_inner = decl;
  tree e_inner = existing;
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      d_inner = DECL_TEMPLATE_RESULT (d_inner);
      e_inner = DECL_TEMPLATE_RESULT (e_inner);
      gcc_checking_assert (TREE_CODE (e_inner) == TREE_CODE (d_inner));
    }

  if (TREE_CODE (d_inner) == FUNCTION_DECL)
    {
      tree e_ret = fndecl_declared_return_type (existing);
      tree d_ret = fndecl_declared_return_type (decl);

      if (decl != d_inner && DECL_NAME (d_inner) == fun_identifier
	  && LAMBDA_TYPE_P (DECL_CONTEXT (d_inner)))
	/* This has a recursive type that will compare different.  */;
      else if (!same_type_p (d_ret, e_ret))
	goto mismatch;

      tree e_type = TREE_TYPE (e_inner);
      tree d_type = TREE_TYPE (d_inner);

      if (DECL_EXTERN_C_P (d_inner) != DECL_EXTERN_C_P (e_inner))
	goto mismatch;

      for (tree e_args = TYPE_ARG_TYPES (e_type),
	     d_args = TYPE_ARG_TYPES (d_type);
	   e_args != d_args && (e_args || d_args);
	   e_args = TREE_CHAIN (e_args), d_args = TREE_CHAIN (d_args))
	{
	  if (!(e_args && d_args))
	    goto mismatch;

	  if (!same_type_p (TREE_VALUE (d_args), TREE_VALUE (e_args)))
	    goto mismatch;

	  // FIXME: Check default values
	}

      /* If EXISTING has an undeduced or uninstantiated exception
	 specification, but DECL does not, propagate the exception
	 specification.  Otherwise we end up asserting or trying to
	 instantiate it in the middle of loading.   */
      tree e_spec = TYPE_RAISES_EXCEPTIONS (e_type);
      tree d_spec = TYPE_RAISES_EXCEPTIONS (d_type);
      if (DEFERRED_NOEXCEPT_SPEC_P (e_spec))
	{
	  if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
	      || (UNEVALUATED_NOEXCEPT_SPEC_P (e_spec)
		  && !UNEVALUATED_NOEXCEPT_SPEC_P (d_spec)))
	    {
	      dump (dumper::MERGE)
		&& dump ("Propagating instantiated noexcept to %N", existing);
	      TREE_TYPE (existing) = d_type;

	      /* Propagate to existing clones.  */
	      tree clone;
	      FOR_EACH_CLONE (clone, existing)
		{
		  if (TREE_TYPE (clone) == e_type)
		    TREE_TYPE (clone) = d_type;
		  else
		    TREE_TYPE (clone)
		      = build_exception_variant (TREE_TYPE (clone), d_spec);
		}
	    }
	}
      else if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
	       && !comp_except_specs (d_spec, e_spec, ce_type))
	goto mismatch;
    }
  else if (is_typedef)
    {
      if (!DECL_ORIGINAL_TYPE (e_inner)
	  || !same_type_p (DECL_ORIGINAL_TYPE (d_inner),
			   DECL_ORIGINAL_TYPE (e_inner)))
	goto mismatch;
    }
  /* Using cp_tree_equal because we can meet TYPE_ARGUMENT_PACKs
     here. I suspect the entities that directly do that are things
     that shouldn't go to duplicate_decls (FIELD_DECLs etc).   */
  else if (!cp_tree_equal (TREE_TYPE (decl), TREE_TYPE (existing)))
    {
    mismatch:
      if (DECL_IS_UNDECLARED_BUILTIN (existing))
	/* Just like duplicate_decls, presum the user knows what
	   they're doing in overriding a builtin.   */
	TREE_TYPE (existing) = TREE_TYPE (decl);
      else
	{
	  // FIXME:QOI Might be template specialization from a module,
	  // not necessarily global module
	  error_at (DECL_SOURCE_LOCATION (decl),
		    "conflicting global module declaration %#qD", decl);
	  inform (DECL_SOURCE_LOCATION (existing),
		  "existing declaration %#qD", existing);
	  return false;
	}
    }

  if (DECL_IS_UNDECLARED_BUILTIN (existing)
      && !DECL_IS_UNDECLARED_BUILTIN (decl))
    {
      /* We're matching a builtin that the user has yet to declare.
	 We are the one!  This is very much duplicate-decl
	 shenanigans. */
      DECL_SOURCE_LOCATION (existing) = DECL_SOURCE_LOCATION (decl);
      if (TREE_CODE (decl) != TYPE_DECL)
	{
	  /* Propagate exceptions etc.  */
	  TREE_TYPE (existing) = TREE_TYPE (decl);
	  TREE_NOTHROW (existing) = TREE_NOTHROW (decl);
	}
      /* This is actually an import! */
      DECL_MODULE_IMPORT_P (existing) = true;

      /* Yay, sliced!  */
      existing->base = decl->base;

      if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  /* Ew :(  */
	  memcpy (&existing->decl_common.size,
		  &decl->decl_common.size,
		  (offsetof (tree_decl_common, pt_uid)
		   - offsetof (tree_decl_common, size)));
	  auto bltin_class = DECL_BUILT_IN_CLASS (decl);
	  existing->function_decl.built_in_class = bltin_class;
	  auto fncode = DECL_UNCHECKED_FUNCTION_CODE (decl);
	  DECL_UNCHECKED_FUNCTION_CODE (existing) = fncode;
	  if (existing->function_decl.built_in_class == BUILT_IN_NORMAL)
	    {
	      if (builtin_decl_explicit_p (built_in_function (fncode)))
		switch (fncode)
		  {
		  case BUILT_IN_STPCPY:
		    set_builtin_decl_implicit_p
		      (built_in_function (fncode), true);
		    break;
		  default:
		    set_builtin_decl_declared_p
		      (built_in_function (fncode), true);
		    break;
		  }
	      copy_attributes_to_builtin (decl);
	    }
	}
    }

  if (VAR_OR_FUNCTION_DECL_P (decl)
      && DECL_TEMPLATE_INSTANTIATED (decl))
    /* Don't instantiate again!  */
    DECL_TEMPLATE_INSTANTIATED (existing) = true;

  if (TREE_CODE (d_inner) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (d_inner))
    DECL_DECLARED_INLINE_P (e_inner) = true;
  if (!DECL_EXTERNAL (d_inner))
    DECL_EXTERNAL (e_inner) = false;

  // FIXME: Check default tmpl and fn parms here

  return true;
}

/* FN is an implicit member function that we've discovered is new to
   the class.  Add it to the TYPE_FIELDS chain and the method vector.
   Reset the appropriate classtype lazy flag.   */

bool
trees_in::install_implicit_member (tree fn)
{
  tree ctx = DECL_CONTEXT (fn);
  tree name = DECL_NAME (fn);
  /* We know these are synthesized, so the set of expected prototypes
     is quite restricted.  We're not validating correctness, just
     distinguishing beteeen the small set of possibilities.  */
  tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (fn));
  if (IDENTIFIER_CTOR_P (name))
    {
      if (CLASSTYPE_LAZY_DEFAULT_CTOR (ctx)
	  && VOID_TYPE_P (parm_type))
	CLASSTYPE_LAZY_DEFAULT_CTOR (ctx) = false;
      else if (!TYPE_REF_P (parm_type))
	return false;
      else if (CLASSTYPE_LAZY_COPY_CTOR (ctx)
	       && !TYPE_REF_IS_RVALUE (parm_type))
	CLASSTYPE_LAZY_COPY_CTOR (ctx) = false;
      else if (CLASSTYPE_LAZY_MOVE_CTOR (ctx))
	CLASSTYPE_LAZY_MOVE_CTOR (ctx) = false;
      else
	return false;
    }
  else if (IDENTIFIER_DTOR_P (name))
    {
      if (CLASSTYPE_LAZY_DESTRUCTOR (ctx))
	CLASSTYPE_LAZY_DESTRUCTOR (ctx) = false;
      else
	return false;
      if (DECL_VIRTUAL_P (fn))
	/* A virtual dtor should have been created when the class
	   became complete.  */
	return false;
    }
  else if (name == assign_op_identifier)
    {
      if (!TYPE_REF_P (parm_type))
	return false;
      else if (CLASSTYPE_LAZY_COPY_ASSIGN (ctx)
	       && !TYPE_REF_IS_RVALUE (parm_type))
	CLASSTYPE_LAZY_COPY_ASSIGN (ctx) = false;
      else if (CLASSTYPE_LAZY_MOVE_ASSIGN (ctx))
	CLASSTYPE_LAZY_MOVE_ASSIGN (ctx) = false;
      else
	return false;
    }
  else
    return false;

  dump (dumper::MERGE) && dump ("Adding implicit member %N", fn);

  DECL_CHAIN (fn) = TYPE_FIELDS (ctx);
  TYPE_FIELDS (ctx) = fn;

  add_method (ctx, fn, false);

    /* Propagate TYPE_FIELDS.  */
  fixup_type_variants (ctx);

  return true;
}

/* Return non-zero if DECL has a definition that would be interesting to
   write out.  */

static bool
has_definition (tree decl)
{
  bool is_tmpl = TREE_CODE (decl) == TEMPLATE_DECL;
  if (is_tmpl)
    decl = DECL_TEMPLATE_RESULT (decl);

  switch (TREE_CODE (decl))
    {
    default:
      break;

    case FUNCTION_DECL:
      if (!DECL_SAVED_TREE (decl))
	/* Not defined.  */
	break;

      if (DECL_DECLARED_INLINE_P (decl))
	return true;

      if (DECL_THIS_STATIC (decl)
	  && (header_module_p ()
	      || (!DECL_LANG_SPECIFIC (decl) || !DECL_MODULE_PURVIEW_P (decl))))
	/* GM static function.  */
	return true;

      if (DECL_TEMPLATE_INFO (decl))
	{
	  int use_tpl = DECL_USE_TEMPLATE (decl);

	  // FIXME: Partial specializations have definitions too.
	  if (use_tpl < 2)
	    return true;
	}
      break;

    case TYPE_DECL:
      {
	tree type = TREE_TYPE (decl);
	if (type == TYPE_MAIN_VARIANT (type)
	    && decl == TYPE_NAME (type)
	    && (TREE_CODE (type) == ENUMERAL_TYPE
		? TYPE_VALUES (type) : TYPE_FIELDS (type)))
	  return true;
      }
      break;

    case VAR_DECL:
      if (DECL_LANG_SPECIFIC (decl)
	  && DECL_TEMPLATE_INFO (decl)
	  && DECL_USE_TEMPLATE (decl) < 2)
	return DECL_INITIAL (decl);
      else
	{
	  if (!DECL_INITIALIZED_P (decl))
	    return false;

	  if (header_module_p ()
	      || (!DECL_LANG_SPECIFIC (decl) || !DECL_MODULE_PURVIEW_P (decl)))
	    /* GM static variable.  */
	    return true;

	  if (!TREE_CONSTANT (decl))
	    return false;

	  return true;
	}
      break;

    case CONCEPT_DECL:
      if (DECL_INITIAL (decl))
	return true;

      break;
    }

  return false;
}

uintptr_t *
trees_in::find_duplicate (tree existing)
{
  if (!duplicates)
    return NULL;

  return duplicates->get (existing);
}

/* We're starting to read a duplicate DECL.  EXISTING is the already
   known node.  */

void
trees_in::register_duplicate (tree decl, tree existing)
{
  if (!duplicates)
    duplicates = new duplicate_hash_map (40);

  bool existed;
  uintptr_t &slot = duplicates->get_or_insert (existing, &existed);
  gcc_checking_assert (!existed);
  slot = reinterpret_cast<uintptr_t> (decl);
}

/* We've read a definition of MAYBE_EXISTING.  If not a duplicate,
   return MAYBE_EXISTING (into which the definition should be
   installed).  Otherwise return NULL if already known bad, or the
   duplicate we read (for ODR checking, or extracting additional merge
   information).  */

tree
trees_in::odr_duplicate (tree maybe_existing, bool has_defn)
{
  tree res = NULL_TREE;

  if (uintptr_t *dup = find_duplicate (maybe_existing))
    {
      if (!(*dup & 1))
	res = reinterpret_cast<tree> (*dup);
    }
  else
    res = maybe_existing;

  assert_definition (maybe_existing, res && !has_defn);

  // FIXME: We probably need to return the template, so that the
  // template header can be checked?
  return res ? STRIP_TEMPLATE (res) : NULL_TREE;
}

/* The following writer functions rely on the current behaviour of
   depset::hash::add_dependency making the decl and defn depset nodes
   depend on eachother.  That way we don't have to worry about seeding
   the tree map with named decls that cannot be looked up by name (I.e
   template and function parms).  We know the decl and definition will
   be in the same cluster, which is what we want.  */

void
trees_out::write_function_def (tree decl)
{
  tree_node (DECL_RESULT (decl));
  tree_node (DECL_INITIAL (decl));
  tree_node (DECL_SAVED_TREE (decl));
  tree_node (DECL_FRIEND_CONTEXT (decl));

  constexpr_fundef *cexpr = retrieve_constexpr_fundef (decl);
  int tag = 0;
  if (cexpr)
    {
      if (cexpr->result == error_mark_node)
	/* We'll stream the RESULT_DECL naturally during the
	   serialization.  We never need to fish it back again, so
	   that's ok.  */
	tag = 0;
      else
	tag = insert (cexpr->result);
    }
  if (streaming_p ())
    {
      i (tag);
      if (tag)
	dump (dumper::TREE)
	  && dump ("Constexpr:%d result %N", tag, cexpr->result);
    }
  if (tag)
    {
      unsigned ix = 0;
      for (tree parm = cexpr->parms; parm; parm = DECL_CHAIN (parm), ix++)
	{
	  tag = insert (parm);
	  if (streaming_p ())
	    dump (dumper::TREE)
	      && dump ("Constexpr:%d parm:%u %N", tag, ix, parm);
	}
      tree_node (cexpr->body);
    }

  if (streaming_p ())
    {
      unsigned flags = 0;

      if (DECL_NOT_REALLY_EXTERN (decl))
	flags |= 1;

      u (flags);
    }
}

void
trees_out::mark_function_def (tree)
{
}

bool
trees_in::read_function_def (tree decl, tree maybe_template)
{
  dump () && dump ("Reading function definition %N", decl);
  tree result = tree_node ();
  tree initial = tree_node ();
  tree saved = tree_node ();
  tree context = tree_node ();
  constexpr_fundef cexpr;

  tree maybe_dup = odr_duplicate (maybe_template, DECL_SAVED_TREE (decl));
  bool installing = maybe_dup && !DECL_SAVED_TREE (decl);

  if (int wtag = i ())
    {
      int tag = 1;
      cexpr.result = error_mark_node;

      cexpr.result = copy_decl (result);
      tag = insert (cexpr.result);

      if (wtag != tag)
	set_overrun ();
      dump (dumper::TREE)
	&& dump ("Constexpr:%d result %N", tag, cexpr.result);

      cexpr.parms = NULL_TREE;
      tree *chain = &cexpr.parms;
      unsigned ix = 0;
      for (tree parm = DECL_ARGUMENTS (maybe_dup ? maybe_dup : decl);
	   parm; parm = DECL_CHAIN (parm), ix++)
	{
	  tree p = copy_decl (parm);
	  tag = insert (p);
	  dump (dumper::TREE)
	    && dump ("Constexpr:%d parm:%u %N", tag, ix, p);
	  *chain = p;
	  chain = &DECL_CHAIN (p);
	}
      cexpr.body = tree_node ();
      cexpr.decl = decl;
    }
  else
    cexpr.decl = NULL_TREE;

  unsigned flags = u ();

  if (get_overrun ())
    return NULL_TREE;

  if (installing)
    {
      DECL_NOT_REALLY_EXTERN (decl) = flags & 1;
      DECL_RESULT (decl) = result;
      DECL_INITIAL (decl) = initial;
      DECL_SAVED_TREE (decl) = saved;
      if (maybe_dup)
	DECL_ARGUMENTS (decl) = DECL_ARGUMENTS (maybe_dup);

      if (context)
	SET_DECL_FRIEND_CONTEXT (decl, context);
      if (cexpr.decl)
	register_constexpr_fundef (cexpr);
      post_process (maybe_template);
    }
  else if (maybe_dup)
    {
      // FIXME:QOI Check matching defn
    }
  
  return true;
}

/* Also for CONCEPT_DECLs.  */

void
trees_out::write_var_def (tree decl)
{
  tree init = DECL_INITIAL (decl);
  tree_node (init);
  if (!init)
    {
      tree dyn_init = NULL_TREE;

      if (DECL_NONTRIVIALLY_INITIALIZED_P (decl))
	{
	  dyn_init = value_member (decl,
				   CP_DECL_THREAD_LOCAL_P (decl)
				   ? tls_aggregates : static_aggregates);
	  gcc_checking_assert (dyn_init);
	  /* Mark it so write_inits knows this is needed.  */
	  TREE_LANG_FLAG_0 (dyn_init) = true;
	  dyn_init = TREE_PURPOSE (dyn_init);
	}
      tree_node (dyn_init);
    }
}

void
trees_out::mark_var_def (tree)
{
}

bool
trees_in::read_var_def (tree decl, tree maybe_template)
{
  /* Do not mark the virtual table entries as used.  */
  bool vtable = TREE_CODE (decl) == VAR_DECL && DECL_VTABLE_OR_VTT_P (decl);
  unused += vtable;
  tree init = tree_node ();
  tree dyn_init = init ? NULL_TREE : tree_node ();
  unused -= vtable;

  if (get_overrun ())
    return false;

  bool initialized = (VAR_P (decl) ? bool (DECL_INITIALIZED_P (decl))
		      : bool (DECL_INITIAL (decl)));
  tree maybe_dup = odr_duplicate (maybe_template, initialized);
  bool installing = maybe_dup && !initialized;
  if (installing)
    {
      if (DECL_EXTERNAL (decl))
	DECL_NOT_REALLY_EXTERN (decl) = true;
      if (VAR_P (decl))
	{
	  DECL_INITIALIZED_P (decl) = true;
	  if (maybe_dup && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (maybe_dup))
	    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
	}
      DECL_INITIAL (decl) = init;
      if (!dyn_init)
	;
      else if (CP_DECL_THREAD_LOCAL_P (decl))
	tls_aggregates = tree_cons (dyn_init, decl, tls_aggregates);
      else
	static_aggregates = tree_cons (dyn_init, decl, static_aggregates);
    }
  else if (maybe_dup)
    {
      // FIXME:QOI Check matching defn
    }

  return true;
}

/* If MEMBER doesn't have an independent life outside the class,
   return it (or it's TEMPLATE_DECL).  Otherwise NULL.  */

static tree
member_owned_by_class (tree member)
{
  gcc_assert (DECL_P (member));

  /* Clones are owned by their origin.  */
  if (DECL_CLONED_FUNCTION_P (member))
    return NULL;

  if (TREE_CODE (member) == FIELD_DECL)
    /* FIELD_DECLS can have template info in some cases.  We always
       want the FIELD_DECL though, as there's never a TEMPLATE_DECL
       wrapping them.  */
    return member;

  int use_tpl = -1;
  if (tree ti = node_template_info (member, use_tpl))
    {
      // FIXME: Don't bail on things that CANNOT have their own
      // template header.  No, make sure they're in the same cluster.
      if (use_tpl > 0)
	return NULL_TREE;

      if (DECL_TEMPLATE_RESULT (TI_TEMPLATE (ti)) == member)
	member = TI_TEMPLATE (ti);
    }
  return member;
}

void
trees_out::write_class_def (tree defn)
{
  gcc_assert (DECL_P (defn));
  if (streaming_p ())
    dump () && dump ("Writing class definition %N", defn);

  tree type = TREE_TYPE (defn);
  tree_node (TYPE_SIZE (type));
  tree_node (TYPE_SIZE_UNIT (type));
  tree_node (TYPE_VFIELD (type));
  tree_node (TYPE_BINFO (type));

  vec_chained_decls (TYPE_FIELDS (type));

  /* Every class but __as_base has a type-specific.  */
  gcc_checking_assert (!TYPE_LANG_SPECIFIC (type) == IS_FAKE_BASE_TYPE (type));

  if (TYPE_LANG_SPECIFIC (type))
    {
      {
	vec<tree, va_gc> *v = CLASSTYPE_MEMBER_VEC (type);
	if (!v)
	  {
	    gcc_checking_assert (!streaming_p ());
	    /* Force a class vector.  */
	    v = set_class_bindings (type, -1);
	    gcc_checking_assert (v);
	  }

	unsigned len = v->length ();
	if (streaming_p ())
	  u (len);
	for (unsigned ix = 0; ix != len; ix++)
	  {
	    tree m = (*v)[ix];
	    if (TREE_CODE (m) == TYPE_DECL
		&& DECL_ARTIFICIAL (m)
		&& TYPE_STUB_DECL (TREE_TYPE (m)) == m)
	      /* This is a using-decl for a type, or an anonymous
		 struct (maybe with a typedef name).  Write the type.  */
	      m = TREE_TYPE (m);
	    tree_node (m);
	  }
      }
      tree_node (CLASSTYPE_LAMBDA_EXPR (type));

      /* TYPE_CONTAINS_VPTR_P looks at the vbase vector, which the
	 reader won't know at this point.  */
      int has_vptr = TYPE_CONTAINS_VPTR_P (type);

      if (streaming_p ())
	{
	  unsigned nvbases = vec_safe_length (CLASSTYPE_VBASECLASSES (type));
	  u (nvbases);
	  i (has_vptr);
	}

      if (has_vptr)
	{
	  tree_vec (CLASSTYPE_PURE_VIRTUALS (type));
	  tree_pair_vec (CLASSTYPE_VCALL_INDICES (type));
	  tree_node (CLASSTYPE_KEY_METHOD (type));
	}
    }

  if (TYPE_LANG_SPECIFIC (type))
    {
      tree_node (CLASSTYPE_PRIMARY_BINFO (type));

      tree as_base = CLASSTYPE_AS_BASE (type);
      if (as_base)
	as_base = TYPE_NAME (as_base);
      tree_node (as_base);

      /* Write the vtables.  */
      tree vtables = CLASSTYPE_VTABLES (type);
      vec_chained_decls (vtables);
      for (; vtables; vtables = TREE_CHAIN (vtables))
	write_definition (vtables);

      /* Write the friend classes.  */
      tree_list (CLASSTYPE_FRIEND_CLASSES (type), false);

      /* Write the friend functions.  */
      for (tree friends = DECL_FRIENDLIST (defn);
	   friends; friends = TREE_CHAIN (friends))
	{
	  /* Name of these friends.  */
	  tree_node (TREE_PURPOSE (friends));
	  tree_list (TREE_VALUE (friends), false);
	}
      /* End of friend fns.  */
      tree_node (NULL_TREE);

      /* Write the decl list.  */
      tree_list (CLASSTYPE_DECL_LIST (type), true);

      if (TYPE_CONTAINS_VPTR_P (type))
	{
	  /* Write the thunks.  */
	  for (tree decls = TYPE_FIELDS (type);
	       decls; decls = DECL_CHAIN (decls))
	    if (TREE_CODE (decls) == FUNCTION_DECL
		&& DECL_VIRTUAL_P (decls)
		&& DECL_THUNKS (decls))
	      {
		tree_node (decls);
		/* Thunks are always unique, so chaining is ok.  */
		chained_decls (DECL_THUNKS (decls));
	      }
	  tree_node (NULL_TREE);
	}
    }
}

void
trees_out::mark_class_member (tree member, bool do_defn)
{
  gcc_assert (DECL_P (member));

  member = member_owned_by_class (member);
  if (member)
    mark_declaration (member, do_defn && has_definition (member));
}

void
trees_out::mark_class_def (tree defn)
{
  gcc_assert (DECL_P (defn));
  tree type = TREE_TYPE (defn);
  /* Mark the class members that are not type-decls and cannot have
     independent definitions.  */
  for (tree member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
    if (TREE_CODE (member) == FIELD_DECL
	|| TREE_CODE (member) == USING_DECL
	/* A cloned enum-decl from 'using enum unrelated;'   */
	|| (TREE_CODE (member) == CONST_DECL
	    && DECL_CONTEXT (member) == type))
      {
	mark_class_member (member);
	if (TREE_CODE (member) == FIELD_DECL)
	  if (tree repr = DECL_BIT_FIELD_REPRESENTATIVE (member))
	    mark_declaration (repr, false);
      }

  /* Mark the binfo hierarchy.  */
  for (tree child = TYPE_BINFO (type); child; child = TREE_CHAIN (child))
    mark_by_value (child);

  if (TYPE_LANG_SPECIFIC (type))
    {
      for (tree vtable = CLASSTYPE_VTABLES (type);
	   vtable; vtable = TREE_CHAIN (vtable))
	mark_declaration (vtable, true);

      if (TYPE_CONTAINS_VPTR_P (type))
	/* Mark the thunks, they belong to the class definition,
	   /not/ the thunked-to function.  */
	for (tree decls = TYPE_FIELDS (type);
	     decls; decls = DECL_CHAIN (decls))
	  if (TREE_CODE (decls) == FUNCTION_DECL)
	    for (tree thunks = DECL_THUNKS (decls);
		 thunks; thunks = DECL_CHAIN (thunks))
	      mark_declaration (thunks, false);
    }
}

/* Nop sorting, needed for resorting the member vec.  */

static void
nop (void *, void *)
{
}

bool
trees_in::read_class_def (tree defn, tree maybe_template)
{
  gcc_assert (DECL_P (defn));
  dump () && dump ("Reading class definition %N", defn);
  tree type = TREE_TYPE (defn);
  tree size = tree_node ();
  tree size_unit = tree_node ();
  tree vfield = tree_node ();
  tree binfo = tree_node ();
  vec<tree, va_gc> *vbase_vec = NULL;
  vec<tree, va_gc> *member_vec = NULL;
  vec<tree, va_gc> *pure_virts = NULL;
  vec<tree_pair_s, va_gc> *vcall_indices = NULL;
  tree key_method = NULL_TREE;
  tree lambda = NULL_TREE;

  /* Read the fields.  */
  vec<tree, va_heap> *fields = vec_chained_decls ();

  if (TYPE_LANG_SPECIFIC (type))
    {
      if (unsigned len = u ())
	{
	  vec_alloc (member_vec, len);
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      tree m = tree_node ();
	      if (get_overrun ())
		break;
	      if (TYPE_P (m))
		m = TYPE_STUB_DECL (m);
	      member_vec->quick_push (m);
	    }
	}
      lambda = tree_node ();

      if (!get_overrun ())
	{
	  unsigned nvbases = u ();
	  if (nvbases)
	    {
	      vec_alloc (vbase_vec, nvbases);
	      for (tree child = binfo; child; child = TREE_CHAIN (child))
		if (BINFO_VIRTUAL_P (child))
		  vbase_vec->quick_push (child);
	    }
	}

      if (!get_overrun ())
	{
	  int has_vptr = i ();
	  if (has_vptr)
	    {
	      pure_virts = tree_vec ();
	      vcall_indices = tree_pair_vec ();
	      key_method = tree_node ();
	    }
	}
    }

  tree maybe_dup = odr_duplicate (maybe_template, TYPE_SIZE (type));
  bool installing = maybe_dup && !TYPE_SIZE (type);
  if (installing)
    {
      if (DECL_EXTERNAL (defn) && TYPE_LANG_SPECIFIC (type))
	{
	  /* We don't deal with not-really-extern, because, for a
	     module you want the import to be the interface, and for a
	     header-unit, you're doing it wrong.  */
	  CLASSTYPE_INTERFACE_UNKNOWN (type) = false;
	  CLASSTYPE_INTERFACE_ONLY (type) = true;
	}

      if (maybe_dup != defn)
	{
	  // FIXME: This is needed on other defns too, almost
	  // duplicate-decl like?  See is_matching_decl too.
	  /* Copy flags from the duplicate.  */
	  tree type_dup = TREE_TYPE (maybe_dup);

	  /* Core pieces.  */
	  TYPE_MODE_RAW (type) = TYPE_MODE_RAW (type_dup);
	  SET_DECL_MODE (defn, DECL_MODE (maybe_dup));
	  TREE_ADDRESSABLE (type) = TREE_ADDRESSABLE (type_dup);
	  DECL_SIZE (defn) = DECL_SIZE (maybe_dup);
	  DECL_SIZE_UNIT (defn) = DECL_SIZE_UNIT (maybe_dup);
	  DECL_ALIGN_RAW (defn) = DECL_ALIGN_RAW (maybe_dup);
	  DECL_WARN_IF_NOT_ALIGN_RAW (defn)
	    = DECL_WARN_IF_NOT_ALIGN_RAW (maybe_dup);
	  DECL_USER_ALIGN (defn) = DECL_USER_ALIGN (maybe_dup);

	  /* C++ pieces.  */
	  TYPE_POLYMORPHIC_P (type) = TYPE_POLYMORPHIC_P (type_dup);
	  TYPE_HAS_USER_CONSTRUCTOR (type)
	    = TYPE_HAS_USER_CONSTRUCTOR (type_dup);
	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
	    = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type_dup);

	  if (auto ls = TYPE_LANG_SPECIFIC (type_dup))
	    {
	      if (TYPE_LANG_SPECIFIC (type))
		{
		  CLASSTYPE_BEFRIENDING_CLASSES (type_dup)
		    = CLASSTYPE_BEFRIENDING_CLASSES (type);
		  CLASSTYPE_TYPEINFO_VAR (type_dup)
		    = CLASSTYPE_TYPEINFO_VAR (type);
		}
	      for (tree v = type; v; v = TYPE_NEXT_VARIANT (v))
		TYPE_LANG_SPECIFIC (v) = ls;
	    }
	}

      TYPE_SIZE (type) = size;
      TYPE_SIZE_UNIT (type) = size_unit;

      if (fields)
	{
	  tree *chain = &TYPE_FIELDS (type);
	  unsigned len = fields->length ();
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      tree decl = (*fields)[ix];

	      if (!decl)
		{
		  /* An anonymous struct with typedef name.  */
		  tree tdef = (*fields)[ix+1];
		  decl = TYPE_STUB_DECL (TREE_TYPE (tdef));
		  gcc_checking_assert (IDENTIFIER_ANON_P (DECL_NAME (decl))
				       && decl != tdef);
		}

	      gcc_checking_assert (!*chain == !DECL_CLONED_FUNCTION_P (decl));
	      *chain = decl;
	      chain = &DECL_CHAIN (decl);

	      if (TREE_CODE (decl) == USING_DECL
		  && TREE_CODE (USING_DECL_SCOPE (decl)) == RECORD_TYPE)
		{
		  /* Reconstruct DECL_ACCESS.  */
		  tree decls = USING_DECL_DECLS (decl);
		  tree access = declared_access (decl);

		  for (ovl_iterator iter (decls); iter; ++iter)
		    {
		      tree d = *iter;

		      retrofit_lang_decl (d);
		      tree list = DECL_ACCESS (d);

		      if (!purpose_member (type, list))
			DECL_ACCESS (d) = tree_cons (type, access, list);
		    }
		}
	    }
	}

      TYPE_VFIELD (type) = vfield;
      TYPE_BINFO (type) = binfo;

      if (TYPE_LANG_SPECIFIC (type))
	{
	  CLASSTYPE_LAMBDA_EXPR (type) = lambda;

	  CLASSTYPE_MEMBER_VEC (type) = member_vec;
	  CLASSTYPE_PURE_VIRTUALS (type) = pure_virts;
	  CLASSTYPE_VCALL_INDICES (type) = vcall_indices;

	  CLASSTYPE_KEY_METHOD (type) = key_method;

	  CLASSTYPE_VBASECLASSES (type) = vbase_vec;

	  /* Resort the member vector.  */
	  resort_type_member_vec (member_vec, NULL, nop, NULL);
	}
    }
  else if (maybe_dup)
    {
      // FIXME:QOI Check matching defn
    }

  if (TYPE_LANG_SPECIFIC (type))
    {
      tree primary = tree_node ();
      tree as_base = tree_node ();

      if (as_base)
	as_base = TREE_TYPE (as_base);

      /* Read the vtables.  */
      vec<tree, va_heap> *vtables = vec_chained_decls ();
      if (vtables)
	{
	  unsigned len = vtables->length ();
	  for (unsigned ix = 0; ix != len; ix++)
	    {
	      tree vtable = (*vtables)[ix];
	      read_var_def (vtable, vtable);
	    }
	}

      tree friend_classes = tree_list (false);
      tree friend_functions = NULL_TREE;
      for (tree *chain = &friend_functions;
	   tree name = tree_node (); chain = &TREE_CHAIN (*chain))
	{
	  tree val = tree_list (false);
	  *chain = build_tree_list (name, val);
	}
      tree decl_list = tree_list (true);

      if (installing)
	{
	  CLASSTYPE_PRIMARY_BINFO (type) = primary;
	  CLASSTYPE_AS_BASE (type) = as_base;

	  if (vtables)
	    {
	      if (!CLASSTYPE_KEY_METHOD (type)
		  /* Sneaky user may have defined it inline
		     out-of-class.  */
		  || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type)))
		vec_safe_push (keyed_classes, type);
	      unsigned len = vtables->length ();
	      tree *chain = &CLASSTYPE_VTABLES (type);
	      for (unsigned ix = 0; ix != len; ix++)
		{
		  tree vtable = (*vtables)[ix];
		  gcc_checking_assert (!*chain);
		  *chain = vtable;
		  chain = &DECL_CHAIN (vtable);
		}
	    }
	  CLASSTYPE_FRIEND_CLASSES (type) = friend_classes;
	  DECL_FRIENDLIST (defn) = friend_functions;
	  CLASSTYPE_DECL_LIST (type) = decl_list;

	  for (; friend_classes; friend_classes = TREE_CHAIN (friend_classes))
	    {
	      tree f = TREE_VALUE (friend_classes);

	      if (TYPE_P (f))
		{
		  CLASSTYPE_BEFRIENDING_CLASSES (f)
		    = tree_cons (NULL_TREE, type,
				 CLASSTYPE_BEFRIENDING_CLASSES (f));
		  dump () && dump ("Class %N befriending %C:%N",
				   type, TREE_CODE (f), f);
		}
	    }

	  for (; friend_functions;
	       friend_functions = TREE_CHAIN (friend_functions))
	    for (tree friend_decls = TREE_VALUE (friend_functions);
		 friend_decls; friend_decls = TREE_CHAIN (friend_decls))
	      {
		tree f = TREE_VALUE (friend_decls);
		
		DECL_BEFRIENDING_CLASSES (f)
		  = tree_cons (NULL_TREE, type, DECL_BEFRIENDING_CLASSES (f));
		dump () && dump ("Class %N befriending %C:%N",
				 type, TREE_CODE (f), f);
	      }
	}

      if (TYPE_CONTAINS_VPTR_P (type))
	/* Read and install the thunks.  */
	while (tree vfunc = tree_node ())
	  {
	    tree thunks = chained_decls ();
	    if (installing)
	      SET_DECL_THUNKS (vfunc, thunks);
	  }

      vec_free (vtables);
    }

  /* Propagate to all variants.  */
  if (installing)
    fixup_type_variants (type);

  /* IS_FAKE_BASE_TYPE is inaccurate at this point, because if this is
     the fake base, we've not hooked it into the containing class's
     data structure yet.  Fortunately it has a unique name.  */
  if (installing
      && DECL_NAME (defn) != as_base_identifier
      && (!CLASSTYPE_TEMPLATE_INFO (type)
	  || !uses_template_parms (TI_ARGS (CLASSTYPE_TEMPLATE_INFO (type)))))
    /* Emit debug info.  It'd be nice to know if the interface TU
       already emitted this.  */
    rest_of_type_compilation (type, !LOCAL_CLASS_P (type));

  vec_free (fields);

  return !get_overrun ();
}

void
trees_out::write_enum_def (tree decl)
{
  tree type = TREE_TYPE (decl);

  tree_node (TYPE_VALUES (type));
  tree_node (TYPE_MIN_VALUE (type));
  tree_node (TYPE_MAX_VALUE (type));
}

void
trees_out::mark_enum_def (tree decl)
{
  tree type = TREE_TYPE (decl);

  for (tree values = TYPE_VALUES (type); values; values = TREE_CHAIN (values))
    {
      tree cst = TREE_VALUE (values);
      mark_by_value (cst);
      /* We must mark the init to avoid circularity in tt_enum_int.  */
      if (tree init = DECL_INITIAL (cst))
	if (TREE_CODE (init) == INTEGER_CST)
	  mark_by_value (init);
    }
}

bool
trees_in::read_enum_def (tree defn, tree maybe_template)
{
  tree type = TREE_TYPE (defn);
  tree values = tree_node ();
  tree min = tree_node ();
  tree max = tree_node ();

  if (get_overrun ())
    return false;

  tree maybe_dup = odr_duplicate (maybe_template, TYPE_VALUES (type));
  bool installing = maybe_dup && !TYPE_VALUES (type);

  if (installing)
    {
      TYPE_VALUES (type) = values;
      TYPE_MIN_VALUE (type) = min;
      TYPE_MAX_VALUE (type) = max;

      rest_of_type_compilation (type, DECL_NAMESPACE_SCOPE_P (defn));
    }
  else if (maybe_dup)
    {
      tree known = TYPE_VALUES (type);
      for (; known && values;
	   known = TREE_CHAIN (known), values = TREE_CHAIN (values))
	{
	  tree known_decl = TREE_VALUE (known);
	  tree new_decl = TREE_VALUE (values);

	  if (DECL_NAME (known_decl) != DECL_NAME (new_decl))
	    goto bad;
	      
	  new_decl = maybe_duplicate (new_decl);

	  if (!cp_tree_equal (DECL_INITIAL (known_decl),
			      DECL_INITIAL (new_decl)))
	    goto bad;
	}

      if (known || values)
	goto bad;

      if (!cp_tree_equal (TYPE_MIN_VALUE (type), min)
	  || !cp_tree_equal (TYPE_MAX_VALUE (type), max))
	{
	bad:;
	  error_at (DECL_SOURCE_LOCATION (maybe_dup),
		    "definition of %qD does not match", maybe_dup);
	  inform (DECL_SOURCE_LOCATION (defn),
		  "existing definition %qD", defn);

	  tree known_decl = NULL_TREE, new_decl = NULL_TREE;

	  if (known)
	    known_decl = TREE_VALUE (known);
	  if (values)
	    new_decl = maybe_duplicate (TREE_VALUE (values));

	  if (known_decl && new_decl)
	    {
	      inform (DECL_SOURCE_LOCATION (new_decl),
		      "... this enumerator %qD", new_decl);
	      inform (DECL_SOURCE_LOCATION (known_decl),
		      "enumerator %qD does not match ...", known_decl);
	    }
	  else if (known_decl || new_decl)
	    {
	      tree extra = known_decl ? known_decl : new_decl;
	      inform (DECL_SOURCE_LOCATION (extra),
		      "additional enumerators beginning with %qD", extra);
	    }
	  else
	    inform (DECL_SOURCE_LOCATION (maybe_dup),
		    "enumeration range differs");

	  /* Mark it bad.  */
	  unmatched_duplicate (maybe_template);
	}
    }

  return true;
}

/* Write out the body of DECL.  See above circularity note.  */

void
trees_out::write_definition (tree decl)
{
  if (streaming_p ())
    {
      assert_definition (decl);
      dump ()
	&& dump ("Writing definition %C:%N", TREE_CODE (decl), decl);
    }
  else
    dump (dumper::DEPEND)
      && dump ("Depending definition %C:%N", TREE_CODE (decl), decl);

 again:
  switch (TREE_CODE (decl))
    {
    default:
      gcc_unreachable ();

    case TEMPLATE_DECL:
      decl = DECL_TEMPLATE_RESULT (decl);
      goto again;

    case FUNCTION_DECL:
      write_function_def (decl);
      break;

    case TYPE_DECL:
      {
	tree type = TREE_TYPE (decl);
	gcc_assert (TYPE_MAIN_VARIANT (type) == type
		    && TYPE_NAME (type) == decl);
	if (TREE_CODE (type) == ENUMERAL_TYPE)
	  write_enum_def (decl);
	else
	  write_class_def (decl);
      }
      break;

    case VAR_DECL:
    case CONCEPT_DECL:
      write_var_def (decl);
      break;
    }
}

/* Mark a declaration for by-value walking.  If DO_DEFN is true, mark
   its body too.  */

void
trees_out::mark_declaration (tree decl, bool do_defn)
{
  mark_by_value (decl);

  if (TREE_CODE (decl) == TEMPLATE_DECL)
    decl = DECL_TEMPLATE_RESULT (decl);

  if (!do_defn)
    return;

  switch (TREE_CODE (decl))
    {
    default:
      gcc_unreachable ();

    case FUNCTION_DECL:
      mark_function_def (decl);
      break;

    case TYPE_DECL:
      {
	tree type = TREE_TYPE (decl);
	gcc_assert (TYPE_MAIN_VARIANT (type) == type
		    && TYPE_NAME (type) == decl);
	if (TREE_CODE (type) == ENUMERAL_TYPE)
	  mark_enum_def (decl);
	else
	  mark_class_def (decl);
      }
      break;

    case VAR_DECL:
    case CONCEPT_DECL:
      mark_var_def (decl);
      break;
    }
}

/* Read in the body of DECL.  See above circularity note.  */

bool
trees_in::read_definition (tree decl)
{
  dump () && dump ("Reading definition %C %N", TREE_CODE (decl), decl);

  tree maybe_template = decl;

 again:
  switch (TREE_CODE (decl))
    {
    default:
      break;

    case TEMPLATE_DECL:
      decl = DECL_TEMPLATE_RESULT (decl);
      goto again;

    case FUNCTION_DECL:
      return read_function_def (decl, maybe_template);

    case TYPE_DECL:
      {
	tree type = TREE_TYPE (decl);
	gcc_assert (TYPE_MAIN_VARIANT (type) == type
		    && TYPE_NAME (type) == decl);
	if (TREE_CODE (type) == ENUMERAL_TYPE)
	  return read_enum_def (decl, maybe_template);
	else
	  return read_class_def (decl, maybe_template);
      }
      break;

    case VAR_DECL:
    case CONCEPT_DECL:
      return read_var_def (decl, maybe_template);
    }

  return false;
}

/* Lookup an maybe insert a slot for depset for KEY.  */

depset **
depset::hash::entity_slot (tree entity, bool insert)
{
  traits::compare_type key (entity, NULL);
  depset **slot = find_slot_with_hash (key, traits::hash (key),
				       insert ? INSERT : NO_INSERT);

  return slot;
}

depset **
depset::hash::binding_slot (tree ctx, tree name, bool insert)
{
  traits::compare_type key (ctx, name);
  depset **slot = find_slot_with_hash (key, traits::hash (key),
				       insert ? INSERT : NO_INSERT);

  return slot;
}

depset *
depset::hash::find_dependency (tree decl)
{
  depset **slot = entity_slot (decl, false);

  return slot ? *slot : NULL;
}

depset *
depset::hash::find_binding (tree ctx, tree name)
{
  depset **slot = binding_slot (ctx, name, false);

  return slot ? *slot : NULL;
}

/* DECL is a newly discovered dependency.  Create the depset, if it
   doesn't already exist.  Add it to the worklist if so.

   DECL will be an OVL_USING_P OVERLOAD, if it's from a binding that's
   a using decl.

   We do not have to worry about adding the same dependency more than
   once.  First it's harmless, but secondly the TREE_VISITED marking
   prevents us wanting to do it anyway.  */

depset *
depset::hash::make_dependency (tree decl, entity_kind ek)
{
  /* Make sure we're being told consistent information.  */
  gcc_checking_assert ((ek == EK_NAMESPACE)
		       == (TREE_CODE (decl) == NAMESPACE_DECL
			   && !DECL_NAMESPACE_ALIAS (decl)));
  gcc_checking_assert (ek != EK_BINDING && ek != EK_REDIRECT);
  gcc_checking_assert (TREE_CODE (decl) != FIELD_DECL
		       && (TREE_CODE (decl) != USING_DECL
			   || TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL));
  gcc_checking_assert (!is_key_order ());
  if (ek == EK_USING)
    gcc_checking_assert (TREE_CODE (decl) == OVERLOAD);

  if (TREE_CODE (decl) == TEMPLATE_DECL)
    /* The template should have copied these from its result decl.  */
    gcc_checking_assert (DECL_MODULE_EXPORT_P (decl)
			 == DECL_MODULE_EXPORT_P (DECL_TEMPLATE_RESULT (decl)));

  depset **slot = entity_slot (decl, true);
  depset *dep = *slot;
  bool for_binding = ek == EK_FOR_BINDING;

  if (!dep)
    {
      if (DECL_IMPLICIT_TYPEDEF_P (decl)
	  /* ... not an enum, for instance.  */
	  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
	  && TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
	  && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2)
	{
	  /* A partial or explicit specialization. Partial
	     specializations might not be in the hash table, because
	     there can be multiple differently-constrained variants.

	     template<typename T> class silly;
	     template<typename T> requires true class silly {};

	     We need to find them, insert their TEMPLATE_DECL in the
	     dep_hash, and then convert the dep we just found into a
	     redirect.  */

	  tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (decl));
	  tree tmpl = TI_TEMPLATE (ti);
	  tree partial = NULL_TREE;
	  for (tree spec = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
	       spec; spec = TREE_CHAIN (spec))
	    if (DECL_TEMPLATE_RESULT (TREE_VALUE (spec)) == decl)
	      {
		partial = TREE_VALUE (spec);
		break;
	      }

	  if (partial)
	    {
	      /* Eagerly create an empty redirect.  The following
	         make_dependency call could cause hash reallocation,
	         and invalidate slot's value.  */
	      depset *redirect = make_entity (decl, EK_REDIRECT);

	      /* Redirects are never reached -- always snap to their target.  */
	      redirect->set_flag_bit<DB_UNREACHED_BIT> ();

	      *slot = redirect;

	      depset *tmpl_dep = make_dependency (partial, EK_PARTIAL);
	      gcc_checking_assert (tmpl_dep->get_entity_kind () == EK_PARTIAL);

	      redirect->deps.safe_push (tmpl_dep);

	      return redirect;
	    }
	}

      bool has_def = ek != EK_USING && has_definition (decl);
      if (ek > EK_BINDING)
	ek = EK_DECL;

      /* The only OVERLOADS we should see are USING decls from
	 bindings.  */
      *slot = dep = make_entity (decl, ek, has_def);

      if (TREE_CODE (decl) == TEMPLATE_DECL)
	{
	  if (DECL_ALIAS_TEMPLATE_P (decl) && DECL_TEMPLATE_INFO (decl))
	    dep->set_flag_bit<DB_ALIAS_TMPL_INST_BIT> ();
	  else if (CHECKING_P)
	    /* The template_result should otherwise not be in the
	       table, or be an empty redirect (created above).  */
	    if (auto *eslot = entity_slot (DECL_TEMPLATE_RESULT (decl), false))
	      gcc_checking_assert ((*eslot)->get_entity_kind () == EK_REDIRECT
				   && !(*eslot)->deps.length ());
	}

      if (ek != EK_USING)
	{
	  tree not_tmpl = STRIP_TEMPLATE (decl);

	  if (DECL_LANG_SPECIFIC (not_tmpl)
	      && DECL_MODULE_IMPORT_P (not_tmpl))
	    {
	      /* Store the module number and index in cluster/section,
		 so we don't have to look them up again.  */
	      unsigned index = import_entity_index (decl);
	      module_state *from = import_entity_module (index);
	      /* Remap will be zero for imports from partitions, which
		 we want to treat as-if declared in this TU.  */
	      if (from->remap)
		{
		  dep->cluster = index - from->entity_lwm;
		  dep->section = from->remap;
		  dep->set_flag_bit<DB_IMPORTED_BIT> ();
		}
	    }

	  if (ek == EK_DECL
	      && !dep->is_import ()
	      && TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL
	      && !(TREE_CODE (decl) == TEMPLATE_DECL
		   && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)))
	    {
	      tree ctx = CP_DECL_CONTEXT (decl);

	      if (!TREE_PUBLIC (ctx))
		/* Member of internal namespace.  */
		dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
	      else if (VAR_OR_FUNCTION_DECL_P (not_tmpl)
		       && DECL_THIS_STATIC (not_tmpl))
		{
		  /* An internal decl.  This is ok in a GM entity.  */
		  if (!(header_module_p ()
			|| !DECL_LANG_SPECIFIC (not_tmpl)
			|| !DECL_MODULE_PURVIEW_P (not_tmpl)))
		    dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
		}
	    }
	}

      if (!dep->is_import ())
	worklist.safe_push (dep);
    }

  dump (dumper::DEPEND)
    && dump ("%s on %s %C:%N found",
	     ek == EK_REDIRECT ? "Redirect"
	     : for_binding ? "Binding" : "Dependency",
	     dep->entity_kind_name (), TREE_CODE (decl), decl);

  return dep;
}

/* DEP is a newly discovered dependency.  Append it to current's
   depset.  */

void
depset::hash::add_dependency (depset *dep)
{
  gcc_checking_assert (current && !is_key_order ());
  current->deps.safe_push (dep);

  if (dep->is_internal () && !current->is_internal ())
    current->set_flag_bit<DB_REFS_INTERNAL_BIT> ();

  if (current->get_entity_kind () == EK_USING
      && DECL_IMPLICIT_TYPEDEF_P (dep->get_entity ())
      && TREE_CODE (TREE_TYPE (dep->get_entity ())) == ENUMERAL_TYPE)
    {
      /* CURRENT is an unwrapped using-decl and DECL is an enum's
	 implicit typedef.  Is CURRENT a member of the enum?  */
      tree c_decl = OVL_FUNCTION (current->get_entity ());

      if (TREE_CODE (c_decl) == CONST_DECL
	  && (current->deps[0]->get_entity ()
	      == CP_DECL_CONTEXT (dep->get_entity ())))
	/* Make DECL depend on CURRENT.  */
	dep->deps.safe_push (current);
    }

  if (dep->is_unreached ())
    {
      /* The dependency is reachable now.  */
      reached_unreached = true;
      dep->clear_flag_bit<DB_UNREACHED_BIT> ();
      dump (dumper::DEPEND)
	&& dump ("Reaching unreached %s %C:%N", dep->entity_kind_name (),
		 TREE_CODE (dep->get_entity ()), dep->get_entity ());
    }
}

depset *
depset::hash::add_dependency (tree decl, entity_kind ek)
{
  depset *dep;

  if (is_key_order ())
    {
      dep = find_dependency (decl);
      if (dep)
	{
	  current->deps.safe_push (dep);
	  dump (dumper::MERGE)
	    && dump ("Key dependency on %s %C:%N found",
		     dep->entity_kind_name (), TREE_CODE (decl), decl);
	}
      else
	{
	  /* It's not a mergeable decl, look for it in the original
	     table.  */
	  dep = chain->find_dependency (decl);
	  gcc_checking_assert (dep);
	}
    }
  else
    {
      dep = make_dependency (decl, ek);
      if (dep->get_entity_kind () != EK_REDIRECT)
	add_dependency (dep);
    }

  return dep;
}

void
depset::hash::add_namespace_context (depset *dep, tree ns)
{
  depset *ns_dep = make_dependency (ns, depset::EK_NAMESPACE);
  dep->deps.safe_push (ns_dep);

  /* Mark it as special if imported so we don't walk connect when
     SCCing.  */
  if (!dep->is_binding () && ns_dep->is_import ())
    dep->set_special ();
}

struct add_binding_data
{
  tree ns;
  bitmap partitions;
  depset *binding;
  depset::hash *hash;
  bool met_namespace;
};

/* Return true if we are, or contain something that is exported.  */

bool
depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_)
{
  auto data = static_cast <add_binding_data *> (data_);

  if (!(TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl)))
    {
      tree inner = decl;

      if (TREE_CODE (inner) == CONST_DECL
	  && TREE_CODE (DECL_CONTEXT (inner)) == ENUMERAL_TYPE)
	inner = TYPE_NAME (DECL_CONTEXT (inner));
      else if (TREE_CODE (inner) == TEMPLATE_DECL)
	inner = DECL_TEMPLATE_RESULT (inner);

      if (!DECL_LANG_SPECIFIC (inner) || !DECL_MODULE_PURVIEW_P (inner))
	/* Ignore global module fragment entities.  */
	return false;

      if (VAR_OR_FUNCTION_DECL_P (inner)
	  && DECL_THIS_STATIC (inner))
	{
	  if (!header_module_p ())
	    /* Ignore internal-linkage entitites.  */
	    return false;
	}

      if ((TREE_CODE (decl) == VAR_DECL
	   || TREE_CODE (decl) == TYPE_DECL)
	  && DECL_TINFO_P (decl))
	/* Ignore TINFO things.  */
	return false;

      if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns)
	{
	  /* A using that lost its wrapper or an unscoped enum
	     constant.  */
	  flags = WMB_Flags (flags | WMB_Using);
	  if (DECL_MODULE_EXPORT_P (TREE_CODE (decl) == CONST_DECL
				    ? TYPE_NAME (TREE_TYPE (decl))
				    : STRIP_TEMPLATE (decl)))
	    flags = WMB_Flags (flags | WMB_Export);
	}

      if (!data->binding)
	/* No binding to check.  */;
      else if (flags & WMB_Using)
	{
	  /* Look in the binding to see if we already have this
	     using.  */
	  for (unsigned ix = data->binding->deps.length (); --ix;)
	    {
	      depset *d = data->binding->deps[ix];
	      if (d->get_entity_kind () == EK_USING
		  && OVL_FUNCTION (d->get_entity ()) == decl)
		{
		  if (!(flags & WMB_Hidden))
		    d->clear_hidden_binding ();
		  if (flags & WMB_Export)
		    OVL_EXPORT_P (d->get_entity ()) = true;
		  return bool (flags & WMB_Export);
		}
	    }
	}
      else if (flags & WMB_Dups)
	{
	  /* Look in the binding to see if we already have this decl.  */
	  for (unsigned ix = data->binding->deps.length (); --ix;)
	    {
	      depset *d = data->binding->deps[ix];
	      if (d->get_entity () == decl)
		{
		  if (!(flags & WMB_Hidden))
		    d->clear_hidden_binding ();
		  return false;
		}
	    }
	}

      /* We're adding something.  */
      if (!data->binding)
	{
	  data->binding = make_binding (data->ns, DECL_NAME (decl));
	  data->hash->add_namespace_context (data->binding, data->ns);

	  depset **slot = data->hash->binding_slot (data->ns,
						    DECL_NAME (decl), true);
	  gcc_checking_assert (!*slot);
	  *slot = data->binding;
	}

      /* Make sure nobody left a tree visited lying about.  */
      gcc_checking_assert (!TREE_VISITED (decl));

      if (flags & WMB_Using)
	{
	  decl = ovl_make (decl, NULL_TREE);
	  if (flags & WMB_Export)
	    OVL_EXPORT_P (decl) = true;
	}

      depset *dep = data->hash->make_dependency
	(decl, flags & WMB_Using ? EK_USING : EK_FOR_BINDING);
      if (flags & WMB_Hidden)
	dep->set_hidden_binding ();
      data->binding->deps.safe_push (dep);
      /* Binding and contents are mutually dependent.  */
      dep->deps.safe_push (data->binding);

      return (flags & WMB_Using
	      ? flags & WMB_Export : DECL_MODULE_EXPORT_P (decl));
    }
  else if (DECL_NAME (decl) && !data->met_namespace)
    {
      /* Namespace, walk exactly once.  */
      gcc_checking_assert (TREE_PUBLIC (decl));
      data->met_namespace = true;
      if (data->hash->add_namespace_entities (decl, data->partitions))
	{
	  /* It contains an exported thing, so it is exported.  */
	  gcc_checking_assert (DECL_MODULE_PURVIEW_P (decl));
	  DECL_MODULE_EXPORT_P (decl) = true;
	}

      if (DECL_MODULE_PURVIEW_P (decl))
	{
	  data->hash->make_dependency (decl, depset::EK_NAMESPACE);

	  return DECL_MODULE_EXPORT_P (decl);
	}
    }

  return false;
}

/* Recursively find all the namespace bindings of NS.  Add a depset
   for every binding that contains an export or module-linkage entity.
   Add a defining depset for every such decl that we need to write a
   definition.  Such defining depsets depend on the binding depset.
   Returns true if we contain something exported.  */

bool
depset::hash::add_namespace_entities (tree ns, bitmap partitions)
{
  dump () && dump ("Looking for writables in %N", ns);
  dump.indent ();

  unsigned count = 0;
  add_binding_data data;
  data.ns = ns;
  data.partitions = partitions;
  data.hash = this;

  hash_table<named_decl_hash>::iterator end
    (DECL_NAMESPACE_BINDINGS (ns)->end ());
  for (hash_table<named_decl_hash>::iterator iter
	 (DECL_NAMESPACE_BINDINGS (ns)->begin ()); iter != end; ++iter)
    {
      data.binding = nullptr;
      data.met_namespace = false;
      if (walk_module_binding (*iter, partitions, add_binding_entity, &data))
	count++;
    }

  if (count)
    dump () && dump ("Found %u entries", count);
  dump.outdent ();

  return count != 0;
}

void
depset::hash::add_partial_entities (vec<tree, va_gc> *partial_classes)
{
  for (unsigned ix = 0; ix != partial_classes->length (); ix++)
    {
      tree inner = (*partial_classes)[ix];

      depset *dep = make_dependency (inner, depset::EK_DECL);

      if (dep->get_entity_kind () == depset::EK_REDIRECT)
	/* We should have recorded the template as a partial
	   specialization.  */
	gcc_checking_assert (dep->deps[0]->get_entity_kind ()
			     == depset::EK_PARTIAL);
      else
	/* It was an explicit specialization, not a partial one.  */
	gcc_checking_assert (dep->get_entity_kind ()
			     == depset::EK_SPECIALIZATION);
    }
}

/* Add the members of imported classes that we defined in this TU.
   This will also include lazily created implicit member function
   declarations.  (All others will be definitions.)  */

void
depset::hash::add_class_entities (vec<tree, va_gc> *class_members)
{
  for (unsigned ix = 0; ix != class_members->length (); ix++)
    {
      tree defn = (*class_members)[ix];
      depset *dep = make_dependency (defn, EK_INNER_DECL);

      if (dep->get_entity_kind () == EK_REDIRECT)
	dep = dep->deps[0];

      /* Only non-instantiations need marking as members.  */
      if (dep->get_entity_kind () == EK_DECL)
	dep->set_flag_bit <DB_IS_MEMBER_BIT> ();
    }
}

/* We add the partial & explicit specializations, and the explicit
   instantiations.  */

static void
specialization_add (bool decl_p, spec_entry *entry, void *data_)
{
  vec<spec_entry *> *data = reinterpret_cast <vec<spec_entry *> *> (data_);

  if (!decl_p)
    {
      /* We exclusively use decls to locate things.  Make sure there's
	 no mismatch between the two specialization tables we keep.
	 pt.c optimizes instantiation lookup using a complicated
	 heuristic.  We don't attempt to replicate that algorithm, but
	 observe its behaviour and reproduce it upon read back.  */

       gcc_checking_assert (DECL_ALIAS_TEMPLATE_P (entry->tmpl)
			   || TREE_CODE (entry->spec) == ENUMERAL_TYPE
			   || DECL_CLASS_TEMPLATE_P (entry->tmpl));

       /* Only alias templates can appear in both tables (and
	  if they're in the type table they must also be in the decl
	  table).  */
       gcc_checking_assert
	 (!match_mergeable_specialization (true, entry)
	  == !DECL_ALIAS_TEMPLATE_P (entry->tmpl));
    }
  else if (VAR_OR_FUNCTION_DECL_P (entry->spec))
    gcc_checking_assert (!DECL_LOCAL_DECL_P (entry->spec));

  data->safe_push (entry);
}

/* Arbitrary stable comparison.  */

static int
specialization_cmp (const void *a_, const void *b_)
{
  const spec_entry *ea = *reinterpret_cast<const spec_entry *const *> (a_);
  const spec_entry *eb = *reinterpret_cast<const spec_entry *const *> (b_);

  if (ea == eb)
    return 0;

  tree a = ea->spec;
  tree b = eb->spec;
  if (TYPE_P (a))
    {
      a = TYPE_NAME (a);
      b = TYPE_NAME (b);
    }

  if (a == b)
    /* This can happen with friend specializations.  Just order by
       entry address.  See note in depset_cmp.  */
    return ea < eb ? -1 : +1;

  return DECL_UID (a) < DECL_UID (b) ? -1 : +1;
}

/* We add all kinds of specialializations.  Implicit specializations
   should only streamed and walked if they are reachable from
   elsewhere.  Hence the UNREACHED flag.  This is making the
   assumption that it is cheaper to reinstantiate them on demand
   elsewhere, rather than stream them in when we instantiate their
   general template.  Also, if we do stream them, we can only do that
   if they are not internal (which they can become if they themselves
   touch an internal entity?).  */

void
depset::hash::add_specializations (bool decl_p)
{
  vec<spec_entry *> data;
  data.create (100);
  walk_specializations (decl_p, specialization_add, &data);
  data.qsort (specialization_cmp);
  while (data.length ())
    {
      spec_entry *entry = data.pop ();
      tree spec = entry->spec;
      int use_tpl = 0;
      bool is_alias = false;
      bool is_friend = false;

      if (decl_p && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (entry->tmpl))
	/* A friend of a template.  This is keyed to the
	   instantiation.  */
	is_friend = true;

      if (!decl_p && DECL_ALIAS_TEMPLATE_P (entry->tmpl))
	{
	  spec = TYPE_NAME (spec);
	  is_alias = true;
	}

      if (decl_p || is_alias)
	{
	  if (tree ti = DECL_TEMPLATE_INFO (spec))
	    {
	      tree tmpl = TI_TEMPLATE (ti);

	      use_tpl = DECL_USE_TEMPLATE (spec);
	      if (spec == DECL_TEMPLATE_RESULT (tmpl))
		{
		  spec = tmpl;
		  gcc_checking_assert (DECL_USE_TEMPLATE (spec) == use_tpl);
		}
	      else if (is_friend)
		{
		  if (TI_TEMPLATE (ti) != entry->tmpl
		      || !template_args_equal (TI_ARGS (ti), entry->tmpl))
		    goto template_friend;
		}
	    }
	  else
	    {
	    template_friend:;
	      gcc_checking_assert (is_friend);
	      /* This is a friend of a template class, but not the one
		 that generated entry->spec itself (i.e. it's an
		 equivalent clone).  We do not need to record
		 this.  */
	      continue;
	    }
	}
      else
	{
	  if (TREE_CODE (spec) == ENUMERAL_TYPE)
	    {
	      tree ctx = DECL_CONTEXT (TYPE_NAME (spec));

	      if (TYPE_P (ctx))
		use_tpl = CLASSTYPE_USE_TEMPLATE (ctx);
	      else
		use_tpl = DECL_USE_TEMPLATE (ctx);
	    }
	  else
	    use_tpl = CLASSTYPE_USE_TEMPLATE (spec);

	  tree ti = TYPE_TEMPLATE_INFO (spec);
	  tree tmpl = TI_TEMPLATE (ti);

	  spec = TYPE_NAME (spec);
	  if (spec == DECL_TEMPLATE_RESULT (tmpl))
	    {
	      spec = tmpl;
	      use_tpl = DECL_USE_TEMPLATE (spec);
	    }
	}

      bool needs_reaching = false;
      if (use_tpl == 1)
	/* Implicit instantiations only walked if we reach them.  */
	needs_reaching = true;
      else if (!DECL_LANG_SPECIFIC (spec)
	       || !DECL_MODULE_PURVIEW_P (spec))
	/* Likewise, GMF explicit or partial specializations.  */
	needs_reaching = true;

#if false && CHECKING_P
      /* The instantiation isn't always on
	 DECL_TEMPLATE_INSTANTIATIONS, */
      // FIXME: we probably need to remember this information?
      /* Verify the specialization is on the
	 DECL_TEMPLATE_INSTANTIATIONS of the template.  */
      for (tree cons = DECL_TEMPLATE_INSTANTIATIONS (entry->tmpl);
	   cons; cons = TREE_CHAIN (cons))
	if (TREE_VALUE (cons) == entry->spec)
	  {
	    gcc_assert (entry->args == TREE_PURPOSE (cons));
	    goto have_spec;
	  }
      gcc_unreachable ();
    have_spec:;
#endif

      /* Make sure nobody left a tree visited lying about.  */
      gcc_checking_assert (!TREE_VISITED (spec));
      depset *dep = make_dependency (spec, depset::EK_SPECIALIZATION);
      if (dep->is_special ())
	{
	  /* An already located specialization, this must be the TYPE
	     corresponding to an alias_decl we found in the decl
	     table.  */
	  spec_entry *other = reinterpret_cast <spec_entry *> (dep->deps[0]);
	  gcc_checking_assert (!decl_p && is_alias && !dep->is_type_spec ());
	  gcc_checking_assert (other->tmpl == entry->tmpl
			       && template_args_equal (other->args, entry->args)
			       && TREE_TYPE (other->spec) == entry->spec);
	  dep->set_flag_bit<DB_ALIAS_SPEC_BIT> ();
	}
      else
	{
	  gcc_checking_assert (decl_p || !is_alias);
	  if (dep->get_entity_kind () == depset::EK_REDIRECT)
	    dep = dep->deps[0];
	  else if (dep->get_entity_kind () == depset::EK_SPECIALIZATION)
	    {
	      dep->set_special ();
	      dep->deps.safe_push (reinterpret_cast<depset *> (entry));
	      if (!decl_p)
		dep->set_flag_bit<DB_TYPE_SPEC_BIT> ();
	    }

	  if (needs_reaching)
	    dep->set_flag_bit<DB_UNREACHED_BIT> ();
	  if (is_friend)
	    dep->set_flag_bit<DB_FRIEND_SPEC_BIT> ();
	}
    }
  data.release ();
}

/* Add a depset into the mergeable hash.  */

void
depset::hash::add_mergeable (depset *mergeable)
{
  gcc_checking_assert (is_key_order ());
  entity_kind ek = mergeable->get_entity_kind ();
  tree decl = mergeable->get_entity ();
  gcc_checking_assert (ek < EK_DIRECT_HWM);

  depset **slot = entity_slot (decl, true);
  gcc_checking_assert (!*slot);
  depset *dep = make_entity (decl, ek);
  *slot = dep;

  worklist.safe_push (dep);

  /* So we can locate the mergeable depset this depset refers to,
     mark the first dep.  */
  dep->set_special ();
  dep->deps.safe_push (mergeable);
}

/* Find the innermost-namespace scope of DECL, and that
   namespace-scope decl.  */

tree
find_pending_key (tree decl, tree *decl_p = nullptr)
{
  tree ns = decl;
  do
    {
      decl = ns;
      ns = CP_DECL_CONTEXT (ns);
      if (TYPE_P (ns))
	ns = TYPE_NAME (ns);
    }
  while (TREE_CODE (ns) != NAMESPACE_DECL);

  if (decl_p)
    *decl_p = decl;

  return ns;
}

/* Iteratively find dependencies.  During the walk we may find more
   entries on the same binding that need walking.  */

void
depset::hash::find_dependencies (module_state *module)
{
  trees_out walker (NULL, module, *this);
  vec<depset *> unreached;
  unreached.create (worklist.length ());

  for (;;)
    {
      reached_unreached = false;
      while (worklist.length ())
	{
	  depset *item = worklist.pop ();

	  gcc_checking_assert (!item->is_binding ());
	  if (item->is_unreached ())
	    unreached.quick_push (item);
	  else
	    {
	      current = item;
	      tree decl = current->get_entity ();
	      dump (is_key_order () ? dumper::MERGE : dumper::DEPEND)
		&& dump ("Dependencies of %s %C:%N",
			 is_key_order () ? "key-order"
			 : current->entity_kind_name (), TREE_CODE (decl), decl);
	      dump.indent ();
	      walker.begin ();
	      if (current->get_entity_kind () == EK_USING)
		walker.tree_node (OVL_FUNCTION (decl));
	      else if (TREE_VISITED (decl))
		/* A global tree.  */;
	      else if (item->get_entity_kind () == EK_NAMESPACE)
		add_namespace_context (current, CP_DECL_CONTEXT (decl));
	      else
		{
		  walker.mark_declaration (decl, current->has_defn ());

		  if (!walker.is_key_order ()
		      && (item->get_entity_kind () == EK_SPECIALIZATION
			  || item->get_entity_kind () == EK_PARTIAL
			  || (item->get_entity_kind () == EK_DECL
			      && item->is_member ())))
		    {
		      tree ns = find_pending_key (decl, nullptr);
		      add_namespace_context (item, ns);
		    }

		  // FIXME: Perhaps p1815 makes this redundant? Or at
		  // least simplifies it.  Voldemort types are only
		  // ever emissable when containing (inline) function
		  // definition is emitted?
		  /* Turn the Sneakoscope on when depending the decl.  */
		  sneakoscope = true;
		  walker.decl_value (decl, current);
		  sneakoscope = false;
		  if (current->has_defn ())
		    walker.write_definition (decl);
		}
	      walker.end ();

	      if (!walker.is_key_order ()
		  && TREE_CODE (decl) == TEMPLATE_DECL
		  && !DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
		/* Mark all the explicit & partial specializations as
		   reachable.  */
		for (tree cons = DECL_TEMPLATE_INSTANTIATIONS (decl);
		     cons; cons = TREE_CHAIN (cons))
		  {
		    tree spec = TREE_VALUE (cons);
		    if (TYPE_P (spec))
		      spec = TYPE_NAME (spec);
		    int use_tpl;
		    node_template_info (spec, use_tpl);
		    if (use_tpl & 2)
		      {
			depset *spec_dep = find_dependency (spec);
			if (spec_dep->get_entity_kind () == EK_REDIRECT)
			  spec_dep = spec_dep->deps[0];
			if (spec_dep->is_unreached ())
			  {
			    reached_unreached = true;
			    spec_dep->clear_flag_bit<DB_UNREACHED_BIT> ();
			    dump (dumper::DEPEND)
			      && dump ("Reaching unreached specialization"
				       " %C:%N", TREE_CODE (spec), spec);
			  }
		      }
		  }

	      dump.outdent ();
	      current = NULL;
	    }
	}

      if (!reached_unreached)
	break;

      /* It's possible the we reached the unreached before we
	 processed it in the above loop, so we'll be doing this an
	 extra time.  However, to avoid that we have to do some
	 bit shuffling that also involves a scan of the list.
	 Swings & roundabouts I guess.  */
      std::swap (worklist, unreached);
    }

  unreached.release ();
}

/* Compare two entries of a single binding.  TYPE_DECL before
   non-exported before exported.  */

static int
binding_cmp (const void *a_, const void *b_)
{
  depset *a = *(depset *const *)a_;
  depset *b = *(depset *const *)b_;

  tree a_ent = a->get_entity ();
  tree b_ent = b->get_entity ();
  gcc_checking_assert (a_ent != b_ent
		       && !a->is_binding ()
		       && !b->is_binding ());

  /* Implicit typedefs come first.  */
  bool a_implicit = DECL_IMPLICIT_TYPEDEF_P (a_ent);
  bool b_implicit = DECL_IMPLICIT_TYPEDEF_P (b_ent);
  if (a_implicit || b_implicit)
    {
      /* A binding with two implicit type decls?  That's unpossible!  */
      gcc_checking_assert (!(a_implicit && b_implicit));
      return a_implicit ? -1 : +1;  /* Implicit first.  */
    }

  /* Hidden before non-hidden.  */
  bool a_hidden = a->is_hidden ();
  bool b_hidden = b->is_hidden ();
  if (a_hidden != b_hidden)
    return a_hidden ? -1 : +1;

  bool a_using = a->get_entity_kind () == depset::EK_USING;
  bool a_export;
  if (a_using)
    {
      a_export = OVL_EXPORT_P (a_ent);
      a_ent = OVL_FUNCTION (a_ent);
    }
  else
    a_export = DECL_MODULE_EXPORT_P (TREE_CODE (a_ent) == CONST_DECL
				     ? TYPE_NAME (TREE_TYPE (a_ent))
				     : STRIP_TEMPLATE (a_ent));
  
  bool b_using = b->get_entity_kind () == depset::EK_USING;
  bool b_export;
  if (b_using)
    {
      b_export = OVL_EXPORT_P (b_ent);
      b_ent = OVL_FUNCTION (b_ent);
    }
  else
    b_export = DECL_MODULE_EXPORT_P (TREE_CODE (b_ent) == CONST_DECL
				     ? TYPE_NAME (TREE_TYPE (b_ent))
				     : STRIP_TEMPLATE (b_ent));

  /* Non-exports before exports.  */
  if (a_export != b_export)
    return a_export ? +1 : -1;

  /* At this point we don't care, but want a stable sort.  */

  if (a_using != b_using)
    /* using first.  */
    return a_using? -1 : +1;

  return DECL_UID (a_ent) < DECL_UID (b_ent) ? -1 : +1;
}

/* Sort the bindings, issue errors about bad internal refs.  */

bool
depset::hash::finalize_dependencies ()
{
  bool ok = true;
  depset::hash::iterator end (this->end ());
  for (depset::hash::iterator iter (begin ()); iter != end; ++iter)
    {
      depset *dep = *iter;
      if (dep->is_binding ())
	{
	  /* Keep the containing namespace dep first.  */
	  gcc_checking_assert (dep->deps.length () > 1
			       && (dep->deps[0]->get_entity_kind ()
				   == EK_NAMESPACE)
			       && (dep->deps[0]->get_entity ()
				   == dep->get_entity ()));
	  if (dep->deps.length () > 2)
	    gcc_qsort (&dep->deps[1], dep->deps.length () - 1,
		       sizeof (dep->deps[1]), binding_cmp);
	}
      else if (dep->refs_internal ())
	{
	  for (unsigned ix = dep->deps.length (); ix--;)
	    {
	      depset *rdep = dep->deps[ix];
	      if (rdep->is_internal ())
		{
		  // FIXME:QOI Better location information?  We're
		  // losing, so it doesn't matter about efficiency
		  tree decl = dep->get_entity ();
		  error_at (DECL_SOURCE_LOCATION (decl),
			    "%q#D references internal linkage entity %q#D",
			    decl, rdep->get_entity ());
		  break;
		}
	    }
	  ok = false;
	}
    }

  return ok;
}

/* Core of TARJAN's algorithm to find Strongly Connected Components
   within a graph.  See https://en.wikipedia.org/wiki/
   Tarjan%27s_strongly_connected_components_algorithm for details.

   We use depset::section as lowlink.  Completed nodes have
   depset::cluster containing the cluster number, with the top
   bit set.

   A useful property is that the output vector is a reverse
   topological sort of the resulting DAG.  In our case that means
   dependent SCCs are found before their dependers.  We make use of
   that property.  */

void
depset::tarjan::connect (depset *v)
{
  gcc_checking_assert (v->is_binding ()
		       || !(v->is_unreached () || v->is_import ()));

  v->cluster = v->section = ++index;
  stack.safe_push (v);

  /* Walk all our dependencies, ignore a first marked slot  */
  for (unsigned ix = v->is_special (); ix != v->deps.length (); ix++)
    {
      depset *dep = v->deps[ix];

      if (dep->is_binding () || !dep->is_import ())
	{
	  unsigned lwm = dep->cluster;

	  if (!dep->cluster)
	    {
	      /* A new node.  Connect it.  */
	      connect (dep);
	      lwm = dep->section;
	    }

	  if (dep->section && v->section > lwm)
	    v->section = lwm;
	}
    }

  if (v->section == v->cluster)
    {
      /* Root of a new SCC.  Push all the members onto the result list. */
      unsigned num = v->cluster;
      depset *p;
      do
	{
	  p = stack.pop ();
	  p->cluster = num;
	  p->section = 0;
	  result.quick_push (p);
	}
      while (p != v);
    }
}

/* Compare two depsets.  The specific ordering is unimportant, we're
   just trying to get consistency.  */

static int
depset_cmp (const void *a_, const void *b_)
{
  depset *a = *(depset *const *)a_;
  depset *b = *(depset *const *)b_;

  depset::entity_kind a_kind = a->get_entity_kind ();
  depset::entity_kind b_kind = b->get_entity_kind ();

  if  (a_kind != b_kind)
    /* Different entity kinds, order by that.  */
    return a_kind < b_kind ? -1 : +1;
  
  tree a_decl = a->get_entity ();
  tree b_decl = b->get_entity ();
  if (a_kind == depset::EK_USING)
    {
      /* If one is a using, the other must be too.  */
      a_decl = OVL_FUNCTION (a_decl);
      b_decl = OVL_FUNCTION (b_decl);
    }

  if (a_decl != b_decl)
    /* Different entities, order by their UID.  */
    return DECL_UID (a_decl) < DECL_UID (b_decl) ? -1 : +1;

  if (a_kind == depset::EK_BINDING)
    {
      /* Both are bindings.  Order by identifier hash.  */
      gcc_checking_assert (a->get_name () != b->get_name ());
      return (IDENTIFIER_HASH_VALUE (a->get_name ())
	      < IDENTIFIER_HASH_VALUE (b->get_name ())
	      ? -1 : +1);
    }

  /* They are the same decl.  This can happen with two using decls
     pointing to the same target.  The best we can aim for is
     consistently telling qsort how to order them.  Hopefully we'll
     never have to debug a case that depends on this.  Oh, who am I
     kidding?  Good luck.  */
  gcc_checking_assert (a_kind == depset::EK_USING);

  /* Order by depset address.  Not the best, but it is something.  */
  return a < b ? -1 : +1;
}

/* Sort the clusters in SCC such that those that depend on one another
   are placed later.   */

// FIXME: I am not convinced this is needed and, if needed,
// sufficient.  We emit the decls in this order but that emission
// could walk into later decls (from the body of the decl, or default
// arg-like things).  Why doesn't that walk do the right thing?  And
// if it DTRT why do we need to sort here -- won't things naturally
// work?  I think part of the issue is that when we're going to refer
// to an entity by name, and that entity is in the same cluster as us,
// we need to actually walk that entity, if we've not already walked
// it.
static void
sort_cluster (depset::hash *original, depset *scc[], unsigned size)
{
  depset::hash table (size, original);

  dump.indent ();

  /* Place bindings last, usings before that.  It's not strictly
     necessary, but it does make things neater.  Says Mr OCD.  */
  unsigned bind_lwm = size;
  unsigned use_lwm = size;
  for (unsigned ix = 0; ix != use_lwm;)
    {
      depset *dep = scc[ix];
      switch (dep->get_entity_kind ())
	{
	case depset::EK_BINDING:
	  /* Move to end.  No increment.  Notice this could be moving
	     a using decl, which we'll then move again.  */
	  if (--bind_lwm != ix)
	    {
	      scc[ix] = scc[bind_lwm];
	      scc[bind_lwm] = dep;
	    }
	  if (use_lwm > bind_lwm)
	    {
	      use_lwm--;
	      break;
	    }
	  /* We must have copied a using, so move it too.  */
	  dep = scc[ix];
	  gcc_checking_assert (dep->get_entity_kind () == depset::EK_USING);
	  /* FALLTHROUGH  */

	case depset::EK_USING:
	  if (--use_lwm != ix)
	    {
	      scc[ix] = scc[use_lwm];
	      scc[use_lwm] = dep;
	    }
	  break;

	case depset::EK_DECL:
	case depset::EK_SPECIALIZATION:
	case depset::EK_PARTIAL:
	  table.add_mergeable (dep);
	  ix++;
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  gcc_checking_assert (use_lwm <= bind_lwm);
  dump (dumper::MERGE) && dump ("Ordering %u/%u depsets", use_lwm, size);

  table.find_dependencies (nullptr);

  vec<depset *> order = table.connect ();
  gcc_checking_assert (order.length () == use_lwm);

  /* Now rewrite entries [0,lwm), in the dependency order we
     discovered.  Usually each entity is in its own cluster.  Rarely,
     we can get multi-entity clusters, in which case all but one must
     only be reached from within the cluster.  This happens for
     something like:

     template<typename T>
     auto Foo (const T &arg) -> TPL<decltype (arg)>;

     The instantiation of TPL will be in the specialization table, and
     refer to Foo via arg.  But we can only get to that specialization
     from Foo's declaration, so we only need to treat Foo as mergable
     (We'll do structural comparison of TPL<decltype (arg)>).

     Finding the single cluster entry dep is very tricky and
     expensive.  Let's just not do that.  It's harmless in this case
     anyway. */
  unsigned pos = 0;
  unsigned cluster = ~0u;
  for (unsigned ix = 0; ix != order.length (); ix++)
    {
      gcc_checking_assert (order[ix]->is_special ());
      depset *dep = order[ix]->deps[0];
      scc[pos++] = dep;
      dump (dumper::MERGE)
	&& dump ("Mergeable %u is %N%s", ix, dep->get_entity (),
		 order[ix]->cluster == cluster ? " (tight)" : "");
      cluster = order[ix]->cluster;
    }

  gcc_checking_assert (pos == use_lwm);

  order.release ();
  dump (dumper::MERGE) && dump ("Ordered %u keys", pos);
  dump.outdent ();
}

/* Reduce graph to SCCS clusters.  SCCS will be populated with the
   depsets in dependency order.  Each depset's CLUSTER field contains
   its cluster number.  Each SCC has a unique cluster number, and are
   contiguous in SCCS. Cluster numbers are otherwise arbitrary.  */

vec<depset *>
depset::hash::connect ()
{
  tarjan connector (size ());
  vec<depset *> deps;
  deps.create (size ());
  iterator end (this->end ());
  for (iterator iter (begin ()); iter != end; ++iter)
    {
      depset *item = *iter;

      entity_kind kind = item->get_entity_kind ();
      if (kind == EK_BINDING
	  || !(kind == EK_REDIRECT
	       || item->is_unreached ()
	       || item->is_import ()))
	deps.quick_push (item);
    }

  /* Iteration over the hash table is an unspecified ordering.  While
     that has advantages, it causes 2 problems.  Firstly repeatable
     builds are tricky.  Secondly creating testcases that check
     dependencies are correct by making sure a bad ordering would
     happen if that was wrong.  */
  deps.qsort (depset_cmp);

  while (deps.length ())
    {
      depset *v = deps.pop ();
      dump (dumper::CLUSTER) &&
	(v->is_binding ()
	 ? dump ("Connecting binding %P", v->get_entity (), v->get_name ())
	 : dump ("Connecting %s %s %C:%N",
		 is_key_order () ? "key-order"
		 : !v->has_defn () ? "declaration" : "definition",
		 v->entity_kind_name (), TREE_CODE (v->get_entity ()),
		 v->get_entity ()));
      if (!v->cluster)
	connector.connect (v);
    }

  deps.release ();
  return connector.result;
}

/* Initialize location spans.  */

void
loc_spans::init (const line_maps *lmaps, const line_map_ordinary *map)
{
  gcc_checking_assert (!init_p ());
  spans = new vec<span> ();
  spans->reserve (20);

  span interval;
  interval.ordinary.first = 0;
  interval.macro.second = MAX_LOCATION_T + 1;
  interval.ordinary_delta = interval.macro_delta = 0;

  /* A span for reserved fixed locs.  */
  interval.ordinary.second
    = MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0));
  interval.macro.first = interval.macro.second;
  dump (dumper::LOCATION)
    && dump ("Fixed span %u ordinary:[%u,%u) macro:[%u,%u)", spans->length (),
	     interval.ordinary.first, interval.ordinary.second,
	     interval.macro.first, interval.macro.second);
  spans->quick_push (interval);

  /* A span for command line & forced headers.  */
  interval.ordinary.first = interval.ordinary.second;
  interval.macro.second = interval.macro.first;
  if (map)
    {
      interval.ordinary.second = map->start_location;
      interval.macro.first = LINEMAPS_MACRO_LOWEST_LOCATION (lmaps);
    }
  dump (dumper::LOCATION)
    && dump ("Pre span %u ordinary:[%u,%u) macro:[%u,%u)", spans->length (),
	     interval.ordinary.first, interval.ordinary.second,
	     interval.macro.first, interval.macro.second);
  spans->quick_push (interval);
  
  /* Start an interval for the main file.  */
  interval.ordinary.first = interval.ordinary.second;
  interval.macro.second = interval.macro.first;
  dump (dumper::LOCATION)
    && dump ("Main span %u ordinary:[%u,*) macro:[*,%u)", spans->length (),
	     interval.ordinary.first, interval.macro.second);
  spans->quick_push (interval);
}

/* Reopen the span, if we want the about-to-be-inserted set of maps to
   be propagated in our own location table.  I.e. we are the primary
   interface and we're importing a partition.  */

bool
loc_spans::maybe_propagate (module_state *import, location_t hwm)
{
  bool opened = (module_interface_p () && !module_partition_p ()
		 && import->is_partition ());
  if (opened)
    open (hwm);
  return opened;
}

/* Open a new linemap interval.  The just-created ordinary map is the
   first map of the interval.  */

void
loc_spans::open (location_t hwm)
{
  span interval;
  interval.ordinary.first = interval.ordinary.second = hwm;
  interval.macro.first = interval.macro.second
    = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  interval.ordinary_delta = interval.macro_delta = 0;
  dump (dumper::LOCATION)
    && dump ("Opening span %u ordinary:[%u,... macro:...,%u)",
	     spans->length (), interval.ordinary.first,
	     interval.macro.second);
  if (spans->length ())
    {
      /* No overlapping!  */
      auto &last = spans->last ();
      gcc_checking_assert (interval.ordinary.first >= last.ordinary.second);
      gcc_checking_assert (interval.macro.second <= last.macro.first);
    }
  spans->safe_push (interval);
}

/* Close out the current linemap interval.  The last maps are within
   the interval.  */

void
loc_spans::close ()
{
  span &interval = spans->last ();

  interval.ordinary.second
    = ((line_table->highest_location + (1 << line_table->default_range_bits))
       & ~((1u << line_table->default_range_bits) - 1));
  interval.macro.first = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  dump (dumper::LOCATION)
    && dump ("Closing span %u ordinary:[%u,%u) macro:[%u,%u)",
	     spans->length () - 1,
	     interval.ordinary.first,interval.ordinary.second,
	     interval.macro.first, interval.macro.second);
}

/* Given an ordinary location LOC, return the lmap_interval it resides
   in.  NULL if it is not in an interval.  */

const loc_spans::span *
loc_spans::ordinary (location_t loc)
{
  unsigned len = spans->length ();
  unsigned pos = 0;
  while (len)
    {
      unsigned half = len / 2;
      const span &probe = (*spans)[pos + half];
      if (loc < probe.ordinary.first)
	len = half;
      else if (loc < probe.ordinary.second)
	return &probe;
      else
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
    }
  return NULL;
}

/* Likewise, given a macro location LOC, return the lmap interval it
   resides in.   */

const loc_spans::span *
loc_spans::macro (location_t loc)
{
  unsigned len = spans->length ();
  unsigned pos = 0;
  while (len)
    {
      unsigned half = len / 2;
      const span &probe = (*spans)[pos + half];
      if (loc >= probe.macro.second)
	len = half;
      else if (loc >= probe.macro.first)
	return &probe;
      else
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
    }
  return NULL;
}

/* Return the ordinary location closest to FROM.  */

static location_t
ordinary_loc_of (line_maps *lmaps, location_t from)
{
  while (!IS_ORDINARY_LOC (from))
    {
      if (IS_ADHOC_LOC (from))
	from = get_location_from_adhoc_loc (lmaps, from);
      if (from >= LINEMAPS_MACRO_LOWEST_LOCATION (lmaps))
	{
	  /* Find the ordinary location nearest FROM.  */
	  const line_map *map = linemap_lookup (lmaps, from);
	  const line_map_macro *mac_map = linemap_check_macro (map);
	  from = MACRO_MAP_EXPANSION_POINT_LOCATION (mac_map);
	}
    }
  return from;
}

static module_state **
get_module_slot (tree name, module_state *parent, bool partition, bool insert)
{
  module_state_hash::compare_type ct (name, uintptr_t (parent) | partition);
  hashval_t hv = module_state_hash::hash (ct);

  return modules_hash->find_slot_with_hash (ct, hv, insert ? INSERT : NO_INSERT);
}

static module_state *
get_primary (module_state *parent)
{
  while (parent->is_partition ())
    parent = parent->parent;

  if (!parent->name)
    // Implementation unit has null name
    parent = parent->parent;

  return parent;
}

/* Find or create module NAME & PARENT in the hash table.  */

module_state *
get_module (tree name, module_state *parent, bool partition)
{
  if (partition)
    {
      if (!parent)
	parent = get_primary ((*modules)[0]);

      if (!parent->is_partition () && !parent->flatname)
	parent->set_flatname ();
    }

  module_state **slot = get_module_slot (name, parent, partition, true);
  module_state *state = *slot;
  if (!state)
    {
      state = (new (ggc_alloc<module_state> ())
	       module_state (name, parent, partition));
      *slot = state;
    }
  return state;
}

/* Process string name PTR into a module_state.  */

static module_state *
get_module (const char *ptr)
{
  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_ABSOLUTE_PATH (ptr))
    /* A header name.  */
    return get_module (build_string (strlen (ptr), ptr));

  bool partition = false;
  module_state *mod = NULL;

  for (const char *probe = ptr;; probe++)
    if (!*probe || *probe == '.' || *probe == ':')
      {
	if (probe == ptr)
	  return NULL;

	mod = get_module (get_identifier_with_length (ptr, probe - ptr),
			  mod, partition);
	ptr = probe;
	if (*ptr == ':')
	  {
	    if (partition)
	      return NULL;
	    partition = true;
	  }

	if (!*ptr++)
	  break;
      }
    else if (!(ISALPHA (*probe) || *probe == '_'
	       || (probe != ptr && ISDIGIT (*probe))))
      return NULL;

  return mod;
}

/* Create a new mapper connecting to OPTION.  */

module_client *
make_mapper (location_t loc)
{
  timevar_start (TV_MODULE_MAPPER);
  const char *option = module_mapper_name;
  if (!option)
    option = getenv ("CXX_MODULE_MAPPER");

  mapper = module_client::open_module_client
    (loc, option, &set_cmi_repo,
     (save_decoded_options[0].opt_index == OPT_SPECIAL_program_name)
     && save_decoded_options[0].arg != progname
     ? save_decoded_options[0].arg : nullptr);

  timevar_stop (TV_MODULE_MAPPER);

  return mapper;
}

static unsigned lazy_snum;

static bool
recursive_lazy (unsigned snum = ~0u)
{
  if (lazy_snum)
    {
      error_at (input_location, "recursive lazy load");
      return true;
    }

  lazy_snum = snum;
  return false;
}

/* If THIS is the current purview, issue an import error and return false.  */

bool
module_state::check_not_purview (location_t from)
{
  module_state *imp = (*modules)[0];
  if (imp && !imp->name)
    imp = imp->parent;
  if (imp == this)
    {
      /* Cannot import the current module.  */
      error_at (from, "cannot import module in its own purview");
      inform (loc, "module %qs declared here", get_flatname ());
      return false;
    }
  return true;
}

/* Module name substitutions.  */
static vec<module_state *,va_heap> substs;

void
module_state::mangle (bool include_partition)
{
  if (subst)
    mangle_module_substitution (subst - 1);
  else
    {
      if (parent)
	parent->mangle (include_partition);
      if (include_partition || !is_partition ())
	{
	  char p = 0;
	  // Partitions are significant for global initializer functions
	  if (is_partition () && !parent->is_partition ())
	    p = 'P';
	  substs.safe_push (this);
	  subst = substs.length ();
	  mangle_identifier (p, name);
	}
    }
}

void
mangle_module (int mod, bool include_partition)
{
  module_state *imp = (*modules)[mod];

  if (!imp->name)
    /* Set when importing the primary module interface.  */
    imp = imp->parent;

  imp->mangle (include_partition);
}

/* Clean up substitutions.  */
void
mangle_module_fini ()
{
  while (substs.length ())
    substs.pop ()->subst = 0;
}

/* Announce WHAT about the module.  */

void
module_state::announce (const char *what) const
{
  if (noisy_p ())
    {
      fprintf (stderr, " %s:%s", what, get_flatname ());
      fflush (stderr);
    }
}

/* A human-readable README section.  The contents of this section to
   not contribute to the CRC, so the contents can change per
   compilation.  That allows us to embed CWD, hostname, build time and
   what not.  It is a STRTAB that may be extracted with:
     readelf -pgnu.c++.README $(module).gcm */

void
module_state::write_readme (elf_out *to, cpp_reader *reader,
			    const char *dialect, unsigned extensions)
{
  bytes_out readme (to);

  readme.begin (false);

  readme.printf ("GNU C++ %smodule%s%s",
		 is_header () ? "header " : is_partition () ? "" : "primary ",
		 is_header () ? ""
		 : is_interface () ? " interface" : " implementation",
		 is_partition () ? " partition" : "");

  /* Compiler's version.  */
  readme.printf ("compiler: %s", version_string);

  /* Module format version.  */
  verstr_t string;
  version2string (MODULE_VERSION, string);
  readme.printf ("version: %s", string);

  /* Module information.  */
  readme.printf ("module: %s", get_flatname ());
  readme.printf ("source: %s", main_input_filename);
  readme.printf ("dialect: %s", dialect);
  if (extensions)
    readme.printf ("extensions: %s",
		   extensions & SE_OPENMP ? "-fopenmp" : "");

  /* The following fields could be expected to change between
     otherwise identical compilations.  Consider a distributed build
     system.  We should have a way of overriding that.  */
  if (char *cwd = getcwd (NULL, 0))
    {
      readme.printf ("cwd: %s", cwd);
      free (cwd);
    }
  readme.printf ("repository: %s", cmi_repo ? cmi_repo : ".");
#if NETWORKING
  {
    char hostname[64];
    if (!gethostname (hostname, sizeof (hostname)))
      readme.printf ("host: %s", hostname);
  }
#endif
  {
    /* This of course will change!  */
    time_t stampy;
    auto kind = cpp_get_date (reader, &stampy);
    if (kind != CPP_time_kind::UNKNOWN)
      {
	struct tm *time;

	time = gmtime (&stampy);
	readme.print_time ("build", time, "UTC");

	if (kind == CPP_time_kind::DYNAMIC)
	  {
	    time = localtime (&stampy);
	    readme.print_time ("local", time,
#if defined (__USE_MISC) || defined (__USE_BSD) /* Is there a better way?  */
			       time->tm_zone
#else
			       ""
#endif
			       );
	  }
      }
  }

  /* Its direct imports.  */
  for (unsigned ix = 1; ix < modules->length (); ix++)
    {
      module_state *state = (*modules)[ix];

      if (state->is_direct ())
	readme.printf ("%s: %s %s", state->exported_p ? "export" : "import",
		       state->get_flatname (), state->filename);
    }

  readme.end (to, to->name (MOD_SNAME_PFX ".README"), NULL);
}

/* Sort environment var names in reverse order.  */

static int
env_var_cmp (const void *a_, const void *b_)
{
  const unsigned char *a = *(const unsigned char *const *)a_;
  const unsigned char *b = *(const unsigned char *const *)b_;

  for (unsigned ix = 0; ; ix++)
    {
      bool a_end = !a[ix] || a[ix] == '=';
      if (a[ix] == b[ix])
	{
	  if (a_end)
	    break;
	}
      else
	{
	  bool b_end = !b[ix] || b[ix] == '=';

	  if (!a_end && !b_end)
	    return a[ix] < b[ix] ? +1 : -1;
	  if (a_end && b_end)
	    break;
	  return a_end ? +1 : -1;
	}
    }

  return 0;
}

/* Write the environment. It is a STRTAB that may be extracted with:
     readelf -pgnu.c++.ENV $(module).gcm */

void
module_state::write_env (elf_out *to)
{
  vec<const char *> vars;
  vars.create (20);

  extern char **environ;
  while (const char *var = environ[vars.length ()])
    vars.safe_push (var);
  vars.qsort (env_var_cmp);

  bytes_out env (to);
  env.begin (false);
  while (vars.length ())
    env.printf ("%s", vars.pop ());
  env.end (to, to->name (MOD_SNAME_PFX ".ENV"), NULL);

  vars.release ();
}

/* Write the direct or indirect imports.
   u:N
   {
     u:index
     s:name
     u32:crc
     s:filename (direct)
     u:exported (direct)
   } imports[N]
 */

void
module_state::write_imports (bytes_out &sec, bool direct)
{
  unsigned count = 0;

  for (unsigned ix = 1; ix < modules->length (); ix++)
    {
      module_state *imp = (*modules)[ix];

      if (imp->remap && imp->is_direct () == direct)
	count++;
    }

  gcc_assert (!direct || count);

  sec.u (count);
  for (unsigned ix = 1; ix < modules->length (); ix++)
    {
      module_state *imp = (*modules)[ix];

      if (imp->remap && imp->is_direct () == direct)
	{
	  dump () && dump ("Writing %simport:%u->%u %M (crc=%x)",
			   !direct ? "indirect "
			   : imp->exported_p ? "exported " : "",
			   ix, imp->remap, imp, imp->crc);
	  sec.u (imp->remap);
	  sec.str (imp->get_flatname ());
	  sec.u32 (imp->crc);
	  if (direct)
	    {
	      write_location (sec, imp->imported_from ());
	      sec.str (imp->filename);
	      int exportedness = 0;
	      if (imp->exported_p)
		exportedness = +1;
	      else if (!imp->is_purview_direct ())
		exportedness = -1;
	      sec.i (exportedness);
	    }
	}
    }
}

/* READER, LMAPS  != NULL == direct imports,
   == NUL == indirect imports.  */

unsigned
module_state::read_imports (bytes_in &sec, cpp_reader *reader, line_maps *lmaps)
{
  unsigned count = sec.u ();
  unsigned loaded = 0;

  while (count--)
    {
      unsigned ix = sec.u ();
      if (ix >= slurp->remap->length () || !ix || (*slurp->remap)[ix])
	{
	  sec.set_overrun ();
	  break;
	}

      const char *name = sec.str (NULL);
      module_state *imp = get_module (name);
      unsigned crc = sec.u32 ();
      int exportedness = 0;

      /* If the import is a partition, it must be the same primary
	 module as this TU.  */
      if (imp && imp->is_partition () &&
	  (!named_module_p ()
	   || (get_primary ((*modules)[0]) != get_primary (imp))))
	imp = NULL;

      if (!imp)
	sec.set_overrun ();
      if (sec.get_overrun ())
	break;

      if (lmaps)
	{
	  /* A direct import, maybe load it.  */
	  location_t floc = read_location (sec);
	  const char *fname = sec.str (NULL);
	  exportedness = sec.i ();

	  if (sec.get_overrun ())
	    break;

	  if (!imp->check_not_purview (loc))
	    continue;

	  if (imp->loadedness == ML_NONE)
	    {
	      imp->loc = floc;
	      imp->crc = crc;
	      if (!imp->get_flatname ())
		imp->set_flatname ();

	      unsigned n = dump.push (imp);

	      if (!imp->filename && fname)
		imp->filename = xstrdup (fname);

	      if (imp->is_partition ())
		dump () && dump ("Importing elided partition %M", imp);

	      if (!imp->do_import (reader, false))
		imp = NULL;
	      dump.pop (n);
	      if (!imp)
		continue;
	    }

	  if (is_partition ())
	    {
	      if (!imp->is_direct ())
		imp->directness = MD_PARTITION_DIRECT;
	      if (exportedness > 0)
		imp->exported_p = true;
	    }
	}
      else
	{
	  /* An indirect import, find it, it should already be here.  */
	  if (imp->loadedness == ML_NONE)
	    {
	      error_at (loc, "indirect import %qs is not already loaded", name);
	      continue;
	    }
	}

      if (imp->crc != crc)
	error_at (loc, "import %qs has CRC mismatch", imp->get_flatname ());

      (*slurp->remap)[ix] = (imp->mod << 1) | (lmaps != NULL);

      if (lmaps && exportedness >= 0)
	set_import (imp, bool (exportedness));
      dump () && dump ("Found %simport:%u %M->%u", !lmaps ? "indirect "
		       : exportedness > 0 ? "exported "
		       : exportedness < 0 ? "gmf" : "", ix, imp,
		       imp->mod);
      loaded++;
    }

  return loaded;
}

/* Write the import table to MOD_SNAME_PFX.imp.  */

void
module_state::write_imports (elf_out *to, unsigned *crc_ptr)
{
  dump () && dump ("Writing imports");
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  write_imports (sec, true);
  write_imports (sec, false);

  sec.end (to, to->name (MOD_SNAME_PFX ".imp"), crc_ptr);
  dump.outdent ();
}

bool
module_state::read_imports (cpp_reader *reader, line_maps *lmaps)
{
  bytes_in sec;

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".imp"))
    return false;

  dump () && dump ("Reading %u imports", slurp->remap->length () - 1);
  dump.indent ();

  /* Read the imports.  */
  unsigned direct = read_imports (sec, reader, lmaps);
  unsigned indirect = read_imports (sec, NULL, NULL);
  if (direct + indirect + 1 != slurp->remap->length ())
    from ()->set_error (elf::E_BAD_IMPORT);

  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* We're the primary module interface, but have partitions.  Document
   them so that non-partition module implementation units know which
   have already been loaded.  */

void
module_state::write_partitions (elf_out *to, unsigned count, unsigned *crc_ptr)
{
  dump () && dump ("Writing %u elided partitions", count);
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  for (unsigned ix = 1; ix != modules->length (); ix++)
    {
      module_state *imp = (*modules)[ix];
      if (imp->is_partition ())
	{
	  dump () && dump ("Writing elided partition %M (crc=%x)",
			   imp, imp->crc);
	  sec.str (imp->get_flatname ());
	  sec.u32 (imp->crc);
	  write_location (sec, imp->is_direct ()
			  ? imp->imported_from () : UNKNOWN_LOCATION);
	  sec.str (imp->filename);
	}
    }

  sec.end (to, to->name (MOD_SNAME_PFX ".prt"), crc_ptr);
  dump.outdent ();
}

bool
module_state::read_partitions (unsigned count)
{
  bytes_in sec;
  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".prt"))
    return false;

  dump () && dump ("Reading %u elided partitions", count);
  dump.indent ();

  while (count--)
    {
      const char *name = sec.str (NULL);
      unsigned crc = sec.u32 ();
      location_t floc = read_location (sec);
      const char *fname = sec.str (NULL);

      if (sec.get_overrun ())
	break;

      dump () && dump ("Reading elided partition %s (crc=%x)", name, crc);

      module_state *imp = get_module (name);
      if (!imp	/* Partition should be ...  */
	  || !imp->is_partition () /* a partition ...  */
	  || imp->loadedness != ML_NONE  /* that is not yet loaded ...  */
	  || get_primary (imp) != this) /* whose primary is this.  */
	{
	  sec.set_overrun ();
	  break;
	}

      if (!imp->has_location ())
	imp->loc = floc;
      imp->crc = crc;
      if (!imp->filename && fname[0])
	imp->filename = xstrdup (fname);
    }

  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* Counter indices.  */
enum module_state_counts
{
  MSC_sec_lwm,
  MSC_sec_hwm,
  MSC_pendings,
  MSC_entities,
  MSC_namespaces,
  MSC_bindings,
  MSC_macros,
  MSC_inits,
  MSC_HWM
};

/* Data for config reading and writing.  */
struct module_state_config {
  const char *dialect_str;
  unsigned num_imports;
  unsigned num_partitions;
  unsigned num_entities;
  unsigned ordinary_locs;
  unsigned macro_locs;
  unsigned ordinary_loc_align;

public:
  module_state_config ()
    :dialect_str (get_dialect ()),
     num_imports (0), num_partitions (0), num_entities (0),
     ordinary_locs (0), macro_locs (0), ordinary_loc_align (0)
  {
  }

  static void release ()
  {
    XDELETEVEC (dialect);
    dialect = NULL;
  }

private:
  static const char *get_dialect ();
  static char *dialect;
};

char *module_state_config::dialect;

/* Generate a string of the significant compilation options.
   Generally assume the user knows what they're doing, in the same way
   that object files can be mixed.  */

const char *
module_state_config::get_dialect ()
{
  if (!dialect)
    dialect = concat (get_cxx_dialect_name (cxx_dialect),
		      /* C++ implies these, only show if disabled.  */
		      flag_exceptions ? "" : "/no-exceptions",
		      flag_rtti ? "" : "/no-rtti",
		      flag_new_inheriting_ctors ? "" : "/old-inheriting-ctors",
		      /* C++ 20 implies concepts.  */
		      cxx_dialect < cxx20 && flag_concepts ? "/concepts" : "",
		      flag_coroutines ? "/coroutines" : "",
		      flag_module_implicit_inline ? "/implicit-inline" : "",
		      NULL);

  return dialect;
}

/* Contents of a cluster.  */
enum cluster_tag {
  ct_decl,	/* A decl.  */
  ct_defn,	/* A definition.  */
  ct_bind,	/* A binding.  */
  ct_hwm
};

/* Binding modifiers.  */
enum ct_bind_flags
{
  cbf_export = 0x1,	/* An exported decl.  */
  cbf_hidden = 0x2,	/* A hidden (friend) decl.  */
  cbf_using = 0x4,	/* A using decl.  */
  cbf_wrapped = 0x8,  	/* ... that is wrapped.  */
};

/* DEP belongs to a different cluster, seed it to prevent
   unfortunately timed duplicate import.  */
// FIXME: QOI For inter-cluster references we could just only pick
// one entity from an earlier cluster.  Even better track
// dependencies between earlier clusters

void
module_state::intercluster_seed (trees_out &sec, unsigned index_hwm, depset *dep)
{
  if (dep->is_import ()
      || dep->cluster < index_hwm)
    {
      tree ent = dep->get_entity ();
      if (!TREE_VISITED (ent))
	{
	  sec.tree_node (ent);
	  dump (dumper::CLUSTER)
	    && dump ("Seeded %s %N",
		     dep->is_import () ? "import" : "intercluster", ent);
	}
    }
}

/* Write the cluster of depsets in SCC[0-SIZE).
   dep->section -> section number
   dep->cluster -> entity number
 */

unsigned
module_state::write_cluster (elf_out *to, depset *scc[], unsigned size,
			     depset::hash &table, unsigned *counts,
			     unsigned *crc_ptr)
{
  dump () && dump ("Writing section:%u %u depsets", table.section, size);
  dump.indent ();

  trees_out sec (to, this, table, table.section);
  sec.begin ();
  unsigned index_lwm = counts[MSC_entities];

  /* Determine entity numbers, mark for writing.   */
  dump (dumper::CLUSTER) && dump ("Cluster members:") && (dump.indent (), true);
  for (unsigned ix = 0; ix != size; ix++)
    {
      depset *b = scc[ix];

      switch (b->get_entity_kind ())
	{
	default:
	  gcc_unreachable ();

	case depset::EK_BINDING:
	  {
	    dump (dumper::CLUSTER)
	      && dump ("[%u]=%s %P", ix, b->entity_kind_name (),
		       b->get_entity (), b->get_name ());
	    depset *ns_dep = b->deps[0];
	    gcc_checking_assert (ns_dep->get_entity_kind ()
				 == depset::EK_NAMESPACE
				 && ns_dep->get_entity () == b->get_entity ());
	    for (unsigned jx = b->deps.length (); --jx;)
	      {
		depset *dep = b->deps[jx];
		// We could be declaring something that is also a
		// (merged) import
		gcc_checking_assert (dep->is_import ()
				     || TREE_VISITED (dep->get_entity ())
				     || (dep->get_entity_kind ()
					 == depset::EK_USING));
	      }
	  }
	  break;

	case depset::EK_DECL:
	case depset::EK_SPECIALIZATION:
	case depset::EK_PARTIAL:
	  b->cluster = counts[MSC_entities]++;
	  sec.mark_declaration (b->get_entity (), b->has_defn ());
	  /* FALLTHROUGH  */

	case depset::EK_USING:
	  gcc_checking_assert (!b->is_import ()
			       && !b->is_unreached ());
	  dump (dumper::CLUSTER)
	    && dump ("[%u]=%s %s %N", ix, b->entity_kind_name (),
		     b->has_defn () ? "definition" : "declaration",
		     b->get_entity ());
	  break;
	}
    }
  dump (dumper::CLUSTER) && (dump.outdent (), true);

  /* Ensure every out-of-cluster decl is referenced before we start
     streaming.  We must do both imports *and* earlier clusters,
     because the latter could reach into the former and cause a
     duplicate loop.   */
  sec.set_importing (+1);
  for (unsigned ix = 0; ix != size; ix++)
    {
      depset *b = scc[ix];
      for (unsigned jx = (b->get_entity_kind () == depset::EK_BINDING
			  || b->is_special ()) ? 1 : 0;
	   jx != b->deps.length (); jx++)
	{
	  depset *dep = b->deps[jx];

	  if (dep->is_binding ())
	    {
	      for (unsigned ix = dep->deps.length (); --ix;)
		{
		  depset *bind = dep->deps[ix];
		  if (bind->get_entity_kind () == depset::EK_USING)
		    bind = bind->deps[1];

		  intercluster_seed (sec, index_lwm, bind);
		}
	      /* Also check the namespace itself.  */
	      dep = dep->deps[0];
	    }

	  intercluster_seed (sec, index_lwm, dep);
	}
    }
  sec.tree_node (NULL_TREE);
  /* We're done importing now.  */
  sec.set_importing (-1);

  /* Write non-definitions.  */
  for (unsigned ix = 0; ix != size; ix++)
    {
      depset *b = scc[ix];
      tree decl = b->get_entity ();
      switch (b->get_entity_kind ())
	{
	default:
	  gcc_unreachable ();
	  break;

	case depset::EK_BINDING:
	  {
	    gcc_assert (TREE_CODE (decl) == NAMESPACE_DECL);
	    dump () && dump ("Depset:%u binding %C:%P", ix, TREE_CODE (decl),
			     decl, b->get_name ());
	    sec.u (ct_bind);
	    sec.tree_node (decl);
	    sec.tree_node (b->get_name ());

	    /* Write in reverse order, so reading will see the exports
	       first, thus building the overload chain will be
	       optimized.  */
	    for (unsigned jx = b->deps.length (); --jx;)
	      {
		depset *dep = b->deps[jx];
		tree bound = dep->get_entity ();
		unsigned flags = 0;
		if (dep->get_entity_kind () == depset::EK_USING)
		  {
		    tree ovl = bound;
		    bound = OVL_FUNCTION (bound);
		    if (!(TREE_CODE (bound) == CONST_DECL
			  && UNSCOPED_ENUM_P (TREE_TYPE (bound))
			  && decl == TYPE_NAME (TREE_TYPE (bound))))
		      {
			/* An unscope enumerator in its enumeration's
			   scope is not a using.  */
			flags |= cbf_using;
			if (OVL_USING_P (ovl))
			  flags |= cbf_wrapped;
		      }
		    if (OVL_EXPORT_P (ovl))
		      flags |= cbf_export;
		  }
		else
		  {
		    /* An implicit typedef must be at one.  */
		    gcc_assert (!DECL_IMPLICIT_TYPEDEF_P (bound) || jx == 1);
		    if (dep->is_hidden ())
		      flags |= cbf_hidden;
		    else if (DECL_MODULE_EXPORT_P (STRIP_TEMPLATE (bound)))
		      flags |= cbf_export;
		  }

		gcc_checking_assert (DECL_P (bound));

		sec.i (flags);
		sec.tree_node (bound);
	      }

	    /* Terminate the list.  */
	    sec.i (-1);
	  }
	  break;

	case depset::EK_USING:
	  dump () && dump ("Depset:%u %s %C:%N", ix, b->entity_kind_name (),
			   TREE_CODE (decl), decl);
	  break;

	case depset::EK_SPECIALIZATION:
	case depset::EK_PARTIAL:
	case depset::EK_DECL:
	  dump () && dump ("Depset:%u %s entity:%u %C:%N", ix,
			   b->entity_kind_name (), b->cluster,
			   TREE_CODE (decl), decl);

	  sec.u (ct_decl);
	  sec.tree_node (decl);

	  dump () && dump ("Wrote declaration entity:%u %C:%N",
			   b->cluster, TREE_CODE (decl), decl);
	  break;
	}
    }

  depset *namer = NULL;

  /* Write out definitions  */
  for (unsigned ix = 0; ix != size; ix++)
    {
      depset *b = scc[ix];
      tree decl = b->get_entity ();
      switch (b->get_entity_kind ())
	{
	default:
	  break;

	case depset::EK_SPECIALIZATION:
	case depset::EK_PARTIAL:
	case depset::EK_DECL:
	  if (!namer)
	    namer = b;

	  if (b->has_defn ())
	    {
	      sec.u (ct_defn);
	      sec.tree_node (decl);
	      dump () && dump ("Writing definition %N", decl);
	      sec.write_definition (decl);

	      if (!namer->has_defn ())
		namer = b;
	    }
	  break;
	}
    }

  /* We don't find the section by name.  Use depset's decl's name for
     human friendliness.  */
  unsigned name = 0;
  tree naming_decl = NULL_TREE;
  if (namer)
    {
      naming_decl = namer->get_entity ();
      if (namer->get_entity_kind () == depset::EK_USING)
	/* This unfortunately names the section from the target of the
	   using decl.  But the name is only a guide, so Do Not Care.  */
	naming_decl = OVL_FUNCTION (naming_decl);
      if (DECL_IMPLICIT_TYPEDEF_P (naming_decl))
	/* Lose any anonymousness.  */
	naming_decl = TYPE_NAME (TREE_TYPE (naming_decl));
      name = to->qualified_name (naming_decl, namer->has_defn ());
    }

  unsigned bytes = sec.pos;
  unsigned snum = sec.end (to, name, crc_ptr);

  for (unsigned ix = size; ix--;)
    gcc_checking_assert (scc[ix]->section == snum);

  dump.outdent ();
  dump () && dump ("Wrote section:%u named-by:%N", table.section, naming_decl);

  return bytes;
}

/* Read a cluster from section SNUM.  */

bool
module_state::read_cluster (unsigned snum)
{
  trees_in sec (this);

  if (!sec.begin (loc, from (), snum))
    return false;

  dump () && dump ("Reading section:%u", snum);
  dump.indent ();

  /* We care about structural equality.  */
  comparing_dependent_aliases++;

  /* First seed the imports.  */
  while (tree import = sec.tree_node ())
    dump (dumper::CLUSTER) && dump ("Seeded import %N", import);

  while (!sec.get_overrun () && sec.more_p ())
    {
      unsigned ct = sec.u ();
      switch (ct)
	{
	default:
	  sec.set_overrun ();
	  break;

	case ct_bind:
	  /* A set of namespace bindings.  */
	  {
	    tree ns = sec.tree_node ();
	    tree name = sec.tree_node ();
	    tree decls = NULL_TREE;
	    tree visible = NULL_TREE;
	    tree type = NULL_TREE;
	    bool dedup = false;

	    /* We rely on the bindings being in the reverse order of
	       the resulting overload set.  */
	    for (;;)
	      {
		int flags = sec.i ();
		if (flags < 0)
		  break;

		if ((flags & cbf_hidden)
		    && (flags & (cbf_using | cbf_export)))
		  sec.set_overrun ();

		tree decl = sec.tree_node ();
		if (sec.get_overrun ())
		  break;

		if (decls && TREE_CODE (decl) == TYPE_DECL)
		  {
		    /* Stat hack.  */
		    if (type || !DECL_IMPLICIT_TYPEDEF_P (decl))
		      sec.set_overrun ();
		    type = decl;
		  }
		else
		  {
		    if (decls
			|| (flags & (cbf_hidden | cbf_wrapped))
			|| DECL_FUNCTION_TEMPLATE_P (decl))
		      {
			decls = ovl_make (decl, decls);
			if (flags & cbf_using)
			  {
			    dedup = true;
			    OVL_USING_P (decls) = true;
			    if (flags & cbf_export)
			      OVL_EXPORT_P (decls) = true;
			  }

			if (flags & cbf_hidden)
			  OVL_HIDDEN_P (decls) = true;
			else if (dedup)
			  OVL_DEDUP_P (decls) = true;
		      }
		    else
		      decls = decl;

		    if (flags & cbf_export
			|| (!(flags & cbf_hidden)
			    && (is_module () || is_partition ())))
		      visible = decls;
		  }
	      }

	    if (!decls)
	      sec.set_overrun ();

	    if (sec.get_overrun ())
	      break; /* Bail.  */

	    dump () && dump ("Binding of %P", ns, name);
	    if (!set_module_binding (ns, name, mod,
				     is_header () ? -1
				     : is_module () || is_partition () ? 1
				     : 0,
				     decls, type, visible))
	      sec.set_overrun ();
	  }
	  break;

	case ct_decl:
	  /* A decl.  */
	  {
	    tree decl = sec.tree_node ();
	    dump () && dump ("Read declaration of %N", decl);
	  }
	  break;

	case ct_defn:
	  {
	    tree decl = sec.tree_node ();
	    dump () && dump ("Reading definition of %N", decl);
	    sec.read_definition (decl);
	  }
	  break;
	}
    }

  /* When lazy loading is in effect, we can be in the middle of
     parsing or instantiating a function.  Save it away.
     push_function_context does too much work.   */
  tree old_cfd = current_function_decl;
  struct function *old_cfun = cfun;
  while (tree decl = sec.post_process ())
    {
      bool abstract = false;
      if (TREE_CODE (decl) == TEMPLATE_DECL)
	{
	  abstract = true;
	  decl = DECL_TEMPLATE_RESULT (decl);
	}

      current_function_decl = decl;
      allocate_struct_function (decl, abstract);
      cfun->language = ggc_cleared_alloc<language_function> ();
      cfun->language->base.x_stmt_tree.stmts_are_full_exprs_p = 1;

      if (abstract)
	;
      else if (DECL_ABSTRACT_P (decl))
	vec_safe_push (post_load_decls, decl);
      else
	{
	  bool aggr = aggregate_value_p (DECL_RESULT (decl), decl);
#ifdef PCC_STATIC_STRUCT_RETURN
	  cfun->returns_pcc_struct = aggr;
#endif
	  cfun->returns_struct = aggr;

	  if (DECL_COMDAT (decl))
	    // FIXME: Comdat grouping?
	    comdat_linkage (decl);
	  note_vague_linkage_fn (decl);
	  cgraph_node::finalize_function (decl, true);
	}

    }
  /* Look, function.c's interface to cfun does too much for us, we
     just need to restore the old value.  I do not want to go
     redesigning that API right now.  */
#undef cfun
  cfun = old_cfun;
  current_function_decl = old_cfd;
  comparing_dependent_aliases--;

  dump.outdent ();
  dump () && dump ("Read section:%u", snum);

  loaded_clusters++;

  if (!sec.end (from ()))
    return false;

  return true;
}

void
module_state::write_namespace (bytes_out &sec, depset *dep)
{
  unsigned ns_num = dep->cluster;
  unsigned ns_import = 0;

  if (dep->is_import ())
    ns_import = dep->section;
  else if (dep->get_entity () != global_namespace)
    ns_num++;

  sec.u (ns_import);
  sec.u (ns_num);
}

tree
module_state::read_namespace (bytes_in &sec)
{
  unsigned ns_import = sec.u ();
  unsigned ns_num = sec.u ();
  tree ns = NULL_TREE;

  if (ns_import || ns_num)
    {
      if (!ns_import)
	ns_num--;

      if (unsigned origin = slurp->remap_module (ns_import))
	{
	  module_state *from = (*modules)[origin];
	  if (ns_num < from->entity_num)
	    {
	      binding_slot &slot = (*entity_ary)[from->entity_lwm + ns_num];

	      if (!slot.is_lazy ())
		ns = slot;
	    }
	}
      else
	sec.set_overrun ();
    }
  else
    ns = global_namespace;

  return ns;
}

/* SPACES is a sorted vector of namespaces.  Write out the namespaces
   to MOD_SNAME_PFX.nms section.   */

void
module_state::write_namespaces (elf_out *to, vec<depset *> spaces,
				unsigned num, unsigned *crc_p)
{
  dump () && dump ("Writing namespaces");
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  for (unsigned ix = 0; ix != num; ix++)
    {
      depset *b = spaces[ix];
      tree ns = b->get_entity ();

      gcc_checking_assert (TREE_CODE (ns) == NAMESPACE_DECL);
      /* P1815 may have something to say about this.  */
      gcc_checking_assert (TREE_PUBLIC (ns));

      unsigned flags = 0;
      if (TREE_PUBLIC (ns))
	flags |= 1;
      if (DECL_NAMESPACE_INLINE_P (ns))
	flags |= 2;
      if (DECL_MODULE_PURVIEW_P (ns))
	flags |= 4;
      if (DECL_MODULE_EXPORT_P (ns))
	flags |= 8;

      dump () && dump ("Writing namespace:%u %N%s%s%s%s",
		       b->cluster, ns,
		       flags & 1 ? ", public" : "", 
		       flags & 2 ? ", inline" : "",
		       flags & 4 ? ", purview" : "",
		       flags & 8 ? ", export" : "");
      sec.u (b->cluster);
      sec.u (to->name (DECL_NAME (ns)));
      write_namespace (sec, b->deps[0]);

      sec.u (flags);
      write_location (sec, DECL_SOURCE_LOCATION (ns));
    }

  sec.end (to, to->name (MOD_SNAME_PFX ".nms"), crc_p);
  dump.outdent ();
}

/* Read the namespace hierarchy from MOD_SNAME_PFX.namespace.  Fill in
   SPACES from that data.  */

bool
module_state::read_namespaces (unsigned num)
{
  bytes_in sec;

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".nms"))
    return false;

  dump () && dump ("Reading namespaces");
  dump.indent ();

  for (unsigned ix = 0; ix != num; ix++)
    {
      unsigned entity_index = sec.u ();
      unsigned name = sec.u ();

      tree parent = read_namespace (sec);

      /* See comment in write_namespace about why not bits.  */
      unsigned flags = sec.u ();
      location_t src_loc = read_location (sec);

      if (entity_index >= entity_num
	  || !parent
	  || (flags & 0xc) == 0x8)
	sec.set_overrun ();
      if (sec.get_overrun ())
	break;

      tree id = name ? get_identifier (from ()->name (name)) : NULL_TREE;

      dump () && dump ("Read namespace:%u %P%s%s%s%s",
		       entity_index, parent, id,
		       flags & 1 ? ", public" : "", 
		       flags & 2 ? ", inline" : "",
		       flags & 4 ? ", purview" : "",
		       flags & 8 ? ", export" : "");
      bool visible_p = ((flags & 8)
			|| ((flags & 1)
			    && (flags & 4)
			    && (is_partition () || is_module ())));
      tree inner = add_imported_namespace (parent, id, src_loc, mod,
					   bool (flags & 2), visible_p);
      if (!inner)
	{
	  sec.set_overrun ();
	  break;
	}

      if (is_partition ())
	{
	  if (flags & 4)
	    DECL_MODULE_PURVIEW_P (inner) = true;
	  if (flags & 8)
	    DECL_MODULE_EXPORT_P (inner) = true;
	}

      /* Install the namespace.  */
      (*entity_ary)[entity_lwm + entity_index] = inner;
      if (DECL_MODULE_IMPORT_P (inner))
	{
	  bool existed;
	  unsigned *slot = &entity_map->get_or_insert
	    (DECL_UID (inner), &existed);
	  if (existed)
	    /* If it existed, it should match.  */
	    gcc_checking_assert (inner == (*entity_ary)[*slot]);
	  else
	    *slot = entity_lwm + entity_index;
	}
    }
  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* Write the binding TABLE to MOD_SNAME_PFX.bnd   */

unsigned
module_state::write_bindings (elf_out *to, vec<depset *> sccs, unsigned *crc_p)
{
  dump () && dump ("Writing binding table");
  dump.indent ();

  unsigned num = 0;
  bytes_out sec (to);
  sec.begin ();

  for (unsigned ix = 0; ix != sccs.length (); ix++)
    {
      depset *b = sccs[ix];
      if (b->is_binding ())
	{
	  tree ns = b->get_entity ();
	  dump () && dump ("Bindings %P section:%u", ns, b->get_name (),
			   b->section);
	  sec.u (to->name (b->get_name ()));
	  write_namespace (sec, b->deps[0]);
	  sec.u (b->section);
	  num++;
	}
    }

  sec.end (to, to->name (MOD_SNAME_PFX ".bnd"), crc_p);
  dump.outdent ();

  return num;
}

/* Read the binding table from MOD_SNAME_PFX.bind.  */

bool
module_state::read_bindings (unsigned num, unsigned lwm, unsigned hwm)
{
  bytes_in sec;

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".bnd"))
    return false;

  dump () && dump ("Reading binding table");
  dump.indent ();
  for (; !sec.get_overrun () && num--;)
    {
      const char *name = from ()->name (sec.u ());
      tree ns = read_namespace (sec);
      unsigned snum = sec.u ();

      if (!ns || !name || (snum - lwm) >= (hwm - lwm))
	sec.set_overrun ();
      if (!sec.get_overrun ())
	{
	  tree id = get_identifier (name);
	  dump () && dump ("Bindings %P section:%u", ns, id, snum);
	  if (mod && !import_module_binding (ns, id, mod, snum))
	    break;
	}
    }

  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* Write the entity table to MOD_SNAME_PFX.ent

   Each entry is a section number.  */

void
module_state::write_entities (elf_out *to, vec<depset *> depsets,
			      unsigned count, unsigned *crc_p)
{
  dump () && dump ("Writing entities");
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  unsigned current = 0;
  for (unsigned ix = 0; ix < depsets.length (); ix++)
    {
      depset *d = depsets[ix];

      switch (d->get_entity_kind ())
	{
	default:
	  break;

	case depset::EK_NAMESPACE:
	  if (!d->is_import () && d->get_entity () != global_namespace)
	    {
	      gcc_checking_assert (d->cluster == current);
	      current++;
	      sec.u (0);
	    }
	  break;

	case depset::EK_DECL:
	case depset::EK_SPECIALIZATION:
	case depset::EK_PARTIAL:
	  gcc_checking_assert (!d->is_unreached ()
			       && !d->is_import ()
			       && d->cluster == current
			       && d->section);
	  current++;
	  sec.u (d->section);
	  break;
	}
    }
  gcc_assert (count == current);
  sec.end (to, to->name (MOD_SNAME_PFX ".ent"), crc_p);
  dump.outdent ();
}

bool
module_state::read_entities (unsigned count, unsigned lwm, unsigned hwm)
{
  trees_in sec (this);

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".ent"))
    return false;

  dump () && dump ("Reading entities");
  dump.indent ();

  for (binding_slot *slot = entity_ary->begin () + entity_lwm; count--; slot++)
    {
      unsigned snum = sec.u ();
      if (snum && (snum - lwm) >= (hwm - lwm))
	sec.set_overrun ();
      if (sec.get_overrun ())
	break;

      if (snum)
	slot->set_lazy (snum << 2);
    }

  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* Write the pending table to MOD_SNAME_PFX.pnd

   The pending table holds information about clusters that need to be
   loaded because they contain information about something that is not
   found by namespace-scope lookup.

   The three cases are:

   (a) Template (maybe-partial) specializations that we have
   instantiated or defined.  When an importer needs to instantiate
   that template, they /must have/ the partial, explicit & extern
   specializations available.  If they have the other specializations
   available, they'll have less work to do.  Thus, when we're about to
   instantiate FOO, we have to be able to ask 'are there any
   specialization of FOO in our imports?'.

   (b) (Maybe-implicit) member functions definitions.  A class could
   be defined in one header, and an inline member defined in a
   different header (this occurs in the STL).  Similarly, like the
   specialization case, an implicit member function could have been
   'instantiated' in one module, and it'd be nice to not have to
   reinstantiate it in another.

   (c) A member classes completed elsewhere.  A member class could be
   declared in one header and defined in another.  We need to know to
   load the class definition before looking in it.  This turns out to
   be a specific case of #b, so we can treat these the same.  But it
   does highlight an issue -- there could be an intermediate import
   between the outermost containing namespace-scope class and the
   innermost being-defined member class.  This is actually possible
   with all of these cases, so be aware -- we're not just talking of
   one level of import to get to the innermost namespace.

   This gets complicated fast, it took me multiple attempts to even
   get something remotely working.  Partially because I focussed on
   optimizing what I think turns out to be a smaller problem, given
   the known need to do the more general case *anyway*.  I document
   the smaller problem, because it does appear to be the natural way
   to do it.  It's trap!

   **** THE TRAP

   Let's refer to the primary template or the containing class as the
   KEY.  And the specialization or member as the PENDING-ENTITY.  (To
   avoid having to say those mouthfuls all the time.)

   In either case, we have an entity and we need some way of mapping
   that to a set of entities that need to be loaded before we can
   proceed with whatever processing of the entity we were going to do.

   We need to link the key to the pending-entity in some way.  Given a
   key, tell me the pending-entities I need to have loaded.  However
   we tie the key to the pending-entity must not rely on the key being
   loaded -- that'd defeat the lazy loading scheme.

   As the key will be an import in we know its entity number (either
   because we imported it, or we're writing it out too).  Thus we can
   generate a map of key-indices to pending-entities.  The
   pending-entity indices will be into our span of the entity table,
   and thus allow them to be lazily loaded.  The key index will be
   into another slot of the entity table.  Notice that this checking
   could be expensive, we don't want to iterate over a bunch of
   pending-entity indices (across multiple imports), every time we're
   about do to the thing with the key.  We need to quickly determine
   'definitely nothing needed'.

   That's almost good enough, except that key indices are not unique
   in a couple of cases :( Specifically the Global Module or a module
   partition can result in multiple modules assigning an entity index
   for the key.  The decl-merging on loading will detect that so we
   only have one Key loaded, and in the entity hash it'll indicate the
   entity index of first load.  Which might be different to how we
   know it.  Notice this is restricted to GM entities or this-module
   entities.  Foreign imports cannot have this.

   We can simply resolve this in the direction of how this module
   referred to the key to how the importer knows it.  Look in the
   entity table slot that we nominate, maybe lazy load it, and then
   lookup the resultant entity in the entity hash to learn how the
   importer knows it.

   But we need to go in the other direction :( Given the key, find all
   the index-aliases of that key.  We can partially solve that by
   adding an alias hash table.  Whenever we load a merged decl, add or
   augment a mapping from the entity (or its entity-index) to the
   newly-discovered index.  Then when we look for pending entities of
   a key, we also iterate over this aliases this mapping provides.

   But that requires the alias to be loaded.  And that's not
   necessarily true.

   *** THE SIMPLER WAY

   The remaining fixed thing we have is the innermost namespace
   containing the ultimate namespace-scope container of the key and
   the name of that container (which might be the key itself).  I.e. a
   namespace-decl/identifier/module tuple.  Let's call this the
   top-key.  We'll discover that the module is not important here,
   because of cross-module possibilities mentioned in case #c above.
   We can't markup namespace-binding slots.  The best we can do is
   mark the binding vector with 'there's something here', and have
   another map from namespace/identifier pairs to a vector of pending
   entity indices.

   Maintain a pending-entity map.  This is keyed by top-key, and
   maps to a vector of pending-entity indices.  On the binding vector
   have flags saying whether the pending-name-entity map has contents.
   (We might want to further extend the key to be GM-vs-Partition and
   specialization-vs-member, but let's not get ahead of ourselves.)

   For every key-like entity, find the outermost namespace-scope
   name.  Use that to lookup in the pending-entity map and then make
   sure the specified entities are loaded.

   An optimization might be to have a flag in each key-entity saying
   that it's top key might be in the entity table.  It's not clear to
   me how to set that flag cheaply -- cheaper than just looking.

   FIXME: It'd be nice to have a bit in decls to tell us whether to
   even try this.  We can have a 'already done' flag, that we set when
   we've done KLASS's lazy pendings.  When we import a module that
   registers pendings on the same top-key as KLASS we need to clear
   the flag.  A recursive walk of the top-key clearing the bit will
   suffice.  Plus we only need to recurse on classes that have the bit
   set.  (That means we need to set the bit on parents of KLASS here,
   don't forget.)  However, first: correctness, second: efficiency.  */

unsigned
module_state::write_pendings (elf_out *to, vec<depset *> depsets,
			      depset::hash &table, unsigned *crc_p)
{
  dump () && dump ("Writing pending-entities");
  dump.indent ();

  trees_out sec (to, this, table);
  sec.begin ();

  unsigned count = 0;
  tree cache_ns = NULL_TREE;
  tree cache_id = NULL_TREE;
  unsigned cache_section = ~0;
  for (unsigned ix = 0; ix < depsets.length (); ix++)
    {
      depset *d = depsets[ix];

      if (d->is_binding ())
	continue;

      if (d->is_import ())
	continue;

      if (!(d->get_entity_kind () == depset::EK_SPECIALIZATION
	    || d->get_entity_kind () == depset::EK_PARTIAL
	    || (d->get_entity_kind () == depset::EK_DECL && d->is_member ())))
	continue;

      tree key_decl = nullptr;
      tree key_ns = find_pending_key (d->get_entity (), &key_decl);
      tree key_name = DECL_NAME (key_decl);

      if (IDENTIFIER_ANON_P (key_name))
	{
	  gcc_checking_assert (IDENTIFIER_LAMBDA_P (key_name));
	  if (tree attached = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (key_decl)))
	    key_name = DECL_NAME (attached);
	  else
	    {
	      /* There's nothing to attach it to.  Must
		 always reinstantiate.  */
	      dump ()
		&& dump ("Unattached lambda %N[%u] section:%u",
			 d->get_entity_kind () == depset::EK_DECL
			 ? "Member" : "Specialization", d->get_entity (),
			 d->cluster, d->section);
	      continue;
	    }
	}

      char const *also = "";
      if (d->section == cache_section
	  && key_ns == cache_ns
	  && key_name == cache_id)
	/* Same section & key as previous, no need to repeat ourselves.  */
	also = "also ";
      else
	{
	  cache_ns = key_ns;
	  cache_id = key_name;
	  cache_section = d->section;
	  gcc_checking_assert (table.find_dependency (cache_ns));
	  sec.tree_node (cache_ns);
	  sec.tree_node (cache_id);
	  sec.u (d->cluster);
	  count++;
	}
      dump () && dump ("Pending %s %N entity:%u section:%u %skeyed to %P",
		       d->get_entity_kind () == depset::EK_DECL
		       ? "member" : "specialization", d->get_entity (),
		       d->cluster, cache_section, also, cache_ns, cache_id);
      }
  sec.end (to, to->name (MOD_SNAME_PFX ".pnd"), crc_p);
  dump.outdent ();

  return count;
}

bool
module_state::read_pendings (unsigned count)
{
  trees_in sec (this);

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".pnd"))
    return false;

  dump () && dump ("Reading %u pendings", count);
  dump.indent ();

  for (unsigned ix = 0; ix != count; ix++)
    {
      pending_key key;
      unsigned index;

      key.ns = sec.tree_node ();
      key.id = sec.tree_node ();
      index = sec.u ();

      if (!key.ns || !key.id
	  || !(TREE_CODE (key.ns) == NAMESPACE_DECL
	       && !DECL_NAMESPACE_ALIAS (key.ns))
	  || !identifier_p (key.id)
	  || index >= entity_num)
	sec.set_overrun ();

      if (sec.get_overrun ())
	break;

      dump () && dump ("Pending:%u keyed to %P", index, key.ns, key.id);

      index += entity_lwm;
      auto &vec = pending_table->get_or_insert (key);
      vec.safe_push (index);
    }

  dump.outdent ();
  if (!sec.end (from ()))
    return false;
  return true;
}

/* Read & write locations.  */
enum loc_kind {
  LK_ORDINARY,
  LK_MACRO,
  LK_IMPORT_ORDINARY,
  LK_IMPORT_MACRO,
  LK_ADHOC,
  LK_RESERVED,
};

static const module_state *
module_for_ordinary_loc (location_t loc)
{
  unsigned pos = 0;
  unsigned len = ool->length () - pos;

  while (len)
    {
      unsigned half = len / 2;
      module_state *probe = (*ool)[pos + half];
      if (loc < probe->ordinary_locs.first)
	len = half;
      else if (loc < probe->ordinary_locs.second)
	return probe;
      else
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
    }

  return nullptr;
}

static const module_state *
module_for_macro_loc (location_t loc)
{
  unsigned pos = 1;
  unsigned len = modules->length () - pos;

  while (len)
    {
      unsigned half = len / 2;
      module_state *probe = (*modules)[pos + half];
      if (loc >= probe->macro_locs.second)
	len = half;
      else if (loc >= probe->macro_locs.first)
	return probe;
      else
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
    }

  return NULL;
}

location_t
module_state::imported_from () const
{
  location_t from = loc;
  line_map_ordinary const *fmap
    = linemap_check_ordinary (linemap_lookup (line_table, from));

  if (MAP_MODULE_P (fmap))
    from = linemap_included_from (fmap);

  return from;
}

/* If we're not streaming, record that we need location LOC.
   Otherwise stream it.  */

void
module_state::write_location (bytes_out &sec, location_t loc)
{
  if (!sec.streaming_p ())
    /* This is where we should note we use this location.  See comment
       about write_ordinary_maps.  */
    return;

  if (loc < RESERVED_LOCATION_COUNT)
    {
      dump (dumper::LOCATION) && dump ("Reserved location %u", unsigned (loc));
      sec.u (LK_RESERVED + loc);
    }
  else if (IS_ADHOC_LOC (loc))
    {
      dump (dumper::LOCATION) && dump ("Adhoc location");
      sec.u (LK_ADHOC);
      location_t locus = get_location_from_adhoc_loc (line_table, loc);
      write_location (sec, locus);
      source_range range = get_range_from_loc (line_table, loc);
      if (range.m_start == locus)
	/* Compress.  */
	range.m_start = UNKNOWN_LOCATION;
      write_location (sec, range.m_start);
      write_location (sec, range.m_finish);
    }
  else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
    {
      if (const loc_spans::span *span = spans.macro (loc))
	{
	  unsigned off = MAX_LOCATION_T - loc;

	  off -= span->macro_delta;

	  sec.u (LK_MACRO);
	  sec.u (off);
	  dump (dumper::LOCATION)
	    && dump ("Macro location %u output %u", loc, off);
	}
      else if (const module_state *import = module_for_macro_loc (loc))
	{
	  unsigned off = import->macro_locs.second - loc - 1;
	  sec.u (LK_IMPORT_MACRO);
	  sec.u (import->remap);
	  sec.u (off);
	  dump (dumper::LOCATION)
	    && dump ("Imported macro location %u output %u:%u",
		     loc, import->remap, off);
	}
      else
	gcc_unreachable ();
    }
  else if (IS_ORDINARY_LOC (loc))
    {
      if (const loc_spans::span *span = spans.ordinary (loc))
	{
	  unsigned off = loc;

	  off += span->ordinary_delta;
	  sec.u (LK_ORDINARY);
	  sec.u (off);

	  dump (dumper::LOCATION)
	    && dump ("Ordinary location %u output %u", loc, off);
	}
      else if (const module_state *import = module_for_ordinary_loc (loc))
	{
	  unsigned off = loc - import->ordinary_locs.first;
	  sec.u (LK_IMPORT_ORDINARY);
	  sec.u (import->remap);
	  sec.u (off);
	  dump (dumper::LOCATION)
	    && dump ("Imported ordinary location %u output %u:%u",
		     import->remap, import->remap, off);
	}
      else
	gcc_unreachable ();
    }
  else
    gcc_unreachable ();
}

location_t
module_state::read_location (bytes_in &sec) const
{
  location_t locus = UNKNOWN_LOCATION;
  unsigned kind = sec.u ();
  switch (kind)
     {
    default:
      {
	if (kind < LK_RESERVED + RESERVED_LOCATION_COUNT)
	  locus = location_t (kind - LK_RESERVED);
	else
	  sec.set_overrun ();
	dump (dumper::LOCATION)
	  && dump ("Reserved location %u", unsigned (locus));
      }
      break;

     case LK_ADHOC:
      {
	dump (dumper::LOCATION) && dump ("Adhoc location");
	locus = read_location (sec);
	source_range range;
	range.m_start = read_location (sec);
	if (range.m_start == UNKNOWN_LOCATION)
	  range.m_start = locus;
	range.m_finish = read_location (sec);
	if (locus != loc && range.m_start != loc && range.m_finish != loc)
	  locus = get_combined_adhoc_loc (line_table, locus, range, NULL);
      }
      break;

    case LK_MACRO:
      {
	unsigned off = sec.u ();

	if (macro_locs.first)
	  {
	    location_t adjusted = MAX_LOCATION_T - off;
	    adjusted -= slurp->loc_deltas.second;
	    if (adjusted < macro_locs.first)
	      sec.set_overrun ();
	    else if (adjusted < macro_locs.second)
	      locus = adjusted;
	    else
	      sec.set_overrun ();
	  }
	else
	  locus = loc;
	dump (dumper::LOCATION)
	  && dump ("Macro %u becoming %u", off, locus);
      }
      break;

    case LK_ORDINARY:
      {
	unsigned off = sec.u ();
	if (ordinary_locs.second)
	  {
	    location_t adjusted = off;

	    adjusted += slurp->loc_deltas.first;
	    if (adjusted >= ordinary_locs.second)
	      sec.set_overrun ();
	    else if (adjusted >= ordinary_locs.first)
	      locus = adjusted;
	    else if (adjusted < spans.main_start ())
	      locus = off;
	  }
	else
	  locus = loc;

	dump (dumper::LOCATION)
	  && dump ("Ordinary location %u becoming %u", off, locus);
      }
      break;

     case LK_IMPORT_MACRO:
     case LK_IMPORT_ORDINARY:
       {
	 unsigned mod = sec.u ();
	 unsigned off = sec.u ();
	 const module_state *import = NULL;

	 if (!mod && !slurp->remap)
	   /* This is an early read of a partition location during the
	      read of our ordinary location map.  */
	   import = this;
	 else
	   {
	     mod = slurp->remap_module (mod);
	     if (!mod)
	       sec.set_overrun ();
	     else
	       import = (*modules)[mod];
	   }

	 if (import)
	   {
	     if (kind == LK_IMPORT_MACRO)
	       {
		 if (!import->macro_locs.first)
		   locus = import->loc;
		 else if (off < import->macro_locs.second - macro_locs.first)
		   locus = import->macro_locs.second - off - 1;
		 else
		   sec.set_overrun ();
	       }
	     else
	       {
		 if (!import->ordinary_locs.second)
		   locus = import->loc;
		 else if (off < (import->ordinary_locs.second
			    - import->ordinary_locs.first))
		   locus = import->ordinary_locs.first + off;
		 else
		   sec.set_overrun ();
	       }
	   }
       }
       break;
    }

  return locus;
}

/* Prepare the span adjustments.  */

// FIXME:QOI I do not prune the unreachable locations.  Modules with
// textually-large GMFs could well cause us to run out of locations.
// Regular single-file modules could also be affected.  We should
// determine which locations we need to represent, so that we do not
// grab more locations than necessary.  An example is in
// write_macro_maps where we work around macro expansions that are not
// covering any locations -- the macro expands to nothing.  Perhaps we
// should decompose locations so that we can have a more graceful
// degradation upon running out?

location_map_info
module_state::write_prepare_maps (module_state_config *)
{
  dump () && dump ("Preparing locations");
  dump.indent ();

  dump () && dump ("Reserved locations [%u,%u) macro [%u,%u)",
		   spans[loc_spans::SPAN_RESERVED].ordinary.first,
		   spans[loc_spans::SPAN_RESERVED].ordinary.second,
		   spans[loc_spans::SPAN_RESERVED].macro.first,
		   spans[loc_spans::SPAN_RESERVED].macro.second);

  location_map_info info;

  info.num_maps.first = info.num_maps.second = 0;

  /* Figure the alignment of ordinary location spans.  */
  unsigned max_range = 0;
  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
    {
      loc_spans::span &span = spans[ix];

      if (span.ordinary.first != span.ordinary.second)
	{
	  line_map_ordinary const *omap
	    = linemap_check_ordinary (linemap_lookup (line_table,
						      span.ordinary.first));

	  /* We should exactly match up.  */
	  gcc_checking_assert (MAP_START_LOCATION (omap) == span.ordinary.first);

	  line_map_ordinary const *fmap = omap;
	  for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
	    {
	      /* We should never find a module linemap in an interval.  */
	      gcc_checking_assert (!MAP_MODULE_P (omap));

	      if (max_range < omap->m_range_bits)
		max_range = omap->m_range_bits;
	    }

	  info.num_maps.first += omap - fmap;
	}

      if (span.macro.first != span.macro.second)
	{
	  /* Iterate over the span's macros, to elide the empty
	     expansions.  */
	  unsigned count = 0;
	  for (unsigned macro
		 = linemap_lookup_macro_index (line_table,
					       span.macro.second - 1);
	       macro < LINEMAPS_MACRO_USED (line_table);
	       macro++)
	    {
	      line_map_macro const *mmap
		= LINEMAPS_MACRO_MAP_AT (line_table, macro);
	      if (MAP_START_LOCATION (mmap) < span.macro.first)
		/* Fallen out of the span.  */
		break;

	      if (mmap->n_tokens)
		count++;
	    }
	  dump (dumper::LOCATION) && dump ("Span:%u %u macro maps", ix, count);
	  info.num_maps.second += count;
	}
    }

  /* Adjust the maps.  Ordinary ones ascend, and we must maintain
     alignment.  Macro ones descend, but are unaligned.  */
  location_t ord_off = spans[loc_spans::SPAN_FIRST].ordinary.first;
  location_t mac_off = spans[loc_spans::SPAN_FIRST].macro.second;
  location_t range_mask = (1u << max_range) - 1;

  dump () && dump ("Ordinary maps range bits:%u, preserve:%x, zero:%u",
		   max_range, ord_off & range_mask, ord_off & ~range_mask);

  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
    {
      loc_spans::span &span = spans[ix];

      span.macro_delta = mac_off - span.macro.second;
      mac_off -= span.macro.second - span.macro.first;
      dump () && dump ("Macro span:%u [%u,%u):%u->%d(%u)", ix,
		       span.macro.first, span.macro.second,
		       span.macro.second - span.macro.first,
		       span.macro_delta, span.macro.first + span.macro_delta);

      line_map_ordinary const *omap
	= linemap_check_ordinary (linemap_lookup (line_table,
						      span.ordinary.first));
      location_t base = MAP_START_LOCATION (omap);

      /* Preserve the low MAX_RANGE bits of base by incrementing ORD_OFF.  */
      unsigned low_bits = base & range_mask;
      if ((ord_off & range_mask) > low_bits)
	low_bits += range_mask + 1;
      ord_off = (ord_off & ~range_mask) + low_bits;
      span.ordinary_delta = ord_off - base;

      for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
	{
	  location_t start_loc = MAP_START_LOCATION (omap);
	  unsigned to = start_loc + span.ordinary_delta;
	  location_t end_loc = MAP_START_LOCATION (omap + 1);

	  dump () && dump ("Ordinary span:%u [%u,%u):%u->%d(%u)",
			   ix, start_loc,
			   end_loc, end_loc - start_loc,
			   span.ordinary_delta, to);

	  /* There should be no change in the low order bits.  */
	  gcc_checking_assert (((start_loc ^ to) & range_mask) == 0);
	}

      /* The ending serialized value.  */
      ord_off = span.ordinary.second + span.ordinary_delta;
    }

  dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps lwm:%u ",
		   info.num_maps.first, ord_off,
		   info.num_maps.second, mac_off);

  dump.outdent ();

  info.max_range = max_range;
  
  return info;
}

bool
module_state::read_prepare_maps (const module_state_config *cfg)
{
  location_t ordinary = line_table->highest_location + 1;
  ordinary = ((ordinary + (1u << cfg->ordinary_loc_align))
	      & ~((1u << cfg->ordinary_loc_align) - 1));
  ordinary += cfg->ordinary_locs;

  location_t macro = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  macro -= cfg->macro_locs;

  if (ordinary < LINE_MAP_MAX_LOCATION_WITH_COLS
      && macro >= LINE_MAP_MAX_LOCATION)
    /* OK, we have enough locations.  */
    return true;

  ordinary_locs.first = ordinary_locs.second = 0;
  macro_locs.first = macro_locs.second = 0;

  static bool informed = false;
  if (!informed)
    {
      /* Just give the notice once.  */
      informed = true;
      inform (loc, "unable to represent further imported source locations");
    }

  return false;
}

/* Write the location maps.  This also determines the shifts for the
   location spans.  */

void
module_state::write_ordinary_maps (elf_out *to, location_map_info &info,
				   module_state_config *cfg, bool has_partitions,
				   unsigned *crc_p)
{
  dump () && dump ("Writing ordinary location maps");
  dump.indent ();

  vec<const char *> filenames;
  filenames.create (20);

  /* Determine the unique filenames.  */
  // FIXME:QOI We should find the set of filenames when working out
  // which locations we actually need.  See write_prepare_maps.
  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
    {
      loc_spans::span &span = spans[ix];
      line_map_ordinary const *omap
	= linemap_check_ordinary (linemap_lookup (line_table,
						  span.ordinary.first));

      /* We should exactly match up.  */
      gcc_checking_assert (MAP_START_LOCATION (omap) == span.ordinary.first);

      for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
	{
	  const char *fname = ORDINARY_MAP_FILE_NAME (omap);

	  /* We should never find a module linemap in an interval.  */
	  gcc_checking_assert (!MAP_MODULE_P (omap));

	  /* We expect very few filenames, so just an array.
	     (Not true when headers are still in play :()  */
	  for (unsigned jx = filenames.length (); jx--;)
	    {
	      const char *name = filenames[jx];
	      if (0 == strcmp (name, fname))
		{
		  /* Reset the linemap's name, because for things like
		     preprocessed input we could have multiple
		     instances of the same name, and we'd rather not
		     percolate that.  */
		  const_cast<line_map_ordinary *> (omap)->to_file = name;
		  fname = NULL;
		  break;
		}
	    }
	  if (fname)
	    filenames.safe_push (fname);
	}
    }

  bytes_out sec (to);
  sec.begin ();

  /* Write the filenames.  */
  unsigned len = filenames.length ();
  sec.u (len);
  dump () && dump ("%u source file names", len);
  for (unsigned ix = 0; ix != len; ix++)
    {
      const char *fname = filenames[ix];
      dump (dumper::LOCATION) && dump ("Source file[%u]=%s", ix, fname);
      sec.str (fname);
    }

  location_t offset = spans[loc_spans::SPAN_FIRST].ordinary.first;
  location_t range_mask = (1u << info.max_range) - 1;

  dump () && dump ("Ordinary maps:%u, range bits:%u, preserve:%x, zero:%u",
		   info.num_maps.first, info.max_range, offset & range_mask,
		   offset & ~range_mask);
  sec.u (info.num_maps.first);	/* Num maps.  */
  sec.u (info.max_range);		/* Maximum range bits  */
  sec.u (offset & range_mask);	/* Bits to preserve.  */
  sec.u (offset & ~range_mask);

  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
    {
      loc_spans::span &span = spans[ix];
      line_map_ordinary const *omap
	= linemap_check_ordinary (linemap_lookup (line_table,
						  span.ordinary.first));
      for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
	{
	  location_t start_loc = MAP_START_LOCATION (omap);
	  unsigned to = start_loc + span.ordinary_delta;

	  dump (dumper::LOCATION)
	    && dump ("Span:%u ordinary [%u,%u)->%u", ix, start_loc,
		     MAP_START_LOCATION (omap + 1), to);

	  /* There should be no change in the low order bits.  */
	  gcc_checking_assert (((start_loc ^ to) & range_mask) == 0);
	  sec.u (to);

	  /* Making accessors just for here, seems excessive.  */
	  sec.u (omap->reason);
	  sec.u (omap->sysp);
	  sec.u (omap->m_range_bits);
	  sec.u (omap->m_column_and_range_bits - omap->m_range_bits);

	  const char *fname = ORDINARY_MAP_FILE_NAME (omap);
	  for (unsigned ix = 0; ix != filenames.length (); ix++)
	    if (filenames[ix] == fname)
	      {
		sec.u (ix);
		break;
	      }
	  sec.u (ORDINARY_MAP_STARTING_LINE_NUMBER (omap));

	  /* Write the included from location, which means reading it
	     while reading in the ordinary maps.  So we'd better not
	     be getting ahead of ourselves.  */
	  location_t from = linemap_included_from (omap);
	  gcc_checking_assert (from < MAP_START_LOCATION (omap));
	  if (from != UNKNOWN_LOCATION && has_partitions)
	    {
	      /* A partition's span will have a from pointing at a
		 MODULE_INC.  Find that map's from.  */
	      line_map_ordinary const *fmap
		= linemap_check_ordinary (linemap_lookup (line_table, from));
	      if (MAP_MODULE_P (fmap))
		from = linemap_included_from (fmap);
	    }
	  write_location (sec, from);
	}
      /* The ending serialized value.  */
      offset = MAP_START_LOCATION (omap) + span.ordinary_delta;
    }
  dump () && dump ("Ordinary location hwm:%u", offset);
  sec.u (offset);

  // Record number of locations and alignment.
  cfg->ordinary_loc_align = info.max_range;
  cfg->ordinary_locs = offset;

  filenames.release ();

  sec.end (to, to->name (MOD_SNAME_PFX ".olm"), crc_p);
  dump.outdent ();
}

void
module_state::write_macro_maps (elf_out *to, location_map_info &info,
				module_state_config *cfg, unsigned *crc_p)
{
  dump () && dump ("Writing macro location maps");
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  dump () && dump ("Macro maps:%u", info.num_maps.second);
  sec.u (info.num_maps.second);

  location_t offset = spans[loc_spans::SPAN_FIRST].macro.second;
  sec.u (offset);

  unsigned macro_num = 0;
  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
    {
      loc_spans::span &span = spans[ix];
      if (span.macro.first == span.macro.second)
	/* Empty span.  */
	continue;

      for (unsigned macro
	     = linemap_lookup_macro_index (line_table, span.macro.second - 1);
	   macro < LINEMAPS_MACRO_USED (line_table);
	   macro++)
	{
	  line_map_macro const *mmap
	    = LINEMAPS_MACRO_MAP_AT (line_table, macro);
	  location_t start_loc = MAP_START_LOCATION (mmap);
	  if (start_loc < span.macro.first)
	    /* Fallen out of the span.  */
	    break;

	  if (!mmap->n_tokens)
	    /* Empty expansion.  */
	    continue;

	  sec.u (offset);
	  sec.u (mmap->n_tokens);
	  sec.cpp_node (mmap->macro);
	  write_location (sec, mmap->expansion);
	  const location_t *locs = mmap->macro_locations;
	  /* There are lots of identical runs.  */
	  location_t prev = UNKNOWN_LOCATION;
	  unsigned count = 0;
	  unsigned runs = 0;
	  for (unsigned jx = mmap->n_tokens * 2; jx--;)
	    {
	      location_t tok_loc = locs[jx];
	      if (tok_loc == prev)
		{
		  count++;
		  continue;
		}
	      runs++;
	      sec.u (count);
	      count = 1;
	      prev = tok_loc;
	      write_location (sec, tok_loc);
	    }
	  sec.u (count);
	  dump (dumper::LOCATION)
	    && dump ("Span:%u macro:%u %I %u/%u*2 locations [%u,%u)->%u",
		     ix, macro_num, identifier (mmap->macro),
		     runs, mmap->n_tokens,
		     start_loc, start_loc + mmap->n_tokens,
		     start_loc + span.macro_delta);
	  macro_num++;
	  offset -= mmap->n_tokens;
	  gcc_checking_assert (offset == start_loc + span.macro_delta);
	}
    }
  dump () && dump ("Macro location lwm:%u", offset);
  sec.u (offset);
  gcc_assert (macro_num == info.num_maps.second);

  cfg->macro_locs = MAX_LOCATION_T + 1 - offset;

  sec.end (to, to->name (MOD_SNAME_PFX ".mlm"), crc_p);
  dump.outdent ();
}

bool
module_state::read_ordinary_maps ()
{
  bytes_in sec;

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".olm"))
    return false;
  dump () && dump ("Reading ordinary location maps");
  dump.indent ();

  /* Read the filename table.  */
  unsigned len = sec.u ();
  dump () && dump ("%u source file names", len);
  vec<const char *> filenames;
  filenames.create (len);
  for (unsigned ix = 0; ix != len; ix++)
    {
      size_t l;
      const char *buf = sec.str (&l);
      char *fname = XNEWVEC (char, l + 1);
      memcpy (fname, buf, l + 1);
      dump (dumper::LOCATION) && dump ("Source file[%u]=%s", ix, fname);
      /* We leak these names into the line-map table.  But it
	 doesn't own them.  */
      filenames.quick_push (fname);
    }

  unsigned num_ordinary = sec.u (); 
  unsigned max_range = sec.u ();
  unsigned low_bits = sec.u ();
  location_t zero = sec.u ();
  location_t range_mask = (1u << max_range) - 1;

  dump () && dump ("Ordinary maps:%u, range bits:%u, preserve:%x, zero:%u",
		   num_ordinary, max_range, low_bits, zero);

  location_t offset = line_table->highest_location + 1;
  /* Ensure offset doesn't go backwards at the start.  */
  if ((offset & range_mask) > low_bits)
    offset += range_mask + 1;
  offset = (offset & ~range_mask);

  bool propagated = spans.maybe_propagate (this, offset + low_bits);

  line_map_ordinary *maps = static_cast<line_map_ordinary *>
    (line_map_new_raw (line_table, false, num_ordinary));

  location_t lwm = offset;
  slurp->loc_deltas.first = offset - zero;
  ordinary_locs.first = zero + low_bits + slurp->loc_deltas.first;
  dump () && dump ("Ordinary loc delta %d", slurp->loc_deltas.first);

  for (unsigned ix = 0; ix != num_ordinary && !sec.get_overrun (); ix++)
    {
      line_map_ordinary *map = &maps[ix];
      unsigned hwm = sec.u ();

      /* Record the current HWM so that the below read_location is
	 ok.  */
      ordinary_locs.second = hwm + slurp->loc_deltas.first;
      map->start_location = hwm + (offset - zero);
      if (map->start_location < lwm)
	sec.set_overrun ();
      lwm = map->start_location;
      dump (dumper::LOCATION) && dump ("Map:%u %u->%u", ix, hwm, lwm);
      map->reason = lc_reason (sec.u ());
      map->sysp = sec.u ();
      map->m_range_bits = sec.u ();
      map->m_column_and_range_bits = map->m_range_bits + sec.u ();

      unsigned fnum = sec.u ();
      map->to_file = (fnum < filenames.length () ? filenames[fnum] : "");
      map->to_line = sec.u ();

      /* Root the outermost map at our location.  */
      location_t from = read_location (sec);
      map->included_from = from != UNKNOWN_LOCATION ? from : loc;
    }

  location_t hwm = sec.u ();
  ordinary_locs.second = hwm + slurp->loc_deltas.first;

  /* highest_location is the one handed out, not the next one to
     hand out.  */
  line_table->highest_location = ordinary_locs.second - 1;

  if (line_table->highest_location >= LINE_MAP_MAX_LOCATION_WITH_COLS)
    /* We shouldn't run out of locations, as we checked before
       starting.  */
    sec.set_overrun ();
  dump () && dump ("Ordinary location hwm:%u", ordinary_locs.second);

  if (propagated)
    spans.close ();

  filenames.release ();
  
  dump.outdent ();
  if (!sec.end (from ()))
    return false;

  return true;
}

bool
module_state::read_macro_maps ()
{
  bytes_in sec;

  if (!sec.begin (loc, from (), MOD_SNAME_PFX ".mlm"))
    return false;
  dump () && dump ("Reading macro location maps");
  dump.indent ();

  unsigned num_macros = sec.u ();
  location_t zero = sec.u ();
  dump () && dump ("Macro maps:%u zero:%u", num_macros, zero);

  bool propagated = spans.maybe_propagate (this,
					   line_table->highest_location + 1);

  location_t offset = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  slurp->loc_deltas.second = zero - offset;
  macro_locs.second = zero - slurp->loc_deltas.second;
  dump () && dump ("Macro loc delta %d", slurp->loc_deltas.second);

  for (unsigned ix = 0; ix != num_macros && !sec.get_overrun (); ix++)
    {
      unsigned lwm = sec.u ();
      /* Record the current LWM so that the below read_location is
	 ok.  */
      macro_locs.first = lwm - slurp->loc_deltas.second;

      unsigned n_tokens = sec.u ();
      cpp_hashnode *node = sec.cpp_node ();
      location_t exp_loc = read_location (sec);

      const line_map_macro *macro
	= linemap_enter_macro (line_table, node, exp_loc, n_tokens);
      if (!macro)
	/* We shouldn't run out of locations, as we checked that we
	   had enough before starting.  */
	break;

      location_t *locs = macro->macro_locations;
      location_t tok_loc = UNKNOWN_LOCATION;
      unsigned count = sec.u ();
      unsigned runs = 0;
      for (unsigned jx = macro->n_tokens * 2; jx-- && !sec.get_overrun ();)
	{
	  while (!count-- && !sec.get_overrun ())
	    {
	      runs++;
	      tok_loc = read_location (sec);
	      count = sec.u ();
	    }
	  locs[jx] = tok_loc;
	}
      if (count)
	sec.set_overrun ();
      dump (dumper::LOCATION)
	&& dump ("Macro:%u %I %u/%u*2 locations [%u,%u)",
		 ix, identifier (node), runs, n_tokens,
		 MAP_START_LOCATION (macro),
		 MAP_START_LOCATION (macro) + n_tokens);
    }
  location_t lwm = sec.u ();
  macro_locs.first = lwm - slurp->loc_deltas.second;

  dump () && dump ("Macro location lwm:%u", macro_locs.first);

  if (propagated)
    spans.close ();

  dump.outdent ();
  if (!sec.end (from ()))
    return false;

  return true;
}

/* Serialize the definition of MACRO.  */

void
module_state::write_define (bytes_out &sec, const cpp_macro *macro, bool located)
{
  sec.u (macro->count);

  sec.b (macro->fun_like);
  sec.b (macro->variadic);
  sec.b (macro->syshdr);
  sec.bflush ();

  if (located)
    write_location (sec, macro->line);
  if (macro->fun_like)
    {
      sec.u (macro->paramc);
      const cpp_hashnode *const *parms = macro->parm.params;
      for (unsigned ix = 0; ix != macro->paramc; ix++)
	sec.cpp_node (parms[ix]);
    }

  unsigned len = 0;
  for (unsigned ix = 0; ix != macro->count; ix++)
    {
      const cpp_token *token = &macro->exp.tokens[ix];
      if (located)
	write_location (sec, token->src_loc);
      sec.u (token->type);
      sec.u (token->flags);
      switch (cpp_token_val_index (token))
	{
	default:
	  gcc_unreachable ();

	case CPP_TOKEN_FLD_ARG_NO:
	  /* An argument reference.  */
	  sec.u (token->val.macro_arg.arg_no);
	  sec.cpp_node (token->val.macro_arg.spelling);
	  break;

	case CPP_TOKEN_FLD_NODE:
	  /* An identifier.  */
	  sec.cpp_node (token->val.node.node);
	  if (token->val.node.spelling == token->val.node.node)
	    /* The spelling will usually be the same.  so optimize
	       that.  */
	    sec.str (NULL, 0);
	  else
	    sec.cpp_node (token->val.node.spelling);
	  break;

	case CPP_TOKEN_FLD_NONE:
	  break;

	case CPP_TOKEN_FLD_STR:
	  /* A string, number or comment.  Not always NUL terminated,
	     we stream out in a single contatenation with embedded
	     NULs as that's a safe default.  */
	  len += token->val.str.len + 1;
	  sec.u (token->val.str.len);
	  break;

	case CPP_TOKEN_FLD_SOURCE:
	case CPP_TOKEN_FLD_TOKEN_NO:
	case CPP_TOKEN_FLD_PRAGMA:
	  /* These do not occur inside a macro itself.  */
	  gcc_unreachable ();
	}
    }

  if (len)
    {
      char *ptr = reinterpret_cast<char *> (sec.buf (len));
      len = 0;
      for (unsigned ix = 0; ix != macro->count; ix++)
	{
	  const cpp_token *token = &macro->exp.tokens[ix];
	  if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
	    {
	      memcpy (ptr + len, token->val.str.text,
		      token->val.str.len);
	      len += token->val.str.len;
	      ptr[len++] = 0;
	    }
	}
    }
}

/* Read a macro definition.  */

cpp_macro *
module_state::read_define (bytes_in &sec, cpp_reader *reader, bool located) const
{
  unsigned count = sec.u ();
  /* We rely on knowing cpp_reader's hash table is ident_hash, and
     it's subobject allocator is stringpool_ggc_alloc and that is just
     a wrapper for ggc_alloc_atomic.  */
  cpp_macro *macro
    = (cpp_macro *)ggc_alloc_atomic (sizeof (cpp_macro)
				     + sizeof (cpp_token) * (count - !!count));
  memset (macro, 0, sizeof (cpp_macro) + sizeof (cpp_token) * (count - !!count));

  macro->count = count;
  macro->kind = cmk_macro;
  macro->imported_p = true;

  macro->fun_like = sec.b ();
  macro->variadic = sec.b ();
  macro->syshdr = sec.b ();
  sec.bflush ();

  macro->line = located ? read_location (sec) : loc;

  if (macro->fun_like)
    {
      unsigned paramc = sec.u ();
      cpp_hashnode **params
	= (cpp_hashnode **)ggc_alloc_atomic (sizeof (cpp_hashnode *) * paramc);
      macro->paramc = paramc;
      macro->parm.params = params;
      for (unsigned ix = 0; ix != paramc; ix++)
	params[ix] = sec.cpp_node ();
    }

  unsigned len = 0;
  for (unsigned ix = 0; ix != count && !sec.get_overrun (); ix++)
    {
      cpp_token *token = &macro->exp.tokens[ix];
      token->src_loc = located ? read_location (sec) : loc;
      token->type = cpp_ttype (sec.u ());
      token->flags = sec.u ();
      switch (cpp_token_val_index (token))
	{
	default:
	  sec.set_overrun ();
	  break;

	case CPP_TOKEN_FLD_ARG_NO:
	  /* An argument reference.  */
	  {
	    unsigned arg_no = sec.u ();
	    if (arg_no - 1 >= macro->paramc)
	      sec.set_overrun ();
	    token->val.macro_arg.arg_no = arg_no;
	    token->val.macro_arg.spelling = sec.cpp_node ();
	  }
	  break;

	case CPP_TOKEN_FLD_NODE:
	  /* An identifier.  */
	  token->val.node.node = sec.cpp_node ();
	  token->val.node.spelling = sec.cpp_node ();
	  if (!token->val.node.spelling)
	    token->val.node.spelling = token->val.node.node;
	  break;

	case CPP_TOKEN_FLD_NONE:
	  break;

	case CPP_TOKEN_FLD_STR:
	  /* A string, number or comment.  */
	  token->val.str.len = sec.u ();
	  len += token->val.str.len + 1;
	  break;
	}
    }

  if (len)
    if (const char *ptr = reinterpret_cast<const char *> (sec.buf (len)))
      {
	/* There should be a final NUL.  */
	if (ptr[len-1])
	  sec.set_overrun ();
	/* cpp_alloc_token_string will add a final NUL.  */
	const unsigned char *buf
	  = cpp_alloc_token_string (reader, (const unsigned char *)ptr, len - 1);
	len = 0;
	for (unsigned ix = 0; ix != count && !sec.get_overrun (); ix++)
	  {
	    cpp_token *token = &macro->exp.tokens[ix];
	    if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
	      {
		token->val.str.text = buf + len;
		len += token->val.str.len;
		if (buf[len++])
		  sec.set_overrun ();
	      }
	  }
      }

  if (sec.get_overrun ())
    return NULL;
  return macro;
}

/* Exported macro data.  */
struct GTY(()) macro_export {
  cpp_macro *def;
  location_t undef_loc;

  macro_export ()
    :def (NULL), undef_loc (UNKNOWN_LOCATION)
  {
  }
};

/* Imported macro data.  */
class macro_import {
public:
  struct slot {
#if defined (WORDS_BIGENDIAN) && SIZEOF_VOID_P == 8
    int offset;
#endif
    /* We need to ensure we don't use the LSB for representation, as
       that's the union discriminator below.  */
    unsigned bits;

#if !(defined (WORDS_BIGENDIAN) && SIZEOF_VOID_P == 8)
    int offset;
#endif

  public:
    enum Layout {
      L_DEF = 1,
      L_UNDEF = 2,
      L_BOTH = 3,
      L_MODULE_SHIFT = 2
    };

  public:
    /* Not a regular ctor, because we put it in a union, and that's
       not allowed in C++ 98.  */
    static slot ctor (unsigned module, unsigned defness)
    {
      gcc_checking_assert (defness);
      slot s;
      s.bits = defness | (module << L_MODULE_SHIFT);
      s.offset = -1;
      return s;
    }

  public:
    unsigned get_defness () const
    {
      return bits & L_BOTH;
    }
    unsigned get_module () const
    {
      return bits >> L_MODULE_SHIFT;
    }
    void become_undef ()
    {
      bits &= ~unsigned (L_DEF);
      bits |= unsigned (L_UNDEF);
    }
  };

private:
  typedef vec<slot, va_heap, vl_embed> ary_t;
  union either {
    /* Discriminated by bits 0|1 != 0.  The expected case is that
       there will be exactly one slot per macro, hence the effort of
       packing that.  */
    ary_t *ary;
    slot single;
  } u;

public:
  macro_import ()
  {
    u.ary = NULL;
  }

private:
  bool single_p () const
  {
    return u.single.bits & slot::L_BOTH;
  }
  bool occupied_p () const
  {
    return u.ary != NULL;
  }

public:
  unsigned length () const
  {
    gcc_checking_assert (occupied_p ());
    return single_p () ? 1 : u.ary->length ();
  }
  slot &operator[] (unsigned ix)
  {
    gcc_checking_assert (occupied_p ());
    if (single_p ())
      {
	gcc_checking_assert (!ix);
	return u.single;
      }
    else
      return (*u.ary)[ix];
  }

public:
  slot &exported ();
  slot &append (unsigned module, unsigned defness);
};

/* O is a new import to append to the list for.  If we're an empty
   set, initialize us.  */

macro_import::slot &
macro_import::append (unsigned module, unsigned defness)
{
  if (!occupied_p ())
    {
      u.single = slot::ctor (module, defness);
      return u.single;
    }
  else
    {
      bool single = single_p ();
      ary_t *m = single ? NULL : u.ary;
      vec_safe_reserve (m, 1 + single);
      if (single)
	m->quick_push (u.single);
      u.ary = m;
      return *u.ary->quick_push (slot::ctor (module, defness));
    }
}

/* We're going to export something.  Make sure the first import slot
   is us.  */

macro_import::slot &
macro_import::exported ()
{
  if (occupied_p () && !(*this)[0].get_module ())
    {
      slot &res = (*this)[0];
      res.bits |= slot::L_DEF;
      return res;
    }

  slot *a = &append (0, slot::L_DEF);
  if (!single_p ())
    {
      slot &f = (*this)[0];
      std::swap (f, *a);
      a = &f;
    }
  return *a;
}

/* The import (&exported) macros.  cpp_hasnode's deferred field
   indexes this array (offset by 1, so zero means 'not present'.  */

static vec<macro_import, va_heap, vl_embed> *macro_imports;

/* The exported macros.  A macro_import slot's zeroth element's offset
   indexes this array.  If the zeroth slot is not for module zero,
   there is no export.  */

static GTY(()) vec<macro_export, va_gc> *macro_exports;

/* The reachable set of header imports from this TU.  */

static GTY(()) bitmap headers;

/* Get the (possibly empty) macro imports for NODE.  */

static macro_import &
get_macro_imports (cpp_hashnode *node)
{
  if (node->deferred)
    return (*macro_imports)[node->deferred - 1];

  vec_safe_reserve (macro_imports, 1);
  node->deferred = macro_imports->length () + 1;
  return *vec_safe_push (macro_imports, macro_import ());
}

/* Get the macro export for export EXP of NODE.  */

static macro_export &
get_macro_export (macro_import::slot &slot)
{
  if (slot.offset >= 0)
    return (*macro_exports)[slot.offset];

  vec_safe_reserve (macro_exports, 1);
  slot.offset = macro_exports->length ();
  return *macro_exports->quick_push (macro_export ());
}

/* If NODE is an exportable macro, add it to the export set.  */

static int
maybe_add_macro (cpp_reader *, cpp_hashnode *node, void *data_)
{
  bool exporting = false;

  if (cpp_user_macro_p (node))
    if (cpp_macro *macro = node->value.macro)
      /* Ignore imported, builtins, command line and forced header macros.  */
      if (!macro->imported_p
	  && !macro->lazy && macro->line >= spans.main_start ())
	{
	  gcc_checking_assert (macro->kind == cmk_macro);
	  /* I don't want to deal with this corner case, that I suspect is
	     a devil's advocate reading of the standard.  */
	  gcc_checking_assert (!macro->extra_tokens);

	  macro_import::slot &slot = get_macro_imports (node).exported ();
	  macro_export &exp = get_macro_export (slot);
	  exp.def = macro;
	  exporting = true;
	}

  if (!exporting && node->deferred)
    {
      macro_import &imports = (*macro_imports)[node->deferred - 1];
      macro_import::slot &slot = imports[0];
      if (!slot.get_module ())
	{
	  gcc_checking_assert (slot.get_defness ());
	  exporting = true;
	}
    }

  if (exporting)
    static_cast<vec<cpp_hashnode *> *> (data_)->safe_push (node);

  return 1; /* Don't stop.  */
}

/* Order cpp_hashnodes A_ and B_ by their exported macro locations.  */

static int
macro_loc_cmp (const void *a_, const void *b_)
{
  const cpp_hashnode *node_a = *(const cpp_hashnode *const *)a_;
  macro_import &import_a = (*macro_imports)[node_a->deferred - 1];
  const macro_export &export_a = (*macro_exports)[import_a[0].offset];
  location_t loc_a = export_a.def ? export_a.def->line : export_a.undef_loc;

  const cpp_hashnode *node_b = *(const cpp_hashnode *const *)b_;
  macro_import &import_b = (*macro_imports)[node_b->deferred - 1];
  const macro_export &export_b = (*macro_exports)[import_b[0].offset];
  location_t loc_b = export_b.def ? export_b.def->line : export_b.undef_loc;

  if (loc_a < loc_b)
    return +1;
  else if (loc_a > loc_b)
    return -1;
  else
    return 0;
}

/* Write out the exported defines.  This is two sections, one
   containing the definitions, the other a table of node names.  */

unsigned
module_state::write_macros (elf_out *to, cpp_reader *reader, unsigned *crc_p)
{
  dump () && dump ("Writing macros");
  dump.indent ();

  vec<cpp_hashnode *> macros;
  macros.create (100);
  cpp_forall_identifiers (reader, maybe_add_macro, &macros);

  dump (dumper::MACRO) && dump ("No more than %u macros", macros.length ());

  macros.qsort (macro_loc_cmp);

  /* Write the defs */
  bytes_out sec (to);
  sec.begin ();

  unsigned count = 0;
  for (unsigned ix = macros.length (); ix--;)
    {
      cpp_hashnode *node = macros[ix];
      macro_import::slot &slot = (*macro_imports)[node->deferred - 1][0];
      gcc_assert (!slot.get_module () && slot.get_defness ());

      macro_export &mac = (*macro_exports)[slot.offset];
      gcc_assert (!!(slot.get_defness () & macro_import::slot::L_UNDEF)
		  == (mac.undef_loc != UNKNOWN_LOCATION)
		  && !!(slot.get_defness () & macro_import::slot::L_DEF)
		  == (mac.def != NULL));

      if (IDENTIFIER_KEYWORD_P (identifier (node)))
	{
	  warning_at (mac.def->line, 0,
		      "not exporting %<#define %E%> as it is a keyword",
		      identifier (node));
	  slot.offset = 0;
	  continue;
	}

      count++;
      slot.offset = sec.pos;
      dump (dumper::MACRO)
	&& dump ("Writing macro %s%s%s %I at %u",
		 slot.get_defness () & macro_import::slot::L_UNDEF
		 ? "#undef" : "",
		 slot.get_defness () == macro_import::slot::L_BOTH
		 ? " & " : "",
		 slot.get_defness () & macro_import::slot::L_DEF
		 ? "#define" : "",
		 identifier (node), slot.offset);
      if (mac.undef_loc != UNKNOWN_LOCATION)
	write_location (sec, mac.undef_loc);
      if (mac.def)
	write_define (sec, mac.def);
    }
  sec.end (to, to->name (MOD_SNAME_PFX ".def"), crc_p);

  if (count)
    {
      /* Write the table.  */
      bytes_out sec (to);
      sec.begin ();
      sec.u (count);

      for (unsigned ix = macros.length (); ix--;)
	{
	  const cpp_hashnode *node = macros[ix];
	  macro_import::slot &slot = (*macro_imports)[node->deferred - 1][0];

	  if (slot.offset)
	    {
	      sec.cpp_node (node);
	      sec.u (slot.get_defness ());
	      sec.u (slot.offset);
	    }
	}
      sec.end (to, to->name (MOD_SNAME_PFX ".mac"), crc_p);
    }

  macros.release ();
  dump.outdent ();
  return count;
}

bool
module_state::read_macros ()
{
  /* Get the def section.  */
  if (!slurp->macro_defs.begin (loc, from (), MOD_SNAME_PFX ".def"))
    return false;

  /* Get the tbl section, if there are defs. */
  if (slurp->macro_defs.more_p ()
      && !slurp->macro_tbl.begin (loc, from (), MOD_SNAME_PFX ".mac"))
    return false;

  return true;
}

/* Install the macro name table.  */

void
module_state::install_macros ()
{
  bytes_in &sec = slurp->macro_tbl;
  if (!sec.size)
    return;

  dump () && dump ("Reading macro table %M", this);
  dump.indent ();

  unsigned count = sec.u ();
  dump () && dump ("%u macros", count);
  while (count--)
    {
      cpp_hashnode *node = sec.cpp_node ();
      macro_import &imp = get_macro_imports (node);
      unsigned flags = sec.u () & macro_import::slot::L_BOTH;
      if (!flags)
	sec.set_overrun ();

      if (sec.get_overrun ())
	break;

      macro_import::slot &slot = imp.append (mod, flags);
      slot.offset = sec.u ();

      dump (dumper::MACRO)
	&& dump ("Read %s macro %s%s%s %I at %u",
		 imp.length () > 1 ? "add" : "new",
		 flags & macro_import::slot::L_UNDEF ? "#undef" : "",
		 flags == macro_import::slot::L_BOTH ? " & " : "",
		 flags & macro_import::slot::L_DEF ? "#define" : "",
		 identifier (node), slot.offset);

      /* We'll leak an imported definition's TOKEN_FLD_STR's data
	 here.  But that only happens when we've had to resolve the
	 deferred macro before this import -- why are you doing
	 that?  */
      if (cpp_macro *cur = cpp_set_deferred_macro (node))
	if (!cur->imported_p)
	  {
	    macro_import::slot &slot = imp.exported ();
	    macro_export &exp = get_macro_export (slot);
	    exp.def = cur;
	    dump (dumper::MACRO)
	      && dump ("Saving current #define %I", identifier (node));
	  }
    }

  /* We're now done with the table.  */
  elf_in::release (slurp->from, sec);

  dump.outdent ();
}

/* Import the transitive macros.  */

void
module_state::import_macros ()
{
  bitmap_ior_into (headers, slurp->headers);

  bitmap_iterator bititer;
  unsigned bitnum;
  EXECUTE_IF_SET_IN_BITMAP (slurp->headers, 0, bitnum, bititer)
    (*modules)[bitnum]->install_macros ();
}

/* NODE is being undefined at LOC.  Record it in the export table, if
   necessary.  */

void
module_state::undef_macro (cpp_reader *, location_t loc, cpp_hashnode *node)
{
  if (!node->deferred)
    /* The macro is not imported, so our undef is irrelevant.  */
    return;

  unsigned n = dump.push (NULL);

  macro_import::slot &slot = (*macro_imports)[node->deferred - 1].exported ();
  macro_export &exp = get_macro_export (slot);

  exp.undef_loc = loc;
  slot.become_undef ();
  exp.def = NULL;

  dump (dumper::MACRO) && dump ("Recording macro #undef %I", identifier (node));

  dump.pop (n);
}

/* NODE is a deferred macro node.  Determine the definition and return
   it, with NULL if undefined.  May issue diagnostics.

   This can leak memory, when merging declarations -- the string
   contents (TOKEN_FLD_STR) of each definition are allocated in
   unreclaimable cpp objstack.  Only one will win.  However, I do not
   expect this to be common -- mostly macros have a single point of
   definition.  Perhaps we could restore the objstack to its position
   after the first imported definition (if that wins)?  The macros
   themselves are GC'd.  */

cpp_macro *
module_state::deferred_macro (cpp_reader *reader, location_t loc,
			      cpp_hashnode *node)
{
  macro_import &imports = (*macro_imports)[node->deferred - 1];

  unsigned n = dump.push (NULL);
  dump (dumper::MACRO) && dump ("Deferred macro %I", identifier (node));

  bitmap visible (BITMAP_GGC_ALLOC ());

  if (!((imports[0].get_defness () & macro_import::slot::L_UNDEF)
	&& !imports[0].get_module ()))
    {
      /* Calculate the set of visible header imports.  */
      bitmap_copy (visible, headers);
      for (unsigned ix = imports.length (); ix--;)
	{
	  const macro_import::slot &slot = imports[ix];
	  unsigned mod = slot.get_module ();
	  if ((slot.get_defness () & macro_import::slot::L_UNDEF)
	      && bitmap_bit_p (visible, mod))
	    {
	      bitmap arg = mod ? (*modules)[mod]->slurp->headers : headers;
	      bitmap_and_compl_into (visible, arg);
	      bitmap_set_bit (visible, mod);
	    }
	}
    }
  bitmap_set_bit (visible, 0);

  /* Now find the macros that are still visible.  */
  bool failed = false;
  cpp_macro *def = NULL;
  vec<macro_export> defs;
  defs.create (imports.length ());
  for (unsigned ix = imports.length (); ix--;)
    {
      const macro_import::slot &slot = imports[ix];
      unsigned mod = slot.get_module ();
      if (bitmap_bit_p (visible, mod))
	{
	  macro_export *pushed = NULL;
	  if (mod)
	    {
	      const module_state *imp = (*modules)[mod];
	      bytes_in &sec = imp->slurp->macro_defs;
	      if (!sec.get_overrun ())
		{
		  dump (dumper::MACRO)
		    && dump ("Reading macro %s%s%s %I module %M at %u",
			     slot.get_defness () & macro_import::slot::L_UNDEF
			     ? "#undef" : "",
			     slot.get_defness () == macro_import::slot::L_BOTH
			     ? " & " : "",
			     slot.get_defness () & macro_import::slot::L_DEF
			     ? "#define" : "",
			     identifier (node), imp, slot.offset);
		  sec.random_access (slot.offset);

		  macro_export exp;
		  if (slot.get_defness () & macro_import::slot::L_UNDEF)
		    exp.undef_loc = imp->read_location (sec);
		  if (slot.get_defness () & macro_import::slot::L_DEF)
		    exp.def = imp->read_define (sec, reader);
		  if (sec.get_overrun ())
		    error_at (loc, "macro definitions of %qE corrupted",
			      imp->name);
		  else
		    pushed = defs.quick_push (exp);
		}
	    }
	  else
	    pushed = defs.quick_push ((*macro_exports)[slot.offset]);
	  if (pushed && pushed->def)
	    {
	      if (!def)
		def = pushed->def;
	      else if (cpp_compare_macros (def, pushed->def))
		failed = true;
	    }
	}
    }

  if (failed)
    {
      /* If LOC is the first loc, this is the end of file check, which
	 is a warning.  */
      if (loc == MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0)))
	warning_at (loc, OPT_Winvalid_imported_macros,
		    "inconsistent imported macro definition %qE",
		    identifier (node));
      else
	error_at (loc, "inconsistent imported macro definition %qE",
		  identifier (node));
      for (unsigned ix = defs.length (); ix--;)
	{
	  macro_export &exp = defs[ix];
	  if (exp.undef_loc)
	    inform (exp.undef_loc, "%<#undef %E%>", identifier (node));
	  if (exp.def)
	    inform (exp.def->line, "%<#define %s%>",
		    cpp_macro_definition (reader, node, exp.def));
	}
      def = NULL;
    }

  defs.release ();

  dump.pop (n);

  return def;
}

/* Stream the static aggregates.  Sadly some headers (ahem:
   iostream) contain static vars, and rely on them to run global
   ctors.  */
unsigned
module_state::write_inits (elf_out *to, depset::hash &table, unsigned *crc_ptr)
{
  if (!static_aggregates && !tls_aggregates)
    return 0;

  dump () && dump ("Writing initializers");
  dump.indent ();

  static_aggregates = nreverse (static_aggregates);
  tls_aggregates = nreverse (tls_aggregates);

  unsigned count = 0;
  trees_out sec (to, this, table, ~0u);
  sec.begin ();

  tree list = static_aggregates;
  for (int passes = 0; passes != 2; passes++)
    {
      for (tree init = list; init; init = TREE_CHAIN (init), count++)
	if (TREE_LANG_FLAG_0 (init))
	  {
	    tree decl = TREE_VALUE (init);

	    dump ("Initializer:%u for %N", count, decl);
	    sec.tree_node (decl);
	  }

      list = tls_aggregates;
    }
  
  sec.end (to, to->name (MOD_SNAME_PFX ".ini"), crc_ptr);
  dump.outdent ();

  return count;
}

/* We have to defer some post-load processing until we've completed
   reading, because they can cause more reading.  */

static void
post_load_processing ()
{
  /* We mustn't cause a GC, our caller should have arranged for that
     not to happen.  */
  gcc_checking_assert (function_depth);

  if (!post_load_decls)
    return;

  tree old_cfd = current_function_decl;
  struct function *old_cfun = cfun;
  while (post_load_decls->length ())
    {
      tree decl = post_load_decls->pop ();

      dump () && dump ("Post-load processing of %N", decl);

      gcc_checking_assert (DECL_ABSTRACT_P (decl));
      /* Cloning can cause loading -- specifically operator delete for
	 the deleting dtor.  */
      maybe_clone_body (decl);
    }

  cfun = old_cfun;
  current_function_decl = old_cfd;
}

bool
module_state::read_inits (unsigned count)
{
  trees_in sec (this);
  if (!sec.begin (loc, from (), from ()->find (MOD_SNAME_PFX ".ini")))
    return false;
  dump () && dump ("Reading %u initializers", count);
  dump.indent ();

  lazy_snum = ~0u;
  for (unsigned ix = 0; ix != count; ix++)
    {
      /* Merely referencing the decl causes its initializer to be read
	 and added to the correct list.  */
      tree decl = sec.tree_node ();

      if (sec.get_overrun ())
	break;
      if (decl)
	dump ("Initializer:%u for %N", count, decl);
    }
  lazy_snum = 0;
  post_load_processing ();
  dump.outdent ();
  if (!sec.end (from ()))
    return false;  
  return true;
}

void
module_state::write_counts (elf_out *to, unsigned counts[MSC_HWM],
			    unsigned *crc_ptr)
{
  bytes_out cfg (to);

  cfg.begin ();

  for (unsigned ix = MSC_HWM; ix--;)
    cfg.u (counts[ix]);

  if (dump ())
    {
      dump ("Cluster sections are [%u,%u)",
	    counts[MSC_sec_lwm], counts[MSC_sec_hwm]);
      dump ("Bindings %u", counts[MSC_bindings]);
      dump ("Pendings %u", counts[MSC_pendings]);
      dump ("Entities %u", counts[MSC_entities]);
      dump ("Namespaces %u", counts[MSC_namespaces]);
      dump ("Macros %u", counts[MSC_macros]);
      dump ("Initializers %u", counts[MSC_inits]);
    }

  cfg.end (to, to->name (MOD_SNAME_PFX ".cnt"), crc_ptr);
}

bool
module_state::read_counts (unsigned counts[MSC_HWM])
{
  bytes_in cfg;

  if (!cfg.begin (loc, from (), MOD_SNAME_PFX ".cnt"))
    return false;

  for (unsigned ix = MSC_HWM; ix--;)
    counts[ix] = cfg.u ();

  if (dump ())
    {
      dump ("Declaration sections are [%u,%u)",
	    counts[MSC_sec_lwm], counts[MSC_sec_hwm]);
      dump ("Bindings %u", counts[MSC_bindings]);
      dump ("Pendings %u", counts[MSC_pendings]);
      dump ("Entities %u", counts[MSC_entities]);
      dump ("Namespaces %u", counts[MSC_namespaces]);
      dump ("Macros %u", counts[MSC_macros]);
      dump ("Initializers %u", counts[MSC_inits]);
    }

  return cfg.end (from ());
}

/* Tool configuration:  MOD_SNAME_PFX .config

   This is data that confirms current state (or fails).  */

void
module_state::write_config (elf_out *to, module_state_config &config,
			    unsigned inner_crc)
{
  bytes_out cfg (to);

  cfg.begin ();

  /* Write version and inner crc as u32 values, for easier
     debug inspection.  */
  dump () && dump ("Writing version=%V, inner_crc=%x",
		   MODULE_VERSION, inner_crc);
  cfg.u32 (unsigned (MODULE_VERSION));
  cfg.u32 (inner_crc);

  cfg.u (to->name (is_header () ? "" : get_flatname ()));

  /* Configuration. */
  dump () && dump ("Writing target='%s', host='%s'",
		   TARGET_MACHINE, HOST_MACHINE);
  unsigned target = to->name (TARGET_MACHINE);
  unsigned host = (!strcmp (TARGET_MACHINE, HOST_MACHINE)
		   ? target : to->name (HOST_MACHINE));
  cfg.u (target);
  cfg.u (host);

  cfg.str (config.dialect_str);
  cfg.u (extensions);

  /* Global tree information.  We write the globals crc separately,
     rather than mix it directly into the overall crc, as it is used
     to ensure data match between instances of the compiler, not
     integrity of the file.  */
  dump () && dump ("Writing globals=%u, crc=%x",
		   fixed_trees->length (), global_crc);
  cfg.u (fixed_trees->length ());
  cfg.u32 (global_crc);

  if (is_partition ())
    cfg.u (is_interface ());

  cfg.u (config.num_imports);
  cfg.u (config.num_partitions);
  cfg.u (config.num_entities);

  cfg.u (config.ordinary_locs);
  cfg.u (config.macro_locs);
  cfg.u (config.ordinary_loc_align);  

  /* Now generate CRC, we'll have incorporated the inner CRC because
     of its serialization above.  */
  cfg.end (to, to->name (MOD_SNAME_PFX ".cfg"), &crc);
  dump () && dump ("Writing CRC=%x", crc);
}

void
module_state::note_cmi_name ()
{
  if (!cmi_noted_p && filename)
    {
      cmi_noted_p = true;
      inform (loc, "compiled module file is %qs",
	      maybe_add_cmi_prefix (filename));
    }
}

bool
module_state::read_config (module_state_config &config)
{
  bytes_in cfg;

  if (!cfg.begin (loc, from (), MOD_SNAME_PFX ".cfg"))
    return false;

  /* Check version.  */
  unsigned my_ver = MODULE_VERSION;
  unsigned their_ver = cfg.u32 ();
  dump () && dump  (my_ver == their_ver ? "Version %V"
		    : "Expecting %V found %V", my_ver, their_ver);
  if (their_ver != my_ver)
    {
      /* The compiler versions differ.  Close enough? */
      verstr_t my_string, their_string;

      version2string (my_ver, my_string);
      version2string (their_ver, their_string);

      /* Reject when either is non-experimental or when experimental
	 major versions differ.  */
      bool reject_p = ((!IS_EXPERIMENTAL (my_ver)
			|| !IS_EXPERIMENTAL (their_ver)
			|| MODULE_MAJOR (my_ver) != MODULE_MAJOR (their_ver))
		       /* The 'I know what I'm doing' switch.  */
		       && !flag_module_version_ignore);
      bool inform_p = true;
      if (reject_p)
	{
	  cfg.set_overrun ();
	  error_at (loc, "compiled module is %sversion %s",
		    IS_EXPERIMENTAL (their_ver) ? "experimental " : "",
		    their_string);
	}
      else
	inform_p = warning_at (loc, 0, "compiled module is %sversion %s",
			     IS_EXPERIMENTAL (their_ver) ? "experimental " : "",
			     their_string);

      if (inform_p)
	{
	  inform (loc, "compiler is %sversion %s%s%s",
		  IS_EXPERIMENTAL (my_ver) ? "experimental " : "",
		  my_string,
		  reject_p ? "" : flag_module_version_ignore
		  ? ", be it on your own head!" : ", close enough?",
		  reject_p ? "" : " \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf");
	  note_cmi_name ();
	}

      if (reject_p)
	goto done;
    }

  /*  We wrote the inner crc merely to merge it, so simply read it
      back and forget it.  */
  cfg.u32 ();

  /* Check module name.  */
  {
    const char *their_name = from ()->name (cfg.u ());
    const char *our_name = "";

    if (!is_header ())
      our_name = get_flatname ();

    /* Header units can be aliased, so name checking is
       inappropriate.  */
    if (0 != strcmp (their_name, our_name))
      {
	error_at (loc,
		  their_name[0] && our_name[0] ? G_("module %qs found")
		  : their_name[0]
		  ? G_("header module expected, module %qs found")
		  : G_("module %qs expected, header module found"),
		  their_name[0] ? their_name : our_name);
	cfg.set_overrun ();
	goto done;
      }
  }

  /* Check the CRC after the above sanity checks, so that the user is
     clued in.  */
  {
    unsigned e_crc = crc;
    crc = cfg.get_crc ();
    dump () && dump ("Reading CRC=%x", crc);
    if (!is_direct () && crc != e_crc)
      {
	error_at (loc, "module %qs CRC mismatch", get_flatname ());
	cfg.set_overrun ();
	goto done;
      }
  }

  /* Check target & host.  */
  {
    const char *their_target = from ()->name (cfg.u ());
    const char *their_host = from ()->name (cfg.u ());
    dump () && dump ("Read target='%s', host='%s'", their_target, their_host);
    if (strcmp (their_target, TARGET_MACHINE)
	|| strcmp (their_host, HOST_MACHINE))
      {
	error_at (loc, "target & host is %qs:%qs, expected %qs:%qs",
		  their_target, TARGET_MACHINE, their_host, HOST_MACHINE);
	cfg.set_overrun ();
	goto done;
      }
  }

  /* Check compilation dialect.  This must match.  */
  {
    const char *their_dialect = cfg.str ();
    if (strcmp (their_dialect, config.dialect_str))
      {
	error_at (loc, "language dialect differs %qs, expected %qs",
		  their_dialect, config.dialect_str);
	cfg.set_overrun ();
	goto done;
      }
  }

  /* Check for extensions.  If they set any, we must have them set
     too.  */
  {
    unsigned ext = cfg.u ();
    unsigned allowed = (flag_openmp ? SE_OPENMP : 0);

    if (unsigned bad = ext & ~allowed)
      {
	if (bad & SE_OPENMP)
	  error_at (loc, "module contains OpenMP, use %<-fopenmp%> to enable");
	cfg.set_overrun ();
	goto done;
      }
    extensions = ext;
  }

  /* Check global trees.  */
  {
    unsigned their_fixed_length = cfg.u ();
    unsigned their_fixed_crc = cfg.u32 ();
    dump () && dump ("Read globals=%u, crc=%x",
		     their_fixed_length, their_fixed_crc);
    if (!flag_preprocess_only
	&& (their_fixed_length != fixed_trees->length ()
	    || their_fixed_crc != global_crc))
      {
	error_at (loc, "fixed tree mismatch");
	cfg.set_overrun ();
	goto done;
      }
  }

  /* All non-partitions are interfaces.  */
  interface_p = !is_partition () || cfg.u ();

  config.num_imports = cfg.u ();
  config.num_partitions = cfg.u ();
  config.num_entities = cfg.u ();

  config.ordinary_locs = cfg.u ();
  config.macro_locs = cfg.u ();
  config.ordinary_loc_align = cfg.u ();

 done:
  return cfg.end (from ());
}

/* Comparator for ordering the Ordered Ordinary Location array.  */

static int
ool_cmp (const void *a_, const void *b_)
{
  auto *a = *static_cast<const module_state *const *> (a_);
  auto *b = *static_cast<const module_state *const *> (b_);
  if (a == b)
    return 0;
  else if (a->ordinary_locs.first < b->ordinary_locs.second)
    return -1;
  else
    return +1;
}

/* Use ELROND format to record the following sections:
     qualified-names	    : binding value(s)
     MOD_SNAME_PFX.README   : human readable, strings
     MOD_SNAME_PFX.ENV      : environment strings, strings
     MOD_SNAME_PFX.nms 	    : namespace hierarchy
     MOD_SNAME_PFX.bnd      : binding table
     MOD_SNAME_PFX.spc      : specialization table
     MOD_SNAME_PFX.imp      : import table
     MOD_SNAME_PFX.ent      : entity table
     MOD_SNAME_PFX.prt      : partitions table
     MOD_SNAME_PFX.olm      : ordinary line maps
     MOD_SNAME_PFX.mlm      : macro line maps
     MOD_SNAME_PFX.def      : macro definitions
     MOD_SNAME_PFX.mac      : macro index
     MOD_SNAME_PFX.ini      : inits
     MOD_SNAME_PFX.cnt      : counts
     MOD_SNAME_PFX.cfg      : config data
*/

void
module_state::write (elf_out *to, cpp_reader *reader)
{
  /* Figure out remapped module numbers, which might elide
     partitions.  */
  bitmap partitions = NULL;
  if (!is_header () && !is_partition ())
    partitions = BITMAP_GGC_ALLOC ();

  unsigned mod_hwm = 1;
  for (unsigned ix = 1; ix != modules->length (); ix++)
    {
      module_state *imp = (*modules)[ix];

      /* Promote any non-partition direct import from a partition, unless
	 we're a partition.  */
      if (!is_partition () && !imp->is_partition ()
	  && imp->is_partition_direct ())
	imp->directness = MD_PURVIEW_DIRECT;

      /* Write any import that is not a partition, unless we're a
	 partition.  */
      if (!partitions || !imp->is_partition ())
	imp->remap = mod_hwm++;
      else
	{
	  dump () && dump ("Partition %M %u", imp, ix);
	  bitmap_set_bit (partitions, ix);
	  imp->remap = 0;
	  /* All interface partitions must be exported.  */
	  if (imp->is_interface () && !bitmap_bit_p (exports, imp->mod))
	    {
	      error_at (imp->loc, "interface partition is not exported");
	      bitmap_set_bit (exports, imp->mod);
	    }

	  /* All the partition entities should have been loaded when
	     loading the partition.  */
	  if (CHECKING_P)
	    for (unsigned jx = 0; jx != imp->entity_num; jx++)
	      {
		binding_slot *slot = &(*entity_ary)[imp->entity_lwm + jx];
		gcc_checking_assert (!slot->is_lazy ());
	      }
	}
    }

  if (partitions && bitmap_empty_p (partitions))
    /* No partitions present.  */
    partitions = nullptr;

  /* Find the set of decls we must write out.  */
  depset::hash table (DECL_NAMESPACE_BINDINGS (global_namespace)->size () * 8);
  /* Add the specializations before the writables, so that we can
     detect injected friend specializations.  */
  table.add_specializations (true);
  table.add_specializations (false);
  if (partial_specializations)
    {
      table.add_partial_entities (partial_specializations);
      partial_specializations = NULL;
    }
  table.add_namespace_entities (global_namespace, partitions);
  if (class_members)
    {
      table.add_class_entities (class_members);
      class_members = NULL;
    }

  /* Now join everything up.  */
  table.find_dependencies (this);

  if (!table.finalize_dependencies ())
    {
      to->set_error ();
      return;
    }

#if CHECKING_P
  /* We're done verifying at-most once reading, reset to verify
     at-most once writing.  */
  note_defs = note_defs_table_t::create_ggc (1000);
#endif

  /* Determine Strongy Connected Components.  */
  vec<depset *> sccs = table.connect ();

  vec_alloc (ool, modules->length ());
  for (unsigned ix = modules->length (); --ix;)
    {
      auto *import = (*modules)[ix];
      if (import->loadedness > ML_NONE
	  && !(partitions && bitmap_bit_p (partitions, import->mod)))
	ool->quick_push (import);
    }
  ool->qsort (ool_cmp);

  unsigned crc = 0;
  module_state_config config;
  location_map_info map_info = write_prepare_maps (&config);
  unsigned counts[MSC_HWM];

  config.num_imports = mod_hwm;
  config.num_partitions = modules->length () - mod_hwm;
  memset (counts, 0, sizeof (counts));

  /* depset::cluster is the cluster number,
     depset::section is unspecified scratch value.

     The following loops make use of the tarjan property that
     dependencies will be earlier in the SCCS array.  */

  /* This first loop determines the number of depsets in each SCC, and
     also the number of namespaces we're dealing with.  During the
     loop, the meaning of a couple of depset fields now change:

     depset::cluster -> size_of cluster, if first of cluster & !namespace
     depset::section -> section number of cluster (if !namespace). */

  unsigned n_spaces = 0;
  counts[MSC_sec_lwm] = counts[MSC_sec_hwm] = to->get_section_limit ();
  for (unsigned size, ix = 0; ix < sccs.length (); ix += size)
    {
      depset **base = &sccs[ix];

      if (base[0]->get_entity_kind () == depset::EK_NAMESPACE)
	{
	  n_spaces++;
	  size = 1;
	}
      else
	{
	  /* Count the members in this cluster.  */
	  for (size = 1; ix + size < sccs.length (); size++)
	    if (base[size]->cluster != base[0]->cluster)
	      break;

	  for (unsigned jx = 0; jx != size; jx++)
	    {
	      /* Set the section number.  */
	      base[jx]->cluster = ~(~0u >> 1); /* A bad value.  */
	      base[jx]->section = counts[MSC_sec_hwm];
	    }

	  /* Save the size in the first member's cluster slot.  */
	  base[0]->cluster = size;

	  counts[MSC_sec_hwm]++;
	}
    }

  /* Write the clusters.  Namespace decls are put in the spaces array.
     The meaning of depset::cluster changes to provide the
     unnamed-decl count of the depset's decl (and remains zero for
     non-decls and non-unnamed).  */
  unsigned bytes = 0;
  vec<depset *> spaces;
  spaces.create (n_spaces);

  for (unsigned size, ix = 0; ix < sccs.length (); ix += size)
    {
      depset **base = &sccs[ix];

      if (base[0]->get_entity_kind () == depset::EK_NAMESPACE)
	{
	  tree decl = base[0]->get_entity ();
	  if (decl == global_namespace)
	    base[0]->cluster = 0;
	  else if (!base[0]->is_import ())
	    {
	      base[0]->cluster = counts[MSC_entities]++;
	      spaces.quick_push (base[0]);
	      counts[MSC_namespaces]++;
	      if (CHECKING_P)
		{
		  /* Add it to the entity map, such that we can tell it is
		     part of us.  */
		  bool existed;
		  unsigned *slot = &entity_map->get_or_insert
		    (DECL_UID (decl), &existed);
		  if (existed)
		    /* It must have come from a partition.  */
		    gcc_checking_assert
		      (import_entity_module (*slot)->is_partition ());
		  *slot = ~base[0]->cluster;
		}
	      dump (dumper::CLUSTER) && dump ("Cluster namespace %N", decl);
	    }
	  size = 1;
	}
      else
	{
	  size = base[0]->cluster;

	  /* Cluster is now used to number entities.  */
	  base[0]->cluster = ~(~0u >> 1); /* A bad value.  */

	  sort_cluster (&table, base, size);

	  /* Record the section for consistency checking during stream
	     out -- we don't want to start writing decls in different
	     sections.  */
	  table.section = base[0]->section;
	  bytes += write_cluster (to, base, size, table, counts, &crc);
	  table.section = 0;
	}
    }

  /* depset::cluster - entity number (on entities)
     depset::section - cluster number  */
  /* We'd better have written as many sections and found as many
     namespaces as we predicted.  */
  gcc_assert (counts[MSC_sec_hwm] == to->get_section_limit ()
	      && spaces.length () == counts[MSC_namespaces]);

  /* Write the entitites.  None happens if we contain namespaces or
     nothing. */
  config.num_entities = counts[MSC_entities];
  if (counts[MSC_entities])
    write_entities (to, sccs, counts[MSC_entities], &crc);

  /* Write the namespaces.  */
  if (counts[MSC_namespaces])
    write_namespaces (to, spaces, counts[MSC_namespaces], &crc);

  /* Write the bindings themselves.  */
  counts[MSC_bindings] = write_bindings (to, sccs, &crc);

  /* Write the unnamed.  */
  counts[MSC_pendings] = write_pendings (to, sccs, table, &crc);

  /* Write the import table.  */
  if (config.num_imports > 1)
    write_imports (to, &crc);

  /* Write elided partition table.  */
  if (config.num_partitions)
    write_partitions (to, config.num_partitions, &crc);

  /* Write the line maps.  */
  write_ordinary_maps (to, map_info, &config, config.num_partitions, &crc);
  write_macro_maps (to, map_info, &config, &crc);

  if (is_header ())
    {
      counts[MSC_macros] = write_macros (to, reader, &crc);
      counts[MSC_inits] = write_inits (to, table, &crc);
    }

  unsigned clusters = counts[MSC_sec_hwm] - counts[MSC_sec_lwm];
  dump () && dump ("Wrote %u clusters, average %u bytes/cluster",
		   clusters, (bytes + clusters / 2) / (clusters + !clusters));

  write_counts (to, counts, &crc);

  /* And finish up.  */
  write_config (to, config, crc);

  spaces.release ();
  sccs.release ();

  vec_free (ool);

  /* Human-readable info.  */
  write_readme (to, reader, config.dialect_str, extensions);

  // FIXME:QOI:  Have a command line switch to control more detailed
  // information (which might leak data you do not want to leak).
  // Perhaps (some of) the write_readme contents should also be
  // so-controlled.
  if (false)
    write_env (to);

  trees_out::instrument ();
  dump () && dump ("Wrote %u sections", to->get_section_limit ());
}

/* Initial read of a CMI.  Checks config, loads up imports and line
   maps.  */

bool
module_state::read_initial (cpp_reader *reader)
{
  module_state_config config;
  bool ok = true;

  if (ok && !from ()->begin (loc))
    ok = false;

  if (ok && !read_config (config))
    ok = false;

  bool have_locs = ok && read_prepare_maps (&config);

  /* Ordinary maps before the imports.  */
  if (have_locs && !read_ordinary_maps ())
    ok = false;

  /* Allocate the REMAP vector.  */
  slurp->alloc_remap (config.num_imports);

  if (ok)
    {
      /* Read the import table.  Decrement current to stop this CMI
	 from being evicted during the import. */
      slurp->current--;
      if (config.num_imports > 1 && !read_imports (reader, line_table))
	ok = false;
      slurp->current++;
    }

  /* Read the elided partition table, if we're the primary partition.  */
  if (ok && config.num_partitions && is_module ()
      && !read_partitions (config.num_partitions))
    ok = false;

  /* Determine the module's number.  */
  gcc_checking_assert (mod == MODULE_UNKNOWN);
  gcc_checking_assert (this != (*modules)[0]);

  {
    /* Allocate space in the entities array now -- that array must be
       monotionically in step with the modules array.  */
    entity_lwm = vec_safe_length (entity_ary);
    entity_num = config.num_entities;
    gcc_checking_assert (modules->length () == 1
			 || modules->last ()->entity_lwm <= entity_lwm);
    vec_safe_reserve (entity_ary, config.num_entities);

    binding_slot slot;
    slot.u.binding = NULL_TREE;
    for (unsigned count = config.num_entities; count--;)
      entity_ary->quick_push (slot);
  }

  /* We'll run out of other resources before we run out of module
     indices.  */
  mod = modules->length ();
  vec_safe_push (modules, this);

  /* We always import and export ourselves. */
  bitmap_set_bit (imports, mod);
  bitmap_set_bit (exports, mod);

  if (ok)
    (*slurp->remap)[0] = mod << 1;
  dump () && dump ("Assigning %M module number %u", this, mod);

  /* We should not have been frozen during the importing done by
     read_config.  */
  gcc_assert (!from ()->is_frozen ());

  /* Macro maps after the imports.  */
  if (ok && have_locs && !read_macro_maps ())
    ok = false;

  gcc_assert (slurp->current == ~0u);
  return ok;
}

/* Read a preprocessor state.  */

bool
module_state::read_preprocessor (bool outermost)
{
  gcc_checking_assert (is_header () && slurp
		       && slurp->remap_module (0) == mod);

  if (loadedness == ML_PREPROCESSOR)
    return !(from () && from ()->get_error ());

  bool ok = true;

  /* Read direct header imports.  */
  unsigned len = slurp->remap->length ();
  for (unsigned ix = 1; ok && ix != len; ix++)
    {
      unsigned map = (*slurp->remap)[ix];
      if (map & 1)
	{
	  module_state *import = (*modules)[map >> 1];
	  if (import->is_header ())
	    {
	      ok = import->read_preprocessor (false);
	      bitmap_ior_into (slurp->headers, import->slurp->headers);
	    }
	}
    }

  /* Record as a direct header.  */
  if (ok)
    bitmap_set_bit (slurp->headers, mod);

  if (ok && !read_macros ())
    ok = false;

  loadedness = ML_PREPROCESSOR;
  announce ("macros");

  if (flag_preprocess_only)
    /* We're done with the string table.  */
    from ()->release ();

  return check_read (outermost, ok);
}

/* Read language state.  */

bool
module_state::read_language (bool outermost)
{
  gcc_checking_assert (!lazy_snum);

  if (loadedness == ML_LANGUAGE)
    return !(slurp && from () && from ()->get_error ());

  gcc_checking_assert (slurp && slurp->current == ~0u
		       && slurp->remap_module (0) == mod);

  bool ok = true;

  /* Read direct imports.  */
  unsigned len = slurp->remap->length ();
  for (unsigned ix = 1; ok && ix != len; ix++)
    {
      unsigned map = (*slurp->remap)[ix];
      if (map & 1)
	{
	  module_state *import = (*modules)[map >> 1];
	  if (!import->read_language (false))
	    ok = false;
	}
    }

  unsigned counts[MSC_HWM];

  if (ok && !read_counts (counts))
    ok = false;

  function_depth++; /* Prevent unexpected GCs.  */

  if (counts[MSC_entities] != entity_num)
    ok = false;
  if (ok && counts[MSC_entities]
      && !read_entities (counts[MSC_entities],
			 counts[MSC_sec_lwm], counts[MSC_sec_hwm]))
    ok = false;

  /* Read the namespace hierarchy. */
  if (ok && counts[MSC_namespaces]
      && !read_namespaces (counts[MSC_namespaces]))
    ok = false;

  if (ok && !read_bindings (counts[MSC_bindings],
			    counts[MSC_sec_lwm], counts[MSC_sec_hwm]))
    ok = false;

  /* And unnamed.  */
  if (ok && counts[MSC_pendings] && !read_pendings (counts[MSC_pendings]))
    ok = false;

  if (ok)
    {
      slurp->remaining = counts[MSC_sec_hwm] - counts[MSC_sec_lwm];
      available_clusters += counts[MSC_sec_hwm] - counts[MSC_sec_lwm];
    }

  if (!flag_module_lazy
      || (is_partition ()
	  && module_interface_p ()
	  && !module_partition_p ()))
    {
      /* Read the sections in forward order, so that dependencies are read
	 first.  See note about tarjan_connect.  */
      ggc_collect ();

      lazy_snum = ~0u;

      unsigned hwm = counts[MSC_sec_hwm];
      for (unsigned ix = counts[MSC_sec_lwm]; ok && ix != hwm; ix++)
	if (!load_section (ix, NULL))
	  {
	    ok = false;
	    break;
	  }
      lazy_snum = 0;
      post_load_processing ();

      ggc_collect ();

      if (ok && CHECKING_P)
	for (unsigned ix = 0; ix != entity_num; ix++)
	  gcc_assert (!(*entity_ary)[ix + entity_lwm].is_lazy ());
    }

  // If the import is a header-unit, we need to register initializers
  // of any static objects it contains (looking at you _Ioinit).
  // Notice, the ordering of these initializers will be that of a
  // dynamic initializer at this point in the current TU.  (Other
  // instances of these objects in other TUs will be initialized as
  // part of that TU's global initializers.)
  if (ok && counts[MSC_inits] && !read_inits (counts[MSC_inits]))
    ok = false;

  function_depth--;
  
  announce (flag_module_lazy ? "lazy" : "imported");
  loadedness = ML_LANGUAGE;

  gcc_assert (slurp->current == ~0u);

  /* We're done with the string table.  */
  from ()->release ();

  return check_read (outermost, ok);
}

bool
module_state::maybe_defrost ()
{
  bool ok = true;
  if (from ()->is_frozen ())
    {
      if (lazy_open >= lazy_limit)
	freeze_an_elf ();
      dump () && dump ("Defrosting '%s'", filename);
      ok = from ()->defrost (maybe_add_cmi_prefix (filename));
      lazy_open++;
    }

  return ok;
}

/* Load section SNUM, dealing with laziness.  It doesn't matter if we
   have multiple concurrent loads, because we do not use TREE_VISITED
   when reading back in.  */

bool
module_state::load_section (unsigned snum, binding_slot *mslot)
{
  if (from ()->get_error ())
    return false;

  if (snum >= slurp->current)
    from ()->set_error (elf::E_BAD_LAZY);
  else if (maybe_defrost ())
    {
      unsigned old_current = slurp->current;
      slurp->current = snum;
      slurp->lru = 0;  /* Do not swap out.  */
      slurp->remaining--;
      read_cluster (snum);
      slurp->lru = ++lazy_lru;
      slurp->current = old_current;
    }
  
  if (mslot && mslot->is_lazy ())
    {
      /* Oops, the section didn't set this slot.  */
      from ()->set_error (elf::E_BAD_DATA);
      *mslot = NULL_TREE;
    }

  bool ok = !from ()->get_error ();
  if (!ok)
    {
      error_at (loc, "failed to read compiled module cluster %u: %s",
		snum, from ()->get_error (filename));
      note_cmi_name ();
    }

  maybe_completed_reading ();

  return ok;
}

void
module_state::maybe_completed_reading ()
{
  if (loadedness == ML_LANGUAGE && slurp->current == ~0u && !slurp->remaining)
    {
      lazy_open--;
      /* We no longer need the macros, all tokenizing has been done.  */
      slurp->release_macros ();

      from ()->end ();
      slurp->close ();
      slurped ();
    }
}

/* After a reading operation, make sure things are still ok.  If not,
   emit an error and clean up.  */

bool
module_state::check_read (bool outermost, bool ok)
{
  gcc_checking_assert (!outermost || slurp->current == ~0u);

  if (!ok)
    from ()->set_error ();

  if (int e = from ()->get_error ())
    {
      error_at (loc, "failed to read compiled module: %s",
		from ()->get_error (filename));
      note_cmi_name ();

      if (e == EMFILE
	  || e == ENFILE
#if MAPPED_READING
	  || e == ENOMEM
#endif
	  || false)
	inform (loc, "consider using %<-fno-module-lazy%>,"
		" increasing %<-param-lazy-modules=%u%> value,"
		" or increasing the per-process file descriptor limit",
		param_lazy_modules);
      else if (e == ENOENT)
	inform (loc, "imports must be built before being imported");

      if (outermost)
	fatal_error (loc, "returning to the gate for a mechanical issue");

      ok = false;
    }

  maybe_completed_reading ();

  return ok;
}

/* Return the IDENTIFIER_NODE naming module IX.  This is the name
   including dots.  */

char const *
module_name (unsigned ix, bool header_ok)
{
  if (modules)
    {
      module_state *imp = (*modules)[ix];

      if (ix && !imp->name)
	imp = imp->parent;

      if (header_ok || !imp->is_header ())
	return imp->get_flatname ();
    }

  return NULL;
}

/* Return the bitmap describing what modules are imported.  Remember,
   we always import ourselves.  */

bitmap
get_import_bitmap ()
{
  return (*modules)[0]->imports;
}

/* Return the visible imports and path of instantiation for an
   instantiation at TINST.  If TINST is nullptr, we're not in an
   instantiation, and thus will return the visible imports of the
   current TU (and NULL *PATH_MAP_P).   We cache the information on
   the tinst level itself.  */

static bitmap
path_of_instantiation (tinst_level *tinst,  bitmap *path_map_p)
{
  gcc_checking_assert (modules_p ());

  if (!tinst)
    {
      /* Not inside an instantiation, just the regular case.  */
      *path_map_p = nullptr;
      return get_import_bitmap ();
    }

  if (!tinst->path)
    {
      /* Calculate.  */
      bitmap visible = path_of_instantiation (tinst->next, path_map_p);
      bitmap path_map = *path_map_p;

      if (!path_map)
	{
	  path_map = BITMAP_GGC_ALLOC ();
	  bitmap_set_bit (path_map, 0);
	}

      tree decl = tinst->tldcl;
      if (TREE_CODE (decl) == TREE_LIST)
	decl = TREE_PURPOSE (decl);
      if (TYPE_P (decl))
	decl = TYPE_NAME (decl);

      if (unsigned mod = get_originating_module (decl))
	if (!bitmap_bit_p (path_map, mod))
	  {
	    /* This is brand new information!  */
	    bitmap new_path = BITMAP_GGC_ALLOC ();
	    bitmap_copy (new_path, path_map);
	    bitmap_set_bit (new_path, mod);
	    path_map = new_path;

	    bitmap imports = (*modules)[mod]->imports;
	    if (bitmap_intersect_compl_p (imports, visible))
	      {
		/* IMPORTS contains additional modules to VISIBLE.  */
		bitmap new_visible = BITMAP_GGC_ALLOC ();

		bitmap_ior (new_visible, visible, imports);
		visible = new_visible;
	      }
	  }

      tinst->path = path_map;
      tinst->visible = visible;
    }

  *path_map_p = tinst->path;
  return tinst->visible;
}

/* Return the bitmap describing what modules are visible along the
   path of instantiation.  If we're not an instantiation, this will be
   the visible imports of the TU.  *PATH_MAP_P is filled in with the
   modules owning the instantiation path -- we see the module-linkage
   entities of those modules.  */

bitmap
visible_instantiation_path (bitmap *path_map_p)
{
  if (!modules_p ())
    return NULL;

  return path_of_instantiation (current_instantiation (), path_map_p);
}

/* We've just directly imported IMPORT.  Update our import/export
   bitmaps.  IS_EXPORT is true if we're reexporting the OTHER.  */

void
module_state::set_import (module_state const *import, bool is_export)
{
  gcc_checking_assert (this != import);

  /* We see IMPORT's exports (which includes IMPORT).  If IMPORT is
     the primary interface or a partition we'll see its imports.  */
  bitmap_ior_into (imports, import->is_module () || import->is_partition ()
		   ? import->imports : import->exports);

  if (is_export)
    /* We'll export OTHER's exports.  */
    bitmap_ior_into (exports, import->exports);
}

/* Return the declaring entity of DECL.  That is the decl determining
   how to decorate DECL with module information.  Returns NULL_TREE if
   it's the global module.  */

tree
get_originating_module_decl (tree decl)
{
  /* An enumeration constant.  */
  if (TREE_CODE (decl) == CONST_DECL
      && DECL_CONTEXT (decl)
      && (TREE_CODE (DECL_CONTEXT (decl)) == ENUMERAL_TYPE))
    decl = TYPE_NAME (DECL_CONTEXT (decl));
  else if (TREE_CODE (decl) == FIELD_DECL
	   || TREE_CODE (decl) == USING_DECL)
    {
      decl = DECL_CONTEXT (decl);
      if (TREE_CODE (decl) != FUNCTION_DECL)
	decl = TYPE_NAME (decl);
    }

  gcc_checking_assert (TREE_CODE (decl) == TEMPLATE_DECL
		       || TREE_CODE (decl) == FUNCTION_DECL
		       || TREE_CODE (decl) == TYPE_DECL
		       || TREE_CODE (decl) == VAR_DECL
		       || TREE_CODE (decl) == CONCEPT_DECL
		       || TREE_CODE (decl) == NAMESPACE_DECL);

  for (;;)
    {
      /* Uninstantiated template friends are owned by the befriending
	 class -- not their context.  */
      if (TREE_CODE (decl) == TEMPLATE_DECL
	  && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
	decl = TYPE_NAME (DECL_CHAIN (decl));

      int use;
      if (tree ti = node_template_info (decl, use))
	{
	  decl = TI_TEMPLATE (ti);
	  if (TREE_CODE (decl) != TEMPLATE_DECL)
	    {
	      /* A friend template specialization.  */
	      gcc_checking_assert (OVL_P (decl));
	      return global_namespace;
	    }
	}
      else
	{
	  tree ctx = CP_DECL_CONTEXT (decl);
	  if (TREE_CODE (ctx) == NAMESPACE_DECL)
	    break;

	  if (TYPE_P (ctx))
	    {
	      ctx = TYPE_NAME (ctx);
	      if (!ctx)
		{
		  /* Some kind of internal type.  */
		  gcc_checking_assert (DECL_ARTIFICIAL (decl));
		  return global_namespace;
		}
	    }
	  decl = ctx;
	}
    }

  return decl;
}

int
get_originating_module (tree decl, bool for_mangle)
{
  tree owner = get_originating_module_decl (decl);
  tree not_tmpl = STRIP_TEMPLATE (owner);

  if (!DECL_LANG_SPECIFIC (not_tmpl))
    return for_mangle ? -1 : 0;

  if (for_mangle
      && (DECL_MODULE_EXPORT_P (owner) || !DECL_MODULE_PURVIEW_P (not_tmpl)))
    return -1;

  if (!DECL_MODULE_IMPORT_P (not_tmpl))
    return 0;

  return get_importing_module (owner);
}

unsigned
get_importing_module (tree decl, bool flexible)
{
  unsigned index = import_entity_index (decl, flexible);
  if (index == ~(~0u >> 1))
    return -1;
  module_state *module = import_entity_module (index);

  return module->mod;
}

/* Is it permissible to redeclare DECL.  */

bool
module_may_redeclare (tree decl)
{
  module_state *me = (*modules)[0];
  module_state *them = me;
  tree not_tmpl = STRIP_TEMPLATE (decl);
  if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_IMPORT_P (not_tmpl))
    {
      /* We can be given the TEMPLATE_RESULT.  We want the
	 TEMPLATE_DECL.  */
      int use_tpl = -1;
      if (tree ti = node_template_info (decl, use_tpl))
	{
	  tree tmpl = TI_TEMPLATE (ti);
	  if (use_tpl == 2)
	    {
	      /* A partial specialization.  Find that specialization's
		 template_decl.  */
	      for (tree list = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
		   list; list = TREE_CHAIN (list))
		if (DECL_TEMPLATE_RESULT (TREE_VALUE (list)) == decl)
		  {
		    decl = TREE_VALUE (list);
		    break;
		}
	    }
	  else if (DECL_TEMPLATE_RESULT (tmpl) == decl)
	    decl = tmpl;
	}
      unsigned index = import_entity_index (decl);
      them = import_entity_module (index);
    }

  if (them->is_header ())
    {
      if (!header_module_p ())
	return !module_purview_p ();

      if (DECL_SOURCE_LOCATION (decl) == BUILTINS_LOCATION)
	/* This is a builtin, being declared in header-unit.  We
	   now need to mark it as an export.  */
	DECL_MODULE_EXPORT_P (decl) = true;

      /* If it came from a header, it's in the global module.  */
      return true;
    }

  if (me == them)
    return ((DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_PURVIEW_P (not_tmpl))
	    == module_purview_p ());

  if (!me->name)
    me = me->parent;

  /* We can't have found a GMF entity from a named module.  */
  gcc_checking_assert (DECL_LANG_SPECIFIC (not_tmpl)
		       && DECL_MODULE_PURVIEW_P (not_tmpl));

  return me && get_primary (them) == get_primary (me);
}

/* DECL is being created by this TU.  Record it came from here.  We
   record module purview, so we can see if partial or explicit
   specialization needs to be written out, even though its purviewness
   comes from the most general template.  */

void
set_instantiating_module (tree decl)
{
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
	      || TREE_CODE (decl) == VAR_DECL
	      || TREE_CODE (decl) == TYPE_DECL
	      || TREE_CODE (decl) == CONCEPT_DECL
	      || TREE_CODE (decl) == TEMPLATE_DECL
	      || (TREE_CODE (decl) == NAMESPACE_DECL
		  && DECL_NAMESPACE_ALIAS (decl)));

  if (!modules_p ())
    return;

  decl = STRIP_TEMPLATE (decl);

  if (!DECL_LANG_SPECIFIC (decl) && module_purview_p ())
    retrofit_lang_decl (decl);

  if (DECL_LANG_SPECIFIC (decl))
    {
      DECL_MODULE_PURVIEW_P (decl) = module_purview_p ();
      /* If this was imported, we'll still be in the entity_hash.  */
      DECL_MODULE_IMPORT_P (decl) = false;
    }
}

/* If DECL is a class member, whose class is not defined in this TU
   (it was imported), remember this decl.  */

void
set_defining_module (tree decl)
{
  gcc_checking_assert (!DECL_LANG_SPECIFIC (decl)
		       || !DECL_MODULE_IMPORT_P (decl));

  if (module_has_cmi_p ())
    {
      tree ctx = DECL_CONTEXT (decl);
      if (ctx
	  && (TREE_CODE (ctx) == RECORD_TYPE || TREE_CODE (ctx) == UNION_TYPE)
	  && DECL_LANG_SPECIFIC (TYPE_NAME (ctx))
	  && DECL_MODULE_IMPORT_P (TYPE_NAME (ctx)))
	{
	  /* This entity's context is from an import.  We may need to
	     record this entity to make sure we emit it in the CMI.
	     Template specializations are in the template hash tables,
	     so we don't need to record them here as well.  */
	  int use_tpl = -1;
	  tree ti = node_template_info (decl, use_tpl);
	  if (use_tpl <= 0)
	    {
	      if (ti)
		{
		  gcc_checking_assert (!use_tpl);
		  /* Get to the TEMPLATE_DECL.  */
		  decl = TI_TEMPLATE (ti);
		}

	      /* Record it on the class_members list.  */
	      vec_safe_push (class_members, decl);
	    }
	}
      else if (DECL_IMPLICIT_TYPEDEF_P (decl)
	       && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
	/* This is a partial or explicit specialization.  */
	vec_safe_push (partial_specializations, decl);
    }
}

void
set_originating_module (tree decl, bool friend_p ATTRIBUTE_UNUSED)
{
  set_instantiating_module (decl);

  if (TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)
    return;

  gcc_checking_assert (friend_p || decl == get_originating_module_decl (decl));

  if (!module_exporting_p ())
    return;

  // FIXME: Check ill-formed linkage
  DECL_MODULE_EXPORT_P (decl) = true;
}

/* DECL is attached to ROOT for odr purposes.  */

void
maybe_attach_decl (tree ctx, tree decl)
{
  if (!modules_p ())
    return;

  // FIXME: For now just deal with lambdas attached to var decls.
  // This might be sufficient?
  if (TREE_CODE (ctx) != VAR_DECL)
    return;

  gcc_checking_assert (DECL_NAMESPACE_SCOPE_P (ctx));

 if (!attached_table)
    attached_table = new attached_map_t (EXPERIMENT (1, 400));

 auto &vec = attached_table->get_or_insert (ctx);
 if (!vec.length ())
   {
     retrofit_lang_decl (ctx);
     DECL_MODULE_ATTACHMENTS_P (ctx) = true;
   }
 vec.safe_push (decl);
}

/* Create the flat name string.  It is simplest to have it handy.  */

void
module_state::set_flatname ()
{
  gcc_checking_assert (!flatname);
  if (parent)
    {
      auto_vec<tree,5> ids;
      size_t len = 0;
      char const *primary = NULL;
      size_t pfx_len = 0;

      for (module_state *probe = this;
	   probe;
	   probe = probe->parent)
	if (is_partition () && !probe->is_partition ())
	  {
	    primary = probe->get_flatname ();
	    pfx_len = strlen (primary);
	    break;
	  }
	else
	  {
	    ids.safe_push (probe->name);
	    len += IDENTIFIER_LENGTH (probe->name) + 1;
	  }

      char *flat = XNEWVEC (char, pfx_len + len + is_partition ());
      flatname = flat;

      if (primary)
	{
	  memcpy (flat, primary, pfx_len);
	  flat += pfx_len;
	  *flat++ = ':';
	}

      for (unsigned len = 0; ids.length ();)
	{
	  if (len)
	    flat[len++] = '.';
	  tree elt = ids.pop ();
	  unsigned l = IDENTIFIER_LENGTH (elt);
	  memcpy (flat + len, IDENTIFIER_POINTER (elt), l + 1);
	  len += l;
	}
    }
  else if (is_header ())
    flatname = TREE_STRING_POINTER (name);
  else
    flatname = IDENTIFIER_POINTER (name);
}

/* Read the CMI file for a module.  */

bool
module_state::do_import (cpp_reader *reader, bool outermost)
{
  gcc_assert (global_namespace == current_scope () && loadedness == ML_NONE);

  loc = linemap_module_loc (line_table, loc, get_flatname ());

  if (lazy_open >= lazy_limit)
    freeze_an_elf ();

  int fd = -1;
  int e = ENOENT;
  if (filename)
    {
      const char *file = maybe_add_cmi_prefix (filename);
      dump () && dump ("CMI is %s", file);
      if (note_module_cmi_yes || inform_cmi_p)
	inform (loc, "reading CMI %qs", file);
      fd = open (file, O_RDONLY | O_CLOEXEC | O_BINARY);
      e = errno;
    }

  gcc_checking_assert (!slurp);
  slurp = new slurping (new elf_in (fd, e));

  bool ok = true;
  if (!from ()->get_error ())
    {
      announce ("importing");
      loadedness = ML_CONFIG;
      lazy_open++;
      ok = read_initial (reader);
      slurp->lru = ++lazy_lru;
    }

  gcc_assert (slurp->current == ~0u);

  return check_read (outermost, ok);
}

/* Attempt to increase the file descriptor limit.  */

static bool
try_increase_lazy (unsigned want)
{
  gcc_checking_assert (lazy_open >= lazy_limit);

  /* If we're increasing, saturate at hard limit.  */
  if (want > lazy_hard_limit && lazy_limit < lazy_hard_limit)
    want = lazy_hard_limit;

#if HAVE_SETRLIMIT
  if ((!lazy_limit || !param_lazy_modules)
      && lazy_hard_limit
      && want <= lazy_hard_limit)
    {
      struct rlimit rlimit;
      rlimit.rlim_cur = want + LAZY_HEADROOM;
      rlimit.rlim_max = lazy_hard_limit + LAZY_HEADROOM;
      if (!setrlimit (RLIMIT_NOFILE, &rlimit))
	lazy_limit = want;
    }
#endif

  return lazy_open < lazy_limit;
}

/* Pick a victim module to freeze its reader.  */

void
module_state::freeze_an_elf ()
{
  if (try_increase_lazy (lazy_open * 2))
    return;

  module_state *victim = NULL;
  for (unsigned ix = modules->length (); ix--;)
    {
      module_state *candidate = (*modules)[ix];
      if (candidate && candidate->slurp && candidate->slurp->lru
	  && candidate->from ()->is_freezable ()
	  && (!victim || victim->slurp->lru > candidate->slurp->lru))
	victim = candidate;
    }

  if (victim)
    {
      dump () && dump ("Freezing '%s'", victim->filename);
      if (victim->slurp->macro_defs.size)
	/* Save the macro definitions to a buffer.  */
	victim->from ()->preserve (victim->slurp->macro_defs);
      if (victim->slurp->macro_tbl.size)
	/* Save the macro definitions to a buffer.  */
	victim->from ()->preserve (victim->slurp->macro_tbl);
      victim->from ()->freeze ();
      lazy_open--;
    }
  else
    dump () && dump ("No module available for freezing");
}

/* Load the lazy slot *MSLOT, INDEX'th slot of the module.  */

bool
module_state::lazy_load (unsigned index, binding_slot *mslot)
{
  unsigned n = dump.push (this);

  gcc_checking_assert (function_depth);

  unsigned cookie = mslot->get_lazy ();
  unsigned snum = cookie >> 2;
  dump () && dump ("Loading entity %M[%u] section:%u", this, index, snum);

  bool ok = load_section (snum, mslot);
 
  dump.pop (n);

  return ok;
}

/* Load MOD's binding for NS::ID into *MSLOT.  *MSLOT contains the
   lazy cookie.  OUTER is true if this is the outermost lazy, (used
   for diagnostics).  */

void
lazy_load_binding (unsigned mod, tree ns, tree id, binding_slot *mslot)
{
  int count = errorcount + warningcount;

  timevar_start (TV_MODULE_IMPORT);

  /* Stop GC happening, even in outermost loads (because our caller
     could well be building up a lookup set).  */
  function_depth++;

  gcc_checking_assert (mod);
  module_state *module = (*modules)[mod];
  unsigned n = dump.push (module);

  unsigned snum = mslot->get_lazy ();
  dump () && dump ("Lazily binding %P@%N section:%u", ns, id,
		   module->name, snum);

  bool ok = !recursive_lazy (snum);
  if (ok)
    {
      ok = module->load_section (snum, mslot);
      lazy_snum = 0;
      post_load_processing ();
    }

  dump.pop (n);

  function_depth--;

  timevar_stop (TV_MODULE_IMPORT);

  if (!ok)
    fatal_error (input_location,
		 module->is_header ()
		 ? G_("failed to load binding %<%E%s%E%>")
		 : G_("failed to load binding %<%E%s%E@%s%>"),
		 ns, &"::"[ns == global_namespace ? 2 : 0], id,
		 module->get_flatname ());

  if (count != errorcount + warningcount)
    inform (input_location,
	    module->is_header ()
	    ? G_("during load of binding %<%E%s%E%>")
	    : G_("during load of binding %<%E%s%E@%s%>"),
	    ns, &"::"[ns == global_namespace ? 2 : 0], id,
	    module->get_flatname ());
}

/* Load any pending entities keyed to the top-key of DECL.  */

void
lazy_load_pendings (tree decl)
{
  tree key_decl;
  pending_key key;
  key.ns = find_pending_key (decl, &key_decl);
  key.id = DECL_NAME (key_decl);

  auto *pending_vec = pending_table ? pending_table->get (key) : nullptr;
  if (!pending_vec)
    return;

  int count = errorcount + warningcount;

  timevar_start (TV_MODULE_IMPORT);
  bool ok = !recursive_lazy ();
  if (ok)
    {
      function_depth++; /* Prevent GC */
      unsigned n = dump.push (NULL);
      dump () && dump ("Reading %u pending entities keyed to %P",
		       pending_vec->length (), key.ns, key.id);
      for (unsigned ix = pending_vec->length (); ix--;)
	{
	  unsigned index = (*pending_vec)[ix];
	  binding_slot *slot = &(*entity_ary)[index];

	  if (slot->is_lazy ())
	    {
	      module_state *import = import_entity_module (index);
	      if (!import->lazy_load (index - import->entity_lwm, slot))
		ok = false;
	    }
	  else if (dump ())
	    {
	      module_state *import = import_entity_module (index);
	      dump () && dump ("Entity %M[%u] already loaded",
			       import, index - import->entity_lwm);
	    }
	}

      pending_table->remove (key);
      dump.pop (n);
      lazy_snum = 0;
      post_load_processing ();
      function_depth--;
    }

  timevar_stop (TV_MODULE_IMPORT);

  if (!ok)
    fatal_error (input_location, "failed to load pendings for %<%E%s%E%>",
		 key.ns, &"::"[key.ns == global_namespace ? 2 : 0], key.id);

  if (count != errorcount + warningcount)
    inform (input_location, "during load of pendings for %<%E%s%E%>",
	    key.ns, &"::"[key.ns == global_namespace ? 2 : 0], key.id);
}

static void
direct_import (module_state *import, cpp_reader *reader)
{
  timevar_start (TV_MODULE_IMPORT);
  unsigned n = dump.push (import);

  gcc_checking_assert (import->is_direct () && import->has_location ());
  if (import->loadedness == ML_NONE)
    if (!import->do_import (reader, true))
      gcc_unreachable ();

  if (import->loadedness < ML_LANGUAGE)
    {
      if (!attached_table)
	attached_table = new attached_map_t (EXPERIMENT (1, 400));
      import->read_language (true);
    }

  (*modules)[0]->set_import (import, import->exported_p);

  dump.pop (n);
  timevar_stop (TV_MODULE_IMPORT);
}

/* Import module IMPORT.  */

void
import_module (module_state *import, location_t from_loc, bool exporting_p,
	       tree, cpp_reader *reader)
{
  if (!import->check_not_purview (from_loc))
    return;

  if (!import->is_header () && current_lang_depth ())
    /* Only header units should appear inside language
       specifications.  The std doesn't specify this, but I think
       that's an error in resolving US 033, because language linkage
       is also our escape clause to getting things into the global
       module, so we don't want to confuse things by having to think
       about whether 'extern "C++" { import foo; }' puts foo's
       contents into the global module all of a sudden.  */
    warning (0, "import of named module %qs inside language-linkage block",
	     import->get_flatname ());

  if (exporting_p || module_exporting_p ())
    import->exported_p = true;

  if (import->loadedness != ML_NONE)
    {
      from_loc = ordinary_loc_of (line_table, from_loc);
      linemap_module_reparent (line_table, import->loc, from_loc);
    }
  gcc_checking_assert (!import->module_p);
  gcc_checking_assert (import->is_direct () && import->has_location ());

  direct_import (import, reader);
}

/* Declare the name of the current module to be NAME.  EXPORTING_p is
   true if this TU is the exporting module unit.  */

void
declare_module (module_state *module, location_t from_loc, bool exporting_p,
		tree, cpp_reader *reader)
{
  gcc_assert (global_namespace == current_scope ());

  module_state *current = (*modules)[0];
  if (module_purview_p () || module->loadedness > ML_CONFIG)
    {
      error_at (from_loc, module_purview_p ()
		? G_("module already declared")
		: G_("module already imported"));
      if (module_purview_p ())
	module = current;
      inform (module->loc, module_purview_p ()
	      ? G_("module %qs declared here")
	      : G_("module %qs imported here"),
	      module->get_flatname ());
      return;
    }

  gcc_checking_assert (module->module_p);
  gcc_checking_assert (module->is_direct () && module->has_location ());

  /* Yer a module, 'arry.  */
  module_kind &= ~MK_GLOBAL;
  module_kind |= MK_MODULE;

  if (module->is_partition () || exporting_p)
    {
      gcc_checking_assert (module->get_flatname ());

      if (module->is_partition ())
	module_kind |= MK_PARTITION;

      if (exporting_p)
	{
	  module->interface_p = true;
	  module_kind |= MK_INTERFACE;
	}

      if (module->is_header ())
	module_kind |= MK_GLOBAL | MK_EXPORTING;

      /* Copy the importing information we may have already done.  We
	 do not need to separate out the imports that only happen in
	 the GMF, inspite of what the literal wording of the std
	 might imply.  See p2191, the core list had a discussion
	 where the module implementors agreed that the GMF of a named
	 module is invisible to importers.  */
      module->imports = current->imports;

      module->mod = 0;
      (*modules)[0] = module;
    }
  else
    {
      module->interface_p = true;
      current->parent = module; /* So mangler knows module identity. */
      direct_import (module, reader);
    }
}

/* +1, we're the primary or a partition.  Therefore emitting a
   globally-callable idemportent initializer function.
   -1, we have direct imports.  Therefore emitting calls to their
   initializers.  */

int
module_initializer_kind ()
{
  int result = 0;

  if (module_has_cmi_p () && !header_module_p ())
    result = +1;
  else if (num_init_calls_needed)
    result = -1;

  return result;
}

/* Emit calls to each direct import's global initializer.  Including
   direct imports of directly imported header units.  The initializers
   of (static) entities in header units will be called by their
   importing modules (for the instance contained within that), or by
   the current TU (for the instances we've brought in).  Of course
   such header unit behaviour is evil, but iostream went through that
   door some time ago.  */

void
module_add_import_initializers ()
{
  unsigned calls = 0;
  if (modules)
    {
      tree fntype = build_function_type (void_type_node, void_list_node);
      releasing_vec args;  // There are no args

      for (unsigned ix = modules->length (); --ix;)
	{
	  module_state *import = (*modules)[ix];
	  if (import->call_init_p)
	    {
	      tree name = mangle_module_global_init (ix);
	      tree fndecl = build_lang_decl (FUNCTION_DECL, name, fntype);

	      DECL_CONTEXT (fndecl) = FROB_CONTEXT (global_namespace);
	      SET_DECL_ASSEMBLER_NAME (fndecl, name);
	      TREE_PUBLIC (fndecl) = true;
	      determine_visibility (fndecl);

	      tree call = cp_build_function_call_vec (fndecl, &args,
						      tf_warning_or_error);
	      finish_expr_stmt (call);
	      
	      calls++;
	    }
	}
    }

  gcc_checking_assert (calls == num_init_calls_needed);
}

/* NAME & LEN are a preprocessed header name, possibly including the
   surrounding "" or <> characters.  Return the raw string name of the
   module to which it refers.  This will be an absolute path, or begin
   with ./, so it is immediately distinguishable from a (non-header
   unit) module name.  If READER is non-null, ask the preprocessor to
   locate the header to which it refers using the appropriate include
   path.  Note that we do never do \ processing of the string, as that
   matches the preprocessor's behaviour.  */

static const char *
canonicalize_header_name (cpp_reader *reader, location_t loc, bool unquoted,
			  const char *str, size_t &len_r)
{
  size_t len = len_r;
  static char *buf = 0;
  static size_t alloc = 0;

  if (!unquoted)
    {
      gcc_checking_assert (len >= 2
			   && ((reader && str[0] == '<' && str[len-1] == '>')
			       || (str[0] == '"' && str[len-1] == '"')));
      str += 1;
      len -= 2;
    }

  if (reader)
    {
      gcc_assert (!unquoted);

      if (len >= alloc)
	{
	  alloc = len + 1;
	  buf = XRESIZEVEC (char, buf, alloc);
	}
      memcpy (buf, str, len);
      buf[len] = 0;

      if (const char *hdr
	  = cpp_probe_header_unit (reader, buf, str[-1] == '<', loc))
	{
	  len = strlen (hdr);
	  str = hdr;
	}
      else
	str = buf;
    }

  if (!(str[0] == '.' ? IS_DIR_SEPARATOR (str[1]) : IS_ABSOLUTE_PATH (str)))
    {
      /* Prepend './'  */
      if (len + 3 > alloc)
	{
	  alloc = len + 3;
	  buf = XRESIZEVEC (char, buf, alloc);
	}

      buf[0] = '.';
      buf[1] = DIR_SEPARATOR;
      memmove (buf + 2, str, len);
      len += 2;
      buf[len] = 0;
      str = buf;
    }

  len_r = len;
  return str;
}

/* Set the CMI name from a cody packet.  Issue an error if
   ill-formed.  */

void module_state::set_filename (const Cody::Packet &packet)
{
  gcc_checking_assert (!filename);
  if (packet.GetCode () == Cody::Client::PC_PATHNAME)
    filename = xstrdup (packet.GetString ().c_str ());
  else
    {
      gcc_checking_assert (packet.GetCode () == Cody::Client::PC_ERROR);
      error_at (loc, "unknown Compiled Module Interface: %s",
		packet.GetString ().c_str ());
    }
}

/* Figure out whether to treat HEADER as an include or an import.  */

static char *
maybe_translate_include (cpp_reader *reader, line_maps *lmaps, location_t loc,
			 const char *path)
{
  if (!modules_p ())
    {
      /* Turn off.  */
      cpp_get_callbacks (reader)->translate_include = NULL;
      return nullptr;
    }

  if (!spans.init_p ())
    /* Before the main file, don't divert.  */
    return nullptr;

  dump.push (NULL);

  dump () && dump ("Checking include translation '%s'", path);
  auto *mapper = get_mapper (cpp_main_loc (reader));

  size_t len = strlen (path);
  path = canonicalize_header_name (NULL, loc, true, path, len);
  auto packet = mapper->IncludeTranslate (path, Cody::Flags::None, len);
  int xlate = false;
  if (packet.GetCode () == Cody::Client::PC_BOOL)
    xlate = -int (packet.GetInteger ());
  else if (packet.GetCode () == Cody::Client::PC_PATHNAME)
    {
      /* Record the CMI name for when we do the import.  */
      module_state *import = get_module (build_string (len, path));
      import->set_filename (packet);
      xlate = +1;
    }
  else
    {
      gcc_checking_assert (packet.GetCode () == Cody::Client::PC_ERROR);
      error_at (loc, "cannot determine %<#include%> translation of %s: %s",
		path, packet.GetString ().c_str ());
    }

  bool note = false;
  if (note_include_translate_yes && xlate > 1)
    note = true;
  else if (note_include_translate_no && xlate == 0)
    note = true;
  else if (note_includes)
    /* We do not expect the note_includes vector to be large, so O(N)
       iteration.  */
    for (unsigned ix = note_includes->length (); !note && ix--;)
      if (!strcmp ((*note_includes)[ix], path))
	note = true;

  if (note)
    inform (loc, xlate
	    ? G_("include %qs translated to import")
	    : G_("include %qs processed textually") , path);

  dump () && dump (xlate ? "Translating include to import"
		   : "Keeping include as include");
  dump.pop (0);

  if (!(xlate > 0))
    return nullptr;
  
  /* Create the translation text.  */
  loc = ordinary_loc_of (lmaps, loc);
  const line_map_ordinary *map
    = linemap_check_ordinary (linemap_lookup (lmaps, loc));
  unsigned col = SOURCE_COLUMN (map, loc);
  col -= (col != 0); /* Columns are 1-based.  */

  unsigned alloc = len + col + 60;
  char *res = XNEWVEC (char, alloc);

  strcpy (res, "__import");
  unsigned actual = 8;
  if (col > actual)
    {
      /* Pad out so the filename appears at the same position.  */
      memset (res + actual, ' ', col - actual);
      actual = col;
    }
  /* No need to encode characters, that's not how header names are
     handled.  */
  actual += snprintf (res + actual, alloc - actual,
		      "\"%s\" [[__translated]];\n", path);
  gcc_checking_assert (actual < alloc);

  /* cpplib will delete the buffer.  */
  return res;
}

static void
begin_header_unit (cpp_reader *reader)
{
  /* Set the module header name from the main_input_filename.  */
  const char *main = main_input_filename;
  size_t len = strlen (main);
  main = canonicalize_header_name (NULL, 0, true, main, len);
  module_state *module = get_module (build_string (len, main));

  preprocess_module (module, cpp_main_loc (reader), false, false, true, reader);
}

/* We've just properly entered the main source file.  I.e. after the
   command line, builtins and forced headers.  Record the line map and
   location of this map.  Note we may be called more than once.  The
   first call sticks.  */

void
module_begin_main_file (cpp_reader *reader, line_maps *lmaps,
		       const line_map_ordinary *map)
{
  gcc_checking_assert (lmaps == line_table);
  if (modules_p () && !spans.init_p ())
    {
      unsigned n = dump.push (NULL);
      spans.init (lmaps, map);
      dump.pop (n);
      if (flag_header_unit && !cpp_get_options (reader)->preprocessed)
	{
	  /* Tell the preprocessor this is an include file.  */
	  cpp_retrofit_as_include (reader);
	  begin_header_unit (reader);
	}
    }
}

/* Process the pending_import queue, making sure we know the
   filenames.   */

static void
name_pending_imports (cpp_reader *reader)
{
  auto *mapper = get_mapper (cpp_main_loc (reader));

  if (!vec_safe_length (pending_imports))
    /* Not doing anything.  */
    return;

  timevar_start (TV_MODULE_MAPPER);

  auto n = dump.push (NULL);
  dump () && dump ("Resolving direct import names");
  bool want_deps = (bool (mapper->get_flags () & Cody::Flags::NameOnly)
		    || cpp_get_deps (reader));
  bool any = false;

  for (unsigned ix = 0; ix != pending_imports->length (); ix++)
    {
      module_state *module = (*pending_imports)[ix];
      gcc_checking_assert (module->is_direct ());
      if (!module->filename && !module->visited_p)
	{
	  bool export_p = (module->module_p
			   && (module->is_partition () || module->exported_p));

	  Cody::Flags flags = Cody::Flags::None;
	  if (flag_preprocess_only
	      && !(module->is_header () && !export_p))
	    {
	      if (!want_deps)
		continue;
	      flags = Cody::Flags::NameOnly;
	    }

	  if (!any)
	    {
	      any = true;
	      mapper->Cork ();
	    }
	  if (export_p)
	    mapper->ModuleExport (module->get_flatname (), flags);
	  else
	    mapper->ModuleImport (module->get_flatname (), flags);
	  module->visited_p = true;
	}
    }

  if (any)
    {
      auto response = mapper->Uncork ();
      auto r_iter = response.begin ();
      for (unsigned ix = 0; ix != pending_imports->length (); ix++)
	{
	  module_state *module = (*pending_imports)[ix];
	  if (module->visited_p)
	    {
	      module->visited_p = false;
	      gcc_checking_assert (!module->filename);

	      module->set_filename (*r_iter);
	      ++r_iter;
	    }
	}
    }

  dump.pop (n);

  timevar_stop (TV_MODULE_MAPPER);
}

/* We've just lexed a module-specific control line for MODULE.  Mark
   the module as a direct import, and possibly load up its macro
   state.  Returns the primary module, if this is a module
   declaration.  */
/* Perhaps we should offer a preprocessing mode where we read the
   directives from the header unit, rather than require the header's
   CMI.  */

module_state *
preprocess_module (module_state *module, location_t from_loc,
		   bool in_purview, bool is_import, bool is_export,
		   cpp_reader *reader)
{
  if (!is_import)
    {
      if (module->loc)
	/* It's already been mentioned, so ignore its module-ness.  */
	is_import = true;
      else
	{
	  /* Record it is the module.  */
	  module->module_p = true;
	  if (is_export)
	    {
	      module->exported_p = true;
	      module->interface_p = true;
	    }
	}
    }

  if (module->directness < MD_DIRECT + in_purview)
    {
      /* Mark as a direct import.  */
      module->directness = module_directness (MD_DIRECT + in_purview);

      /* Set the location to be most informative for users.  */
      from_loc = ordinary_loc_of (line_table, from_loc);
      if (module->loadedness != ML_NONE)
	linemap_module_reparent (line_table, module->loc, from_loc);
      else
	{
	  module->loc = from_loc;
	  if (!module->flatname)
	    module->set_flatname ();
	}
    }

  auto desired = ML_CONFIG;
  if (is_import
      && module->is_header ()
      && (!cpp_get_options (reader)->preprocessed
	  || cpp_get_options (reader)->directives_only))
    /* We need preprocessor state now.  */
    desired = ML_PREPROCESSOR;

  if (!is_import || module->loadedness < desired)
    {
      vec_safe_push (pending_imports, module);

      if (desired == ML_PREPROCESSOR)
	{
	  unsigned n = dump.push (NULL);

	  dump () && dump ("Reading %M preprocessor state", module);
	  name_pending_imports (reader);

	  /* Preserve the state of the line-map.  */
	  unsigned pre_hwm = LINEMAPS_ORDINARY_USED (line_table);

	  /* We only need to close the span, if we're going to emit a
	     CMI.  But that's a little tricky -- our token scanner
	     needs to be smarter -- and this isn't much state.
	     Remember, we've not parsed anything at this point, so
	     our module state flags are inadequate.  */
	  spans.maybe_init ();
	  spans.close ();

	  timevar_start (TV_MODULE_IMPORT);

	  /* Load the config of each pending import -- we must assign
	     module numbers monotonically.  */
	  for (unsigned ix = 0; ix != pending_imports->length (); ix++)
	    {
	      auto *import = (*pending_imports)[ix];
	      if (!(import->module_p
		    && (import->is_partition () || import->exported_p))
		  && import->loadedness == ML_NONE
		  && (import->is_header () || !flag_preprocess_only))
		{
		  unsigned n = dump.push (import);
		  import->do_import (reader, true);
		  dump.pop (n);
		}
	    }
	  vec_free (pending_imports);

	  /* Restore the line-map state.  */
	  spans.open (linemap_module_restore (line_table, pre_hwm));

	  /* Now read the preprocessor state of this particular
	     import.  */
	  if (module->loadedness == ML_CONFIG
	      && module->read_preprocessor (true))
	    module->import_macros ();

	  timevar_stop (TV_MODULE_IMPORT);

	  dump.pop (n);
	}
    }

  return is_import ? NULL : get_primary (module);
}

/* We've completed phase-4 translation.  Emit any dependency
   information for the not-yet-loaded direct imports, and fill in
   their file names.  We'll have already loaded up the direct header
   unit wavefront.  */

void
preprocessed_module (cpp_reader *reader)
{
  unsigned n = dump.push (NULL);

  dump () && dump ("Completed phase-4 (tokenization) processing");

  name_pending_imports (reader);
  vec_free (pending_imports);

  spans.maybe_init ();
  spans.close ();

  using iterator = hash_table<module_state_hash>::iterator;
  if (mkdeps *deps = cpp_get_deps (reader))
    {
      /* Walk the module hash, informing the dependency machinery.  */
      iterator end = modules_hash->end ();
      for (iterator iter = modules_hash->begin (); iter != end; ++iter)
	{
	  module_state *module = *iter;

	  if (module->is_direct ())
	    {
	      if (module->is_module ()
		  && (module->is_interface () || module->is_partition ()))
		deps_add_module_target (deps, module->get_flatname (),
					maybe_add_cmi_prefix (module->filename),
					module->is_header());
	      else
		deps_add_module_dep (deps, module->get_flatname ());
	    }
	}
    }

  if (flag_header_unit && !flag_preprocess_only)
    {
      /* Find the main module -- remember, it's not yet in the module
	 array.  */
      iterator end = modules_hash->end ();
      for (iterator iter = modules_hash->begin (); iter != end; ++iter)
	{
	  module_state *module = *iter;
	  if (module->is_module ())
	    {
	      declare_module (module, cpp_main_loc (reader), true, NULL, reader);
	      break;
	    }
	}
    }

  dump.pop (n);
}

/* VAL is a global tree, add it to the global vec if it is
   interesting.  Add some of its targets, if they too are
   interesting.  We do not add identifiers, as they can be re-found
   via the identifier hash table.  There is a cost to the number of
   global trees.  */

static int
maybe_add_global (tree val, unsigned &crc)
{
  int v = 0;

  if (val && !(identifier_p (val) || TREE_VISITED (val)))
    {
      TREE_VISITED (val) = true;
      crc = crc32_unsigned (crc, fixed_trees->length ());
      vec_safe_push (fixed_trees, val);
      v++;

      if (CODE_CONTAINS_STRUCT (TREE_CODE (val), TS_TYPED))
	v += maybe_add_global (TREE_TYPE (val), crc);
      if (CODE_CONTAINS_STRUCT (TREE_CODE (val), TS_TYPE_COMMON))
	v += maybe_add_global (TYPE_NAME (val), crc);
    }

  return v;
}

/* Initialize module state.  Create the hash table, determine the
   global trees.  Create the module for current TU.  */

void
init_modules (cpp_reader *reader)
{
  /* PCH should not be reachable because of lang-specs, but the
     user could have overriden that.  */
  if (pch_file)
    fatal_error (input_location,
		 "C++ modules are incompatible with precompiled headers");

  if (cpp_get_options (reader)->traditional)
    fatal_error (input_location,
		 "C++ modules are incompatible with traditional preprocessing");

  if (flag_preprocess_only)
    {
      cpp_options *cpp_opts = cpp_get_options (reader);
      if (flag_no_output
	  || (cpp_opts->deps.style != DEPS_NONE
	      && !cpp_opts->deps.need_preprocessor_output))
	{
	  warning (0, flag_dump_macros == 'M'
		   ? G_("macro debug output may be incomplete with modules")
		   : G_("module dependencies require preprocessing"));
	  if (cpp_opts->deps.style != DEPS_NONE)
	    inform (input_location, "you should use the %<-%s%> option",
		    cpp_opts->deps.style == DEPS_SYSTEM ? "MD" : "MMD");
	}
    }

  /* :: is always exported.  */
  DECL_MODULE_EXPORT_P (global_namespace) = true;

  modules_hash = hash_table<module_state_hash>::create_ggc (31);
  vec_safe_reserve (modules, 20);

  /* Create module for current TU.  */
  module_state *current
    = new (ggc_alloc<module_state> ()) module_state (NULL_TREE, NULL, false);
  current->mod = 0;
  bitmap_set_bit (current->imports, 0);
  modules->quick_push (current);

  gcc_checking_assert (!fixed_trees);

  headers = BITMAP_GGC_ALLOC ();

  if (note_includes)
    /* Canonicalize header names.  */
    for (unsigned ix = 0; ix != note_includes->length (); ix++)
      {
	const char *hdr = (*note_includes)[ix];
	size_t len = strlen (hdr);

	bool system = hdr[0] == '<';
	bool user = hdr[0] == '"';
	bool delimed = system || user;

	if (len <= (delimed ? 2 : 0)
	    || (delimed && hdr[len-1] != (system ? '>' : '"')))
	  error ("invalid header name %qs", hdr);

	hdr = canonicalize_header_name (delimed ? reader : NULL,
					0, !delimed, hdr, len);
	char *path = XNEWVEC (char, len + 1);
	memcpy (path, hdr, len);
	path[len] = 0;

	(*note_includes)[ix] = path;
      }

  if (note_cmis)
    /* Canonicalize & mark module names.  */
    for (unsigned ix = 0; ix != note_cmis->length (); ix++)
      {
	const char *name = (*note_cmis)[ix];
	size_t len = strlen (name);

	bool is_system = name[0] == '<';
	bool is_user = name[0] == '"';
	bool is_pathname = false;
	if (!(is_system || is_user))
	  for (unsigned ix = len; !is_pathname && ix--;)
	    is_pathname = IS_DIR_SEPARATOR (name[ix]);
	if (is_system || is_user || is_pathname)
	  {
	    if (len <= (is_pathname ? 0 : 2)
		|| (!is_pathname && name[len-1] != (is_system ? '>' : '"')))
	      {
		error ("invalid header name %qs", name);
		continue;
	      }
	    else
	      name = canonicalize_header_name (is_pathname ? nullptr : reader,
					       0, is_pathname, name, len);
	  }
	if (auto module = get_module (name))
	  module->inform_cmi_p = 1;
	else
	  error ("invalid module name %qs", name);
      }

  dump.push (NULL);

  /* Determine lazy handle bound.  */
  {
    unsigned limit = 1000;
#if HAVE_GETRLIMIT
    struct rlimit rlimit;
    if (!getrlimit (RLIMIT_NOFILE, &rlimit))
      {
	lazy_hard_limit = (rlimit.rlim_max < 1000000
			   ? unsigned (rlimit.rlim_max) : 1000000);
	lazy_hard_limit = (lazy_hard_limit > LAZY_HEADROOM
			   ? lazy_hard_limit - LAZY_HEADROOM : 0);
	if (rlimit.rlim_cur < limit)
	  limit = unsigned (rlimit.rlim_cur);
      }
#endif
    limit = limit > LAZY_HEADROOM ? limit - LAZY_HEADROOM : 1;

    if (unsigned parm = param_lazy_modules)
      {
	if (parm <= limit || !lazy_hard_limit || !try_increase_lazy (parm))
	  lazy_limit = parm;
      }
    else
      lazy_limit = limit;
  }

  if (dump ())
    {
      verstr_t ver;
      version2string (MODULE_VERSION, ver);
      dump ("Source: %s", main_input_filename);
      dump ("Compiler: %s", version_string);
      dump ("Modules: %s", ver);
      dump ("Checking: %s",
#if CHECKING_P
	    "checking"
#elif ENABLE_ASSERT_CHECKING
	    "asserting"
#else
	    "release"
#endif
	    );
      dump ("Compiled by: "
#ifdef __GNUC__
	    "GCC %d.%d, %s", __GNUC__, __GNUC_MINOR__,
#ifdef __OPTIMIZE__
	    "optimizing"
#else
	    "not optimizing"
#endif
#else
	    "not GCC"
#endif
	    );
      dump ("Reading: %s", MAPPED_READING ? "mmap" : "fileio");
      dump ("Writing: %s", MAPPED_WRITING ? "mmap" : "fileio");
      dump ("Lazy limit: %u", lazy_limit);
      dump ("Lazy hard limit: %u", lazy_hard_limit);
      dump ("");
    }

  /* Construct the global tree array.  This is an array of unique
     global trees (& types).  Do this now, rather than lazily, as
     some global trees are lazily created and we don't want that to
     mess with our syndrome of fixed trees.  */
  unsigned crc = 0;
  vec_alloc (fixed_trees, 200);

  dump () && dump ("+Creating globals");
  /* Insert the TRANSLATION_UNIT_DECL.  */
  TREE_VISITED (DECL_CONTEXT (global_namespace)) = true;
  fixed_trees->quick_push (DECL_CONTEXT (global_namespace));
  for (unsigned jx = 0; global_tree_arys[jx].first; jx++)
    {
      const tree *ptr = global_tree_arys[jx].first;
      unsigned limit = global_tree_arys[jx].second;

      for (unsigned ix = 0; ix != limit; ix++, ptr++)
	{
	  !(ix & 31) && dump ("") && dump ("+\t%u:%u:", jx, ix);
	  unsigned v = maybe_add_global (*ptr, crc);
	  dump () && dump ("+%u", v);
	}
    }
  global_crc = crc32_unsigned (crc, fixed_trees->length ());
  dump ("") && dump ("Created %u unique globals, crc=%x",
		     fixed_trees->length (), global_crc);
  for (unsigned ix = fixed_trees->length (); ix--;)
    TREE_VISITED ((*fixed_trees)[ix]) = false;

  dump.pop (0);

  if (!flag_module_lazy)
    /* Get the mapper now, if we're not being lazy.  */
    get_mapper (cpp_main_loc (reader));

  if (!flag_preprocess_only)
    {
      pending_table = new pending_map_t (EXPERIMENT (1, 400));
      entity_map = new entity_map_t (EXPERIMENT (1, 400));
      vec_safe_reserve (entity_ary, EXPERIMENT (1, 400));
    }

#if CHECKING_P
  note_defs = note_defs_table_t::create_ggc (1000);
#endif

  if (flag_header_unit && cpp_get_options (reader)->preprocessed)
    begin_header_unit (reader);

  /* Collect here to make sure things are tagged correctly (when
     aggressively GC'd).  */
  ggc_collect ();
}

/* If NODE is a deferred macro, load it.  */

static int
load_macros (cpp_reader *reader, cpp_hashnode *node, void *)
{
  location_t main_loc
    = MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0));

  if (cpp_user_macro_p (node)
      && !node->value.macro)
    {
      cpp_macro *macro = cpp_get_deferred_macro (reader, node, main_loc);
      dump () && dump ("Loaded macro #%s %I",
		       macro ? "define" : "undef", identifier (node));
    }

  return 1;
}

/* At the end of tokenizing, we no longer need the macro tables of
   imports.  But the user might have requested some checking.  */

void
maybe_check_all_macros (cpp_reader *reader)
{
  if (!warn_imported_macros)
    return;

  /* Force loading of any remaining deferred macros.  This will
     produce diagnostics if they are ill-formed.  */
  unsigned n = dump.push (NULL);
  cpp_forall_identifiers (reader, load_macros, NULL);
  dump.pop (n);
}

/* Write the CMI, if we're a module interface.  */

void
finish_module_processing (cpp_reader *reader)
{
  if (header_module_p ())
    module_kind &= ~MK_EXPORTING;

  if (!modules || !(*modules)[0]->name)
    {
      if (flag_module_only)
	warning (0, "%<-fmodule-only%> used for non-interface");
    }
  else if (!flag_syntax_only)
    {
      int fd = -1;
      int e = ENOENT;

      timevar_start (TV_MODULE_EXPORT);

      /* Force a valid but empty line map at the end.  This simplifies
	 the line table preparation and writing logic.  */
      linemap_add (line_table, LC_ENTER, false, "", 0);

      /* We write to a tmpname, and then atomically rename.  */
      const char *path = NULL;
      char *tmp_name = NULL;
      module_state *state = (*modules)[0];

      unsigned n = dump.push (state);
      state->announce ("creating");
      if (state->filename)
	{
	  size_t len = 0;
	  path = maybe_add_cmi_prefix (state->filename, &len);
	  tmp_name = XNEWVEC (char, len + 3);
	  memcpy (tmp_name, path, len);
	  strcpy (&tmp_name[len], "~");

	  if (!errorcount)
	    for (unsigned again = 2; ; again--)
	      {
		fd = open (tmp_name,
			   O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY,
			   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
		e = errno;
		if (fd >= 0 || !again || e != ENOENT)
		  break;
		create_dirs (tmp_name);
	      }
	  if (note_module_cmi_yes || state->inform_cmi_p)
	    inform (state->loc, "writing CMI %qs", path);
	  dump () && dump ("CMI is %s", path);
	}

      if (errorcount)
	warning_at (state->loc, 0, "not writing module %qs due to errors",
		    state->get_flatname ());
      else
	{
	  elf_out to (fd, e);
	  if (to.begin ())
	    {
	      auto loc = input_location;
	      /* So crashes finger-point the module decl.  */
	      input_location = state->loc;
	      state->write (&to, reader);
	      input_location = loc;
	    }
	  if (to.end ())
	    {
	      /* Some OS's do not replace NEWNAME if it already
		 exists.  This'll have a race condition in erroneous
		 concurrent builds.  */
	      unlink (path);
	      if (rename (tmp_name, path))
		{
		  dump () && dump ("Rename ('%s','%s') errno=%u", errno);
		  to.set_error (errno);
		}
	    }

	  if (to.get_error ())
	    {
	      error_at (state->loc, "failed to write compiled module: %s",
			to.get_error (state->filename));
	      state->note_cmi_name ();
	    }
	}

      if (!errorcount)
	{
	  auto *mapper = get_mapper (cpp_main_loc (reader));

	  mapper->ModuleCompiled (state->get_flatname ());
	}
      else if (path)
	{
	  /* We failed, attempt to erase all evidence we even tried.  */
	  unlink (tmp_name);
	  unlink (path);
	  XDELETEVEC (tmp_name);
	}

      dump.pop (n);
      timevar_stop (TV_MODULE_EXPORT);

      ggc_collect ();
    }

  if (modules)
    {
      unsigned n = dump.push (NULL);
      dump () && dump ("Imported %u modules", modules->length () - 1);
      dump () && dump ("Containing %u clusters", available_clusters);
      dump () && dump ("Loaded %u clusters (%u%%)", loaded_clusters,
		       (loaded_clusters * 100 + available_clusters / 2) /
		       (available_clusters + !available_clusters));
      dump.pop (n);
    }

  if (modules && !header_module_p ())
    {
      /* Determine call_init_p.  We need the same bitmap allocation
         scheme as for the imports member.  */
      function_depth++; /* Disable GC.  */
      bitmap indirect_imports (BITMAP_GGC_ALLOC ());

      /* Because indirect imports are before their direct import, and
	 we're scanning the array backwards, we only need one pass!  */
      for (unsigned ix = modules->length (); --ix;)
	{
	  module_state *import = (*modules)[ix];

	  if (!import->is_header ()
	      && !bitmap_bit_p (indirect_imports, ix))
	    {
	      /* Everything this imports is therefore indirectly
		 imported.  */
	      bitmap_ior_into (indirect_imports, import->imports);
	      /* We don't have to worry about the self-import bit,
		 because of the single pass.  */

	      import->call_init_p = true;
	      num_init_calls_needed++;
	    }
	}
      function_depth--;
    }
}

void
fini_modules ()
{
  /* We're done with the macro tables now.  */
  vec_free (macro_exports);
  vec_free (macro_imports);
  headers = NULL;

  /* We're now done with everything but the module names.  */
  set_cmi_repo (NULL);
  if (mapper)
    {
      timevar_start (TV_MODULE_MAPPER);
      module_client::close_module_client (0, mapper);
      mapper = nullptr;
      timevar_stop (TV_MODULE_MAPPER);
    }
  module_state_config::release ();

#if CHECKING_P
  note_defs = NULL;
#endif

  if (modules)
    for (unsigned ix = modules->length (); --ix;)
      if (module_state *state = (*modules)[ix])
	state->release ();

  /* No need to lookup modules anymore.  */
  modules_hash = NULL;

  /* Or entity array.  We still need the entity map to find import numbers.  */
  vec_free (entity_ary);
  entity_ary = NULL;

  /* Or remember any pending entities.  */
  delete pending_table;
  pending_table = NULL;

  /* Or any attachments -- Let it go!  */
  delete attached_table;
  attached_table = NULL;

  /* Allow a GC, we've possibly made much data unreachable.  */
  ggc_collect ();
}

/* If CODE is a module option, handle it & return true.  Otherwise
   return false.  For unknown reasons I cannot get the option
   generation machinery to set fmodule-mapper or -fmodule-header to
   make a string type option variable.  */

bool
handle_module_option (unsigned code, const char *str, int)
{
  auto hdr = CMS_header;

  switch (opt_code (code))
    {
    case OPT_fmodule_mapper_:
      module_mapper_name = str;
      return true;

    case OPT_fmodule_header_:
      {
	if (!strcmp (str, "user"))
	  hdr = CMS_user;
	else if (!strcmp (str, "system"))
	  hdr = CMS_system;
	else
	  error ("unknown header kind %qs", str);
      }
      /* Fallthrough.  */

    case OPT_fmodule_header:
      flag_header_unit = hdr;
      flag_modules = 1;
      return true;

    case OPT_flang_info_include_translate_:
      vec_safe_push (note_includes, str);
      return true;

    case OPT_flang_info_module_cmi_:
      vec_safe_push (note_cmis, str);
      return true;

    default:
      return false;
    }
}

/* Set preprocessor callbacks and options for modules.  */

void
module_preprocess_options (cpp_reader *reader)
{
  gcc_checking_assert (!lang_hooks.preprocess_undef);
  if (modules_p ())
    {
      auto *cb = cpp_get_callbacks (reader);
      
      cb->translate_include = maybe_translate_include;
      cb->user_deferred_macro = module_state::deferred_macro;
      if (flag_header_unit)
	{
	  /* If the preprocessor hook is already in use, that
	     implementation will call the undef langhook.  */
	  if (cb->undef)
	    lang_hooks.preprocess_undef = module_state::undef_macro;
	  else
	    cb->undef = module_state::undef_macro;
	}
      auto *opt = cpp_get_options (reader);
      opt->module_directives = true;
      opt->main_search = cpp_main_search (flag_header_unit);
    }
}

#include "gt-cp-module.h"
