/* C++ modules.  Experimental!
   Copyright (C) 2017-2022 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_MODULE_EXPORT_P, DECL_MODULE_PURVIEW_P, DECL_MODULE_ATTACH_P
   and DECL_MODULE_IMPORT_P.  The first indicates whether it is
   exported, the second whether it is in module or header-unit
   purview.  The third indicates it is attached to the named module in
   whose purview it resides and the fourth indicates whether it was an
   import into this TU or not.  DECL_MODULE_ATTACH_P will be false for
   all decls in a header-unit, and for those in a named module inside
   a linkage declaration.

   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_MEMORY
#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)
{
  /* HT_NODE() expands to node->ident that HT_IDENT_TO_GCC_IDENT()
     then subtracts a nonzero constant, deriving a pointer to
     a different member than ident.  That's strictly undefined
     and detected by -Warray-bounds.  Suppress it.  See PR 101372.  */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
  return HT_IDENT_TO_GCC_IDENT (HT_NODE (const_cast<cpp_hashnode *> (node)));
#pragma GCC diagnostic pop
}

/* 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;
  char *grow (char *, unsigned needed) final override;
#if MAPPED_WRITING
  using allocator::shrink;
  void shrink (char *) final override;
#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 its 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 < ARRAY_SIZE (names));
  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 keyed to another entitity for ODR purposes.
   For example, at namespace scope, 'inline auto var = []{};', that
   lambda is keyed to 'var', and follows its ODRness.  */
typedef hash_map<tree, auto_vec<tree>> keyed_map_t;
static keyed_map_t *keyed_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_nttp_var,		/* NTTP_OBJECT VAR_DECL.  */

  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_keyed,     /* Found by key & 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)
  {
  }
};

/* Hashmap of merged duplicates.  Usually decls, but can contain
   BINFOs.  */
typedef hash_map<tree,uintptr_t,
		 simple_hashmap_traits<nodel_ptr_hash<tree_node>,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_attached);
  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;

/* Information about ordinary locations we stream out.  */
struct ord_loc_info
{
  const line_map_ordinary *src; // line map we're based on
  unsigned offset;	// offset to this line
  unsigned span;	// number of locs we span
  unsigned remap;	// serialization

  static int compare (const void *a_, const void *b_)
  {
    auto *a = static_cast<const ord_loc_info *> (a_);
    auto *b = static_cast<const ord_loc_info *> (b_);

    if (a->src != b->src)
      return a->src < b->src ? -1 : +1;

    // Ensure no overlap
    gcc_checking_assert (a->offset + a->span <= b->offset
			 || b->offset + b->span <= a->offset);

    gcc_checking_assert (a->offset != b->offset);
    return a->offset < b->offset ? -1 : +1;
  }
};
struct ord_loc_traits
{
  typedef ord_loc_info value_type;
  typedef value_type compare_type;

  static const bool empty_zero_p = false;

  static hashval_t hash (const value_type &v)
  {
    auto h = pointer_hash<const line_map_ordinary>::hash (v.src);
    return iterative_hash_hashval_t (v.offset, h);
  }
  static bool equal (const value_type &v, const compare_type p)
  {
    return v.src == p.src && v.offset == p.offset;
  }

  static void mark_empty (value_type &v)
  {
    v.src = nullptr;
  }
  static bool is_empty (value_type &v)
  {
    return !v.src;
  }

  static bool is_deleted (value_type &) { return false; }
  static void mark_deleted (value_type &) { gcc_unreachable (); }
  
  static void remove (value_type &) {}
};
/* Table keyed by ord_loc_info, used for noting.  */
static  hash_table<ord_loc_traits> *ord_loc_table;
/* Sorted vector, used for writing.  */
static vec<ord_loc_info> *ord_loc_remap;

/* Information about macro locations we stream out.  */
struct macro_loc_info
{
  const line_map_macro *src;    // original expansion
  unsigned remap;	  // serialization

  static int compare (const void *a_, const void *b_)
  {
    auto *a = static_cast<const macro_loc_info *> (a_);
    auto *b = static_cast<const macro_loc_info *> (b_);

    gcc_checking_assert (MAP_START_LOCATION (a->src)
			 != MAP_START_LOCATION (b->src));
    if (MAP_START_LOCATION (a->src) < MAP_START_LOCATION (b->src))
      return -1;
    else
      return +1;
  }
};
struct macro_loc_traits
{
  typedef macro_loc_info value_type;
  typedef const line_map_macro *compare_type;

  static const bool empty_zero_p = false;

  static hashval_t hash (compare_type p)
  {
    return pointer_hash<const line_map_macro>::hash (p);
  }
  static hashval_t hash (const value_type &v)
  {
    return hash (v.src);
  }
  static bool equal (const value_type &v, const compare_type p)
  {
    return v.src == p;
  }

  static void mark_empty (value_type &v)
  {
    v.src = nullptr;
  }
  static bool is_empty (value_type &v)
  {
    return !v.src;
  }

  static bool is_deleted (value_type &) { return false; }
  static void mark_deleted (value_type &) { gcc_unreachable (); }
  
  static void remove (value_type &) {}
};
/* Table keyed by line_map_macro, used for noting.  */
static  hash_table<macro_loc_traits> *macro_loc_table;
/* Sorted vector, used for writing.  */
static vec<macro_loc_info> *macro_loc_remap;

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

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

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

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

/********************************************************************/
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; // [lwm,num)

  /* 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 active_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_begin (elf_out *to, cpp_reader *,
		    module_state_config &, unsigned &crc);
  void write_end (elf_out *to, cpp_reader *,
		  module_state_config &, unsigned &crc);
  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);
  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 [MSC_HWM], 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:
  void write_init_maps ();
  range_t write_prepare_maps (module_state_config *, bool);
  bool read_prepare_maps (const module_state_config *);

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

 private:
  void write_define (bytes_out &, const cpp_macro *);
  cpp_macro *read_define (bytes_in &, cpp_reader *) const;
  vec<cpp_hashnode *> *prepare_macros (cpp_reader *);
  unsigned write_macros (elf_out *to, vec<cpp_hashnode *> *, 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 bool note_location (location_t);
  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;
  active_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;

/* 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) == CONCEPT_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 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 (CLASS_TYPE_P (frnd)
	      && 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)
		  && !(TREE_STATIC (t)
		       && DECL_FUNCTION_SCOPE_P (t)
		       && DECL_DECLARED_INLINE_P (DECL_CONTEXT (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);
      WB (t->decl_common.decl_not_flexarray);
    }

  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);
      RB (t->decl_common.decl_not_flexarray);
    }

  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, (so
     we know which decls to write).  But when we import them we do not
     want to mark them as in module purview.  */
  WB (lang->u.base.module_purview_p && !header_module_p ());
  WB (lang->u.base.module_attach_p);
  if (VAR_OR_FUNCTION_DECL_P (t))
    WB (lang->u.base.module_keyed_decls_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);
  RB (lang->u.base.module_attach_p);
  if (VAR_OR_FUNCTION_DECL_P (t))
    RB (lang->u.base.module_keyed_decls_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))
    {
      if (code == ENUMERAL_TYPE)
	{
	  /* These fields get set even for opaque enums that lack a
	     definition, so we stream them directly for each ENUMERAL_TYPE.
	     We stream TYPE_VALUES as part of the definition.  */
	  WT (t->type_non_common.maxval);
	  WT (t->type_non_common.minval);
	}
      /* Records and unions hold FIELDS, VFIELD & BINFO on these
	 things.  */
      else if (!RECORD_OR_UNION_CODE_P (code))
	{
	  // 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);

      if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
	WT (lookup_explicit_specifier (t));
      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 : tsi_range (t))
	if (stmt)
	  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))
    {
      if (code == ENUMERAL_TYPE)
	{
	  /* These fields get set even for opaque enums that lack a
	     definition, so we stream them directly for each ENUMERAL_TYPE.
	     We stream TYPE_VALUES as part of the definition.  */
	  RT (t->type_non_common.maxval);
	  RT (t->type_non_common.minval);
	}
      /* Records and unions hold FIELDS, VFIELD & BINFO on these
	 things.  */
      else if (!RECORD_OR_UNION_CODE_P (code))
	{
	  /* 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)))
	memcpy (TREE_REAL_CST_PTR (t), 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);

	if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
	  {
	    tree spec;
	    RT (spec);
	    store_explicit_specifier (t, spec);
	  }
      }
      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 its
   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_attached = false;

	      tree not_tmpl = STRIP_TEMPLATE (o);
	      if (DECL_LANG_SPECIFIC (not_tmpl)
		  && DECL_MODULE_ATTACH_P (not_tmpl))
		is_attached = true;

	      b (is_attached);
	    }
	  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 ti = get_template_info (inner);
	      tree_node (TI_TEMPLATE (ti));
	      tree_node (TI_ARGS (ti));
	    }
	}
      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_KEYED_DECLS_P (inner)
      && !is_key_order ())
    {
      /* Stream the keyed entities.  */
      auto *attach_vec = keyed_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_attached = 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_attached = 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_attached);
  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_KEYED_DECLS_P (inner))
    {
      /* Read and maybe install the attached entities.  */
      bool existed;
      auto &set = keyed_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);

      /* Add to specialization tables now that constraints etc are
	 added.  */
      if (mk == MK_partial)
	{
	  bool is_type = TREE_CODE (inner) == TYPE_DECL;
	  spec.spec = is_type ? type : inner;
	  add_mergeable_specialization (!is_type, false,
					&spec, decl, spec_flags);
	}
      else if (mk & MK_template_mask)
	{
	  bool is_type = !(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;
	}

      if (DECL_NTTP_OBJECT_P (decl))
	{
	  /* A NTTP parm object.  */
	  if (streaming_p ())
	    i (tt_nttp_var);
	  tree_node (tparm_object_argument (decl));
	  tree_node (DECL_NAME (decl));
	  int tag = insert (decl);
	  if (streaming_p ())
	    dump (dumper::TREE)
	      && dump ("Wrote nttp object:%d %N", tag, DECL_NAME (decl));
	  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 DEPENDENT_OPERATOR_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 TRAIT_TYPE:
      tree_node (TRAIT_TYPE_KIND_RAW (type));
      tree_node (TRAIT_TYPE_TYPE1 (type));
      tree_node (TRAIT_TYPE_TYPE2 (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));
      tree_node (PACK_EXPANSION_EXTRA_ARGS (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 DEPENDENT_OPERATOR_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 TRAIT_TYPE:
	    {
	      tree kind = tree_node ();
	      tree type1 = tree_node ();
	      tree type2 = tree_node ();
	      if (!get_overrun ())
		{
		  res = cxx_make_type (TRAIT_TYPE);
		  TRAIT_TYPE_KIND_RAW (res) = kind;
		  TRAIT_TYPE_TYPE1 (res) = type1;
		  TRAIT_TYPE_TYPE2 (res) = type2;
		  SET_TYPE_STRUCTURAL_EQUALITY (res);
		}
	    }
	    break;

	  case TYPE_ARGUMENT_PACK:
	    if (!get_overrun ())
	      {
		tree pack = cxx_make_type (TYPE_ARGUMENT_PACK);
		ARGUMENT_PACK_ARGS (pack) = res;
		res = pack;
	      }
	    break;

	  case TYPE_PACK_EXPANSION:
	    {
	      bool local = u ();
	      tree param_packs = tree_node ();
	      tree extra_args = tree_node ();
	      if (!get_overrun ())
		{
		  tree expn = cxx_make_type (TYPE_PACK_EXPANSION);
		  SET_TYPE_STRUCTURAL_EQUALITY (expn);
		  PACK_EXPANSION_PATTERN (expn) = res;
		  PACK_EXPANSION_PARAMETER_PACKS (expn) = param_packs;
		  PACK_EXPANSION_EXTRA_ARGS (expn) = extra_args;
		  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_nttp_var:
      /* An NTTP object. */
      {
	tree init = tree_node ();
	tree name = tree_node ();
	if (!get_overrun ())
	  {
	    res = get_template_parm_object (init, name);
	    int tag = insert (res);
	    dump (dumper::TREE)
	      && dump ("Created nttp object:%d %N", tag, name);
	  }
      }
      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));
      for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
	{
	  tree parm = TREE_VEC_ELT (vec, ix);
	  tree 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_TYPE (vec) = tree_node ();
      for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
	{
	  tree parm = TREE_VEC_ELT (vec, ix);
	  tree 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);
    }

  if (!streaming_p ())
    {
      /* We must walk contract attrs so the dependency graph is complete. */
      for (tree contract = DECL_CONTRACTS (fn);
	  contract;
	  contract = CONTRACT_CHAIN (contract))
	tree_node (contract);
    }

  /* Write a reference to contracts pre/post functions, if any, to avoid
     regenerating them in importers.  */
  tree_node (DECL_PRE_FN (fn));
  tree_node (DECL_POST_FN (fn));
}

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

  /* Reload references to contract functions, if any.  */
  tree pre_fn = tree_node ();
  tree post_fn = tree_node ();
  set_contract_functions (fn, pre_fn, post_fn);

  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 and NAMESPACE_DECLs cannot have DECL_TEMPLATE_INFO --
	     this isn't permitting them to have one.   */
	  gcc_checking_assert (TREE_CODE (decl) == USING_DECL
			       || TREE_CODE (decl) == NAMESPACE_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_KEYED_DECLS_P (scope))
		  {
		    mk = MK_keyed;
		    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_keyed:
	  {
	    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 = keyed_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 keyed-to decl as the 'name'.  */
	    name = scope;
	    key.index = ix;
	  }
	  break;

	case MK_partial:
	  {
	    tree ti = get_template_info (inner);
	    key.constraints = get_constraints (inner);
	    key.ret = TI_TEMPLATE (ti);
	    key.args = TI_ARGS (ti);
	  }
	  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 its
   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))
		/* Reject if one is a different member of a
		   guarded/pre/post fn set.  */
		&& (!flag_contracts
		    || (DECL_IS_PRE_FN_P (d_inner)
			== DECL_IS_PRE_FN_P (m_inner)))
		&& (!flag_contracts
		    || (DECL_IS_POST_FN_P (d_inner)
			== DECL_IS_POST_FN_P (m_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_attached)
{
  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);
	      tree ti = get_template_info (tmpl);
	      if (template_args_equal (key.args, TI_ARGS (ti))
		  && 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_keyed)
	      {
		if (DECL_LANG_SPECIFIC (name)
		    && VAR_OR_FUNCTION_DECL_P (name)
		    && DECL_MODULE_KEYED_DECLS_P (name))
		  if (auto *set = keyed_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_attached
		     && !(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_attached, &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_attached)
		      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_attached && !(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))
	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);

  if (streaming_p ())
    u (cexpr != nullptr);
  if (cexpr)
    {
      chained_decls (cexpr->parms);
      tree_node (cexpr->result);
      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 (u ())
    {
      cexpr.parms = chained_decls ();
      cexpr.result = tree_node ();
      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 its 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))
	    /* If we're marking a class template definition, then
	       this'll contain the width (as set by grokbitfield)
	       instead of a decl.  */
	    if (DECL_P (repr))
	      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 *, 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);
		  if (!ANON_AGGR_TYPE_P (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) == FIELD_DECL
		  && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
		ANON_AGGR_TYPE_FIELD
		  (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = 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 (CLASS_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));
  /* Note that we stream TYPE_MIN/MAX_VALUE directly as part of the
     ENUMERAL_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 ();

  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;
      /* Note that we stream TYPE_MIN/MAX_VALUE directly as part of the
	 ENUMERAL_TYPE.  */

      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))
	    break;
	      
	  new_decl = maybe_duplicate (new_decl);

	  if (!cp_tree_equal (DECL_INITIAL (known_decl),
			      DECL_INITIAL (new_decl)))
	    break;
	}

      if (known || values)
	{
	  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)
	  || (VAR_P (decl)
	      && DECL_LANG_SPECIFIC (decl)
	      && DECL_USE_TEMPLATE (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 = get_template_info (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 (TREE_CODE (decl) == VAR_DECL && DECL_NTTP_OBJECT_P (decl))
	/* Ignore NTTP objects.  */
	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.cc 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 (STRIP_TEMPLATE (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)
		{
		  module->note_location (DECL_SOURCE_LOCATION (decl));
		  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);
  else
    {
      if (parent)
	parent->mangle (include_partition);
      if (include_partition || !is_partition ()) 
	{
	  // Partitions are significant for global initializer
	  // functions
	  bool partition = is_partition () && !parent->is_partition ();
	  subst = mangle_module_component (name, partition);
	  substs.safe_push (this);
	}
    }
}

void
mangle_module (int mod, bool include_partition)
{
  module_state *imp = (*modules)[mod];

  gcc_checking_assert (!imp->is_header ());

  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)
{
  bytes_out readme (to);

  readme.begin (false);

  readme.printf ("GNU C++ %s",
		 is_header () ? "header unit"
		 : !is_partition () ? "primary interface"
		 : is_interface () ? "interface partition"
		 : "internal 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;
}

/* 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 loc_range_bits;
  unsigned active_init;

public:
  module_state_config ()
    :dialect_str (get_dialect ()),
     num_imports (0), num_partitions (0), num_entities (0),
     ordinary_locs (0), macro_locs (0), loc_range_bits (0),
     active_init (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" : "",
		      flag_contracts ? "/contracts" : "",
		      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.cc'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 its 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.first + 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.first)
	{
	  pos += half + 1;
	  len = len - (half + 1);
	}
      else if (loc >= probe->macro_locs.first + probe->macro_locs.second)
	len = half;
      else
	return probe;
    }

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

/* Note that LOC will need writing.  This allows us to prune locations
   that are not needed.  */

bool
module_state::note_location (location_t loc)
{
  bool added = false;
  if (!macro_loc_table && !ord_loc_table)
    ;
  else if (loc < RESERVED_LOCATION_COUNT)
    ;
  else if (IS_ADHOC_LOC (loc))
    {
      location_t locus = get_location_from_adhoc_loc (line_table, loc);
      note_location (locus);
      source_range range = get_range_from_loc (line_table, loc);
      if (range.m_start != locus)
	note_location (range.m_start);
      note_location (range.m_finish);
    }
  else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
    {
      if (spans.macro (loc))
	{
	  const line_map *map = linemap_lookup (line_table, loc);
	  const line_map_macro *mac_map = linemap_check_macro (map);
	  hashval_t hv = macro_loc_traits::hash (mac_map);
	  macro_loc_info *slot
	    = macro_loc_table->find_slot_with_hash (mac_map, hv, INSERT);
	  if (!slot->src)
	    {
	      slot->src = mac_map;
	      slot->remap = 0;
	      // Expansion locations could themselves be from a
	      // macro, we need to note them all.
	      note_location (mac_map->expansion);
	      gcc_checking_assert (mac_map->n_tokens);
	      location_t tloc = UNKNOWN_LOCATION;
	      for (unsigned ix = mac_map->n_tokens * 2; ix--;)
		if (mac_map->macro_locations[ix] != tloc)
		  {
		    tloc = mac_map->macro_locations[ix];
		    note_location (tloc);
		  }
	      added = true;
	    }
	}				       
    }
  else if (IS_ORDINARY_LOC (loc))
    {
      if (spans.ordinary (loc))
	{
	  const line_map *map = linemap_lookup (line_table, loc);
	  const line_map_ordinary *ord_map = linemap_check_ordinary (map);
	  ord_loc_info lkup;
	  lkup.src = ord_map;
	  lkup.span = 1 << ord_map->m_column_and_range_bits;
	  lkup.offset = (loc - MAP_START_LOCATION (ord_map)) & ~(lkup.span - 1);
	  lkup.remap = 0;
	  ord_loc_info *slot = (ord_loc_table->find_slot_with_hash
				(lkup, ord_loc_traits::hash (lkup), INSERT));
	  if (!slot->src)
	    {
	      *slot = lkup;
	      added = true;
	    }
	}
    }
  else
    gcc_unreachable ();
  return added;
}

/* 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 ())
    {
      note_location (loc);
      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);
      unsigned discriminator = get_discriminator_from_adhoc_loc (line_table, loc);
      sec.u (discriminator);
    }
  else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
    {
      const macro_loc_info *info = nullptr;
      unsigned offset = 0;
      if (unsigned hwm = macro_loc_remap->length ())
	{
	  info = macro_loc_remap->begin ();
	  while (hwm != 1)
	    {
	      unsigned mid = hwm / 2;
	      if (MAP_START_LOCATION (info[mid].src) <= loc)
		{
		  info += mid;
		  hwm -= mid;
		}
	      else
		hwm = mid;
	    }
	  offset = loc - MAP_START_LOCATION (info->src);
	  if (offset > info->src->n_tokens)
	    info = nullptr;
	}

      gcc_checking_assert (bool (info) == bool (spans.macro (loc)));

      if (info)
	{
	  offset += info->remap;
	  sec.u (LK_MACRO);
	  sec.u (offset);
	  dump (dumper::LOCATION)
	    && dump ("Macro location %u output %u", loc, offset);
	}
      else if (const module_state *import = module_for_macro_loc (loc))
	{
	  unsigned off = loc - import->macro_locs.first;
	  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))
    {
      const ord_loc_info *info = nullptr;
      unsigned offset = 0;
      if (unsigned hwm = ord_loc_remap->length ())
	{
	  info = ord_loc_remap->begin ();
	  while (hwm != 1)
	    {
	      unsigned mid = hwm / 2;
	      if (MAP_START_LOCATION (info[mid].src) + info[mid].offset <= loc)
		{
		  info += mid;
		  hwm -= mid;
		}
	      else
		hwm = mid;
	    }
	  offset = loc - MAP_START_LOCATION (info->src) - info->offset;
	  if (offset > info->span)
	    info = nullptr;
	}

      gcc_checking_assert (bool (info) == bool (spans.ordinary (loc)));

      if (info)
	{
	  offset += info->remap;
	  sec.u (LK_ORDINARY);
	  sec.u (offset);

	  dump (dumper::LOCATION)
	    && dump ("Ordinary location %u output %u", loc, offset);
	}
      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);
	unsigned discriminator = sec.u ();
	if (locus != loc && range.m_start != loc && range.m_finish != loc)
	  locus = get_combined_adhoc_loc (line_table, locus, range, NULL, discriminator);
      }
      break;

    case LK_MACRO:
      {
	unsigned off = sec.u ();

	if (macro_locs.second)
	  {
	    if (off < macro_locs.second)
	      locus = off + macro_locs.first;
	    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)
	  {
	    if (off < ordinary_locs.second)
	      locus = off + ordinary_locs.first;
	    else
	      sec.set_overrun ();
	  }
	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.second)
		   locus = import->loc;
		 else if (off < import->macro_locs.second)
		   locus = off + import->macro_locs.first;
		 else
		   sec.set_overrun ();
	       }
	     else
	       {
		 if (!import->ordinary_locs.second)
		   locus = import->loc;
		 else if (off < import->ordinary_locs.second)
		   locus = import->ordinary_locs.first + off;
		 else
		   sec.set_overrun ();
	       }
	   }
       }
       break;
    }

  return locus;
}

/* Allocate hash tables to record needed locations.  */

void
module_state::write_init_maps ()
{
  macro_loc_table = new hash_table<macro_loc_traits> (EXPERIMENT (1, 400));
  ord_loc_table = new hash_table<ord_loc_traits> (EXPERIMENT (1, 400));
}

/* Prepare the span adjustments.  We prune unneeded locations -- at
   this point every needed location must have been seen by
   note_location.  */

range_t
module_state::write_prepare_maps (module_state_config *cfg, bool has_partitions)
{
  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);

  range_t info {0, 0};

  // Sort the noted lines.
  vec_alloc (ord_loc_remap, ord_loc_table->size ());
  for (auto iter = ord_loc_table->begin (), end = ord_loc_table->end ();
       iter != end; ++iter)
    ord_loc_remap->quick_push (*iter);
  ord_loc_remap->qsort (&ord_loc_info::compare);

  // Note included-from maps.
  bool added = false;
  const line_map_ordinary *current = nullptr;
  for (auto iter = ord_loc_remap->begin (), end = ord_loc_remap->end ();
       iter != end; ++iter)
    if (iter->src != current)
      {
	current = iter->src;
	for (auto probe = current;
	     auto from = linemap_included_from (probe);
	     probe = linemap_check_ordinary (linemap_lookup (line_table, from)))
	  {
	    if (has_partitions)
	      {
		// Partition locations need to elide their module map
		// entry.
		probe
		  = linemap_check_ordinary (linemap_lookup (line_table, from));
		if (MAP_MODULE_P (probe))
		  from = linemap_included_from (probe);
	      }

	    if (!note_location (from))
	      break;
	    added = true;
	  }
      }
  if (added)
    {
      // Reconstruct the line array as we added items to the hash table.
      vec_free (ord_loc_remap);
      vec_alloc (ord_loc_remap, ord_loc_table->size ());
      for (auto iter = ord_loc_table->begin (), end = ord_loc_table->end ();
	   iter != end; ++iter)
	ord_loc_remap->quick_push (*iter);
      ord_loc_remap->qsort (&ord_loc_info::compare);
    }
  delete ord_loc_table;
  ord_loc_table = nullptr;

  // Merge (sufficiently) adjacent spans, and calculate remapping.
  constexpr unsigned adjacency = 2; // Allow 2 missing lines.
  auto begin = ord_loc_remap->begin (), end = ord_loc_remap->end ();
  auto dst = begin;
  unsigned offset = 0, range_bits = 0;
  ord_loc_info *base = nullptr;
  for (auto iter = begin; iter != end; ++iter)
    {    
      if (base && iter->src == base->src)
	{
	  if (base->offset + base->span +
	      ((adjacency << base->src->m_column_and_range_bits)
	       // If there are few c&r bits, allow further separation.
	       | (adjacency << 4))
	      >= iter->offset)
	    {
	      // Merge.
	      offset -= base->span;
	      base->span = iter->offset + iter->span - base->offset;
	      offset += base->span;
	      continue;
	    }
	}
      else if (range_bits < iter->src->m_range_bits)
	range_bits = iter->src->m_range_bits;

      offset += ((1u << iter->src->m_range_bits) - 1);
      offset &= ~((1u << iter->src->m_range_bits) - 1);
      iter->remap = offset;
      offset += iter->span;
      base = dst;
      *dst++ = *iter;
    }
  ord_loc_remap->truncate (dst - begin);

  info.first = ord_loc_remap->length ();
  cfg->ordinary_locs = offset;
  cfg->loc_range_bits = range_bits;
  dump () && dump ("Ordinary maps:%u locs:%u range_bits:%u",
		   info.first, cfg->ordinary_locs,
		   cfg->loc_range_bits);

  // Remap the macro locations.
  vec_alloc (macro_loc_remap, macro_loc_table->size ());
  for (auto iter = macro_loc_table->begin (), end = macro_loc_table->end ();
       iter != end; ++iter)
    macro_loc_remap->quick_push (*iter);
  delete macro_loc_table;
  macro_loc_table = nullptr;

  macro_loc_remap->qsort (&macro_loc_info::compare);
  offset = 0;
  for (auto iter = macro_loc_remap->begin (), end = macro_loc_remap->end ();
       iter != end; ++iter)
    {
      auto mac = iter->src;
      iter->remap = offset;
      offset += mac->n_tokens;
    }
  info.second = macro_loc_remap->length ();
  cfg->macro_locs = offset;

  dump () && dump ("Macro maps:%u locs:%u", info.second, cfg->macro_locs);

  dump.outdent ();

  // If we have no ordinary locs, we must also have no macro locs.
  gcc_checking_assert (cfg->ordinary_locs || !cfg->macro_locs);

  return info;
}

bool
module_state::read_prepare_maps (const module_state_config *cfg)
{
  location_t ordinary = line_table->highest_location + 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 & read the location maps. Not called if there are no
   locations.   */

void
module_state::write_ordinary_maps (elf_out *to, range_t &info,
				   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.  */
  const line_map_ordinary *current = nullptr;
  for (auto iter = ord_loc_remap->begin (), end = ord_loc_remap->end ();
       iter != end; ++iter)
    if (iter->src != current)
      {
	current = iter->src;
	const char *fname = ORDINARY_MAP_FILE_NAME (iter->src);

	/* We should never find a module linemap in an interval.  */
	gcc_checking_assert (!MAP_MODULE_P (iter->src));

	/* 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 *> (iter->src)->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);
    }

  sec.u (info.first);	/* Num maps.  */
  const ord_loc_info *base = nullptr;
  for (auto iter = ord_loc_remap->begin (), end = ord_loc_remap->end ();
       iter != end; ++iter)
    {
      dump (dumper::LOCATION)
	&& dump ("Span:%u ordinary [%u+%u,+%u)->[%u,+%u)",
		 iter - ord_loc_remap->begin (),
		 MAP_START_LOCATION (iter->src), iter->offset, iter->span,
		 iter->remap, iter->span);

      if (!base || iter->src != base->src)
	base = iter;
      sec.u (iter->offset - base->offset);
      if (base == iter)
	{
	  sec.u (iter->src->sysp);
	  sec.u (iter->src->m_range_bits);
	  sec.u (iter->src->m_column_and_range_bits - iter->src->m_range_bits);

	  const char *fname = ORDINARY_MAP_FILE_NAME (iter->src);
	  for (unsigned ix = 0; ix != filenames.length (); ix++)
	    if (filenames[ix] == fname)
	      {
		sec.u (ix);
		break;
	      }
	  unsigned line = ORDINARY_MAP_STARTING_LINE_NUMBER (iter->src);
	  line += iter->offset >> iter->src->m_column_and_range_bits;
	  sec.u (line);
	}
      sec.u (iter->remap);
      if (base == iter)
	{
	  /* 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 (iter->src);
	  gcc_checking_assert (from < MAP_START_LOCATION (iter->src));
	  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);
	}
    }

  filenames.release ();

  sec.end (to, to->name (MOD_SNAME_PFX ".olm"), crc_p);
  dump.outdent ();
}

void
module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p)
{
  dump () && dump ("Writing macro location maps");
  dump.indent ();

  bytes_out sec (to);
  sec.begin ();

  dump () && dump ("Macro maps:%u", info.second);
  sec.u (info.second);

  unsigned macro_num = 0;
  for (auto iter = macro_loc_remap->end (), begin = macro_loc_remap->begin ();
       iter-- != begin;)
    {
      auto mac = iter->src;
      sec.u (iter->remap);
      sec.u (mac->n_tokens);
      sec.cpp_node (mac->macro);
      write_location (sec, mac->expansion);
      const location_t *locs = mac->macro_locations;
      /* There are lots of identical runs.  */
      location_t prev = UNKNOWN_LOCATION;
      unsigned count = 0;
      unsigned runs = 0;
      for (unsigned jx = mac->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 ("Macro:%u %I %u/%u*2 locations [%u,%u)->%u",
		 macro_num, identifier (mac->macro),
		 runs, mac->n_tokens,
		 MAP_START_LOCATION (mac),
		 MAP_START_LOCATION (mac) + mac->n_tokens,
		 iter->remap);
      macro_num++;
    }
  gcc_assert (macro_num == info.second);

  sec.end (to, to->name (MOD_SNAME_PFX ".mlm"), crc_p);
  dump.outdent ();
}

bool
module_state::read_ordinary_maps (unsigned num_ord_locs, unsigned range_bits)
{
  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 ();
  dump () && dump ("Ordinary maps:%u, range_bits:%u", num_ordinary, range_bits);

  location_t offset = line_table->highest_location + 1;
  offset += ((1u << range_bits) - 1);
  offset &= ~((1u << range_bits) - 1);
  ordinary_locs.first = offset;

  bool propagated = spans.maybe_propagate (this, offset);
  line_map_ordinary *maps = static_cast<line_map_ordinary *>
    (line_map_new_raw (line_table, false, num_ordinary));

  const line_map_ordinary *base = nullptr;
  for (unsigned ix = 0; ix != num_ordinary && !sec.get_overrun (); ix++)
    {
      line_map_ordinary *map = &maps[ix];

      unsigned offset = sec.u ();
      if (!offset)
	{
	  map->reason = LC_RENAME;
	  map->sysp = sec.u ();
	  map->m_range_bits = sec.u ();
	  map->m_column_and_range_bits = sec.u () + map->m_range_bits;
	  unsigned fnum = sec.u ();
	  map->to_file = (fnum < filenames.length () ? filenames[fnum] : "");
	  map->to_line = sec.u ();
	  base = map;
	}
      else
	{
	  *map = *base;
	  map->to_line += offset >> map->m_column_and_range_bits;
	}
      unsigned remap = sec.u ();
      map->start_location = remap + ordinary_locs.first;
      if (base == map)
	{
	  /* Root the outermost map at our location.  */
	  ordinary_locs.second = remap;
	  location_t from = read_location (sec);
	  map->included_from = from != UNKNOWN_LOCATION ? from : loc;
	}
    }

  ordinary_locs.second = num_ord_locs;
  /* highest_location is the one handed out, not the next one to
     hand out.  */
  line_table->highest_location = ordinary_locs.first + 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 [%u,+%u)",
		   ordinary_locs.first, 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 (unsigned num_macro_locs)
{
  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 ();
  dump () && dump ("Macro maps:%u locs:%u", num_macros, num_macro_locs);

  bool propagated = spans.maybe_propagate (this,
					   line_table->highest_location + 1);

  location_t offset = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  macro_locs.second = num_macro_locs;
  macro_locs.first = offset - num_macro_locs;

  dump () && dump ("Macro loc delta %d", offset);
  dump () && dump ("Macro locations [%u,%u)",
		   macro_locs.first, macro_locs.second);

  for (unsigned ix = 0; ix != num_macros && !sec.get_overrun (); ix++)
    {
      unsigned offset = sec.u ();
      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;
      gcc_checking_assert (MAP_START_LOCATION (macro)
			   == offset + macro_locs.first);

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

  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)
{
  sec.u (macro->count);

  sec.b (macro->fun_like);
  sec.b (macro->variadic);
  sec.b (macro->syshdr);
  sec.bflush ();

  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];
      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) const
{
  unsigned count = sec.u ();
  /* We rely on knowing cpp_reader's hash table is ident_hash, and
     its 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 = read_location (sec);

  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 = read_location (sec);
      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;
}

/* Gather the macro definitions and undefinitions that we will need to
   write out.   */

vec<cpp_hashnode *> *
module_state::prepare_macros (cpp_reader *reader)
{
  vec<cpp_hashnode *> *macros;
  vec_alloc (macros, 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);

  // Note the locations.
  for (unsigned ix = macros->length (); ix--;)
    {
      cpp_hashnode *node = (*macros)[ix];
      macro_import::slot &slot = (*macro_imports)[node->deferred - 1][0];
      macro_export &mac = (*macro_exports)[slot.offset];

      if (IDENTIFIER_KEYWORD_P (identifier (node)))
	continue;

      if (mac.undef_loc != UNKNOWN_LOCATION)
	note_location (mac.undef_loc);
      if (mac.def)
	{
	  note_location (mac.def->line);
	  for (unsigned ix = 0; ix != mac.def->count; ix++)
	    note_location (mac.def->exp.tokens[ix].src_loc);
	}
    }

  return macros;
}

/* 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, vec<cpp_hashnode *> *macros,
			    unsigned *crc_p)
{
  dump () && dump ("Writing macros");
  dump.indent ();

  /* 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);
    }
  if (count)
    // We may have ended on a tokenless macro with a very short
    // location, that will cause problems reading its bit flags.
    sec.u (0);
  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);
    }

  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.loc_range_bits);

  cfg.u (config.active_init);

  /* 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.loc_range_bits = cfg.u ();

  config.active_init = 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.first)
    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_begin (elf_out *to, cpp_reader *reader,
			   module_state_config &config, unsigned &crc)
{
  /* Figure out remapped module numbers, which might elide
     partitions.  */
  bitmap partitions = NULL;
  if (!is_header () && !is_partition ())
    partitions = BITMAP_GGC_ALLOC ();
  write_init_maps ();

  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 (imp->is_direct () && (imp->remap || imp->is_partition ()))
	note_location (imp->imported_from ());
    }

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

  vec<cpp_hashnode *> *macros = nullptr;
  if (is_header ())
    macros = prepare_macros (reader);

  config.num_imports = mod_hwm;
  config.num_partitions = modules->length () - mod_hwm;
  auto map_info = write_prepare_maps (&config, bool (config.num_partitions));
  unsigned counts[MSC_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.  */
  if (config.ordinary_locs)
    write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc);
  if (config.macro_locs)
    write_macro_maps (to, map_info, &crc);

  if (is_header ())
    {
      counts[MSC_macros] = write_macros (to, macros, &crc);
      counts[MSC_inits] = write_inits (to, table, &crc);
      vec_free (macros);
    }

  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));
  trees_out::instrument ();

  write_counts (to, counts, &crc);

  spaces.release ();
  sccs.release ();

  vec_free (macro_loc_remap);
  vec_free (ord_loc_remap);
  vec_free (ool);

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

// Finish module writing after we've emitted all dynamic initializers. 

void
module_state::write_end (elf_out *to, cpp_reader *reader,
			 module_state_config &config, unsigned &crc)
{
  /* And finish up.  */
  write_config (to, config, crc);

  /* Human-readable info.  */
  write_readme (to, reader, config.dialect_str);

  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 && config.ordinary_locs))
    ordinary_locs.first = line_table->highest_location + 1;
  else if (!read_ordinary_maps (config.ordinary_locs, config.loc_range_bits))
    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
       monotonically 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 && config.macro_locs))
    macro_locs.first = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
  else if (!read_macro_maps (config.macro_locs))
    ok = false;

  /* Note whether there's an active initializer.  */
  active_init_p = !is_header () && bool (config.active_init);

  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 (ok && 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_ATTACH_P (not_tmpl))
    return -1;

  int mod = !DECL_MODULE_IMPORT_P (not_tmpl) ? 0 : get_importing_module (owner);
  gcc_checking_assert (!for_mangle || !(*modules)[mod]->is_header ());
  return mod;
}

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)
{
  for (;;)
    {
      tree ctx = CP_DECL_CONTEXT (decl);
      if (TREE_CODE (ctx) == NAMESPACE_DECL)
	// Found the namespace-scope decl.
	break;
      if (!CLASS_TYPE_P (ctx))
	// We've met a non-class scope.  Such a thing is not
	// reopenable, so we must be ok.
	return true;
      decl = TYPE_NAME (ctx);
    }

  tree not_tmpl = STRIP_TEMPLATE (decl);

  int use_tpl = 0;
  if (node_template_info (not_tmpl, use_tpl) && use_tpl)
    // Specializations of any kind can be redeclared anywhere.
    // FIXME: Should we be checking this in more places on the scope chain?
    return true;

  if (!DECL_LANG_SPECIFIC (not_tmpl) || !DECL_MODULE_ATTACH_P (not_tmpl))
    // Decl is attached to global module.  Current scope needs to be too.
    return !module_attach_p ();

  module_state *me = (*modules)[0];
  module_state *them = me;

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

  // Decl is attached to named module.  Current scope needs to be
  // attaching to the same module.
  if (!module_attach_p ())
    return false;

  // Both attached to named module.
  if (me == them)
    return true;

  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 (!DECL_NAMESPACE_SCOPE_P (decl))
    return;

  gcc_checking_assert (friend_p || decl == get_originating_module_decl (decl));

  if (module_attach_p ())
    {
      retrofit_lang_decl (decl);
      DECL_MODULE_ATTACH_P (decl) = true;
    }

  if (!module_exporting_p ())
    return;

  // FIXME: Check ill-formed linkage
  DECL_MODULE_EXPORT_P (decl) = true;
}

/* DECL is keyed to CTX for odr purposes.  */

void
maybe_key_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 (!keyed_table)
    keyed_table = new keyed_map_t (EXPERIMENT (1, 400));

 auto &vec = keyed_table->get_or_insert (ctx);
 if (!vec.length ())
   {
     retrofit_lang_decl (ctx);
     DECL_MODULE_KEYED_DECLS_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);

  /* Make sure lazy loading from a template context behaves as if
     from a non-template context.  */
  processing_template_decl_sentinel ptds;

  /* 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)
{
  /* Make sure lazy loading from a template context behaves as if
     from a non-template context.  */
  processing_template_decl_sentinel ptds;

  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 (!keyed_table)
	keyed_table = new keyed_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 = module->is_header () ? MK_HEADER : MK_NAMED | MK_ATTACH;

  // Even in header units, we consider the decls to be purview
  module_kind |= MK_PURVIEW;

  if (module->is_partition ())
    module_kind |= MK_PARTITION;
  if (exporting_p)
    {
      module->interface_p = true;
      module_kind |= MK_INTERFACE;
    }

  if (module_has_cmi_p ())
    {
      /* 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);
    }
}

/* Return true IFF we must emit a module global initializer function
   (which will be called by importers' init code).  */

bool
module_global_init_needed ()
{
  return module_has_cmi_p () && !header_module_p ();
}

/* Calculate which, if any, import initializers need calling.  */

bool
module_determine_import_inits ()
{
  if (!modules || header_module_p ())
    return false;

  /* Prune active_init_p.  We need the same bitmap allocation
     scheme as for the imports member.  */
  function_depth++; /* Disable GC.  */
  bitmap covered_imports (BITMAP_GGC_ALLOC ());

  bool any = false;

  /* 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->active_init_p)
	;
      else if (bitmap_bit_p (covered_imports, ix))
	import->active_init_p = false;
      else
	{
	  /* Everything this imports is therefore handled by its
	     initializer, so doesn't need initializing by us.  */
	  bitmap_ior_into (covered_imports, import->imports);
	  any = true;
	}
    }
  function_depth--;

  return any;
}

/* 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 ()
{
  if (!modules || header_module_p ())
    return;

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

/* 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);
	      module_kind |= MK_EXPORTING;
	      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);
}

// State propagated from finish_module_processing to fini_modules

struct module_processing_cookie
{
  elf_out out;
  module_state_config config;
  char *cmi_name;
  char *tmp_name;
  unsigned crc;
  bool began;

  module_processing_cookie (char *cmi, char *tmp, int fd, int e)
    : out (fd, e), cmi_name (cmi), tmp_name (tmp), crc (0), began (false)
  {
  }
  ~module_processing_cookie ()
  {
    XDELETEVEC (tmp_name);
    XDELETEVEC (cmi_name);
  }
};

/* Write the CMI, if we're a module interface.  */

void *
finish_module_processing (cpp_reader *reader)
{
  module_processing_cookie *cookie = nullptr;

  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 = -1;

      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.  */
      char *cmi_name = 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;
	  cmi_name = xstrdup (maybe_add_cmi_prefix (state->filename, &len));
	  tmp_name = XNEWVEC (char, len + 3);
	  memcpy (tmp_name, cmi_name, 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", cmi_name);
	  dump () && dump ("CMI is %s", cmi_name);
	}

      cookie = new module_processing_cookie (cmi_name, tmp_name, fd, e);

      if (errorcount)
	warning_at (state->loc, 0, "not writing module %qs due to errors",
		    state->get_flatname ());
      else if (cookie->out.begin ())
	{
	  cookie->began = true;
	  auto loc = input_location;
	  /* So crashes finger-point the module decl.  */
	  input_location = state->loc;
	  state->write_begin (&cookie->out, reader, cookie->config, cookie->crc);
	  input_location = loc;
	}

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

  return cookie;
}

// Do the final emission of a module.  At this point we know whether
// the module static initializer is a NOP or not.

static void
late_finish_module (cpp_reader *reader,  module_processing_cookie *cookie,
		    bool init_fn_non_empty)
{
  timevar_start (TV_MODULE_EXPORT);

  module_state *state = (*modules)[0];
  unsigned n = dump.push (state);
  state->announce ("finishing");

  cookie->config.active_init = init_fn_non_empty;
  if (cookie->began)
    state->write_end (&cookie->out, reader, cookie->config, cookie->crc);

  if (cookie->out.end () && cookie->cmi_name)
    {
      /* Some OS's do not replace NEWNAME if it already exists.
	 This'll have a race condition in erroneous concurrent
	 builds.  */
      unlink (cookie->cmi_name);
      if (rename (cookie->tmp_name, cookie->cmi_name))
	{
	  dump () && dump ("Rename ('%s','%s') errno=%u",
			   cookie->tmp_name, cookie->cmi_name, errno);
	  cookie->out.set_error (errno);
	}
    }

  if (cookie->out.get_error () && cookie->began)
    {
      error_at (state->loc, "failed to write compiled module: %s",
		cookie->out.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 (cookie->cmi_name)
    {
      /* We failed, attempt to erase all evidence we even tried.  */
      unlink (cookie->tmp_name);
      unlink (cookie->cmi_name);
    }

  delete cookie;
  dump.pop (n);
  timevar_stop (TV_MODULE_EXPORT);
}

void
fini_modules (cpp_reader *reader, void *cookie, bool has_inits)
{
  if (cookie)
    late_finish_module (reader,
			static_cast<module_processing_cookie *> (cookie),
			has_inits);

  /* 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 keys -- Let it go!  */
  delete keyed_table;
  keyed_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"
