/* Name mangling for the 3.0 -*- C++ -*- ABI.
   Copyright (C) 2000-2022 Free Software Foundation, Inc.
   Written by Alex Samuel <samuel@codesourcery.com>

   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/>.  */

/* This file implements mangling of C++ names according to the IA64
   C++ ABI specification.  A mangled name encodes a function or
   variable's name, scope, type, and/or template arguments into a text
   identifier.  This identifier is used as the function's or
   variable's linkage name, to preserve compatibility between C++'s
   language features (templates, scoping, and overloading) and C
   linkers.

   Additionally, g++ uses mangled names internally.  To support this,
   mangling of types is allowed, even though the mangled name of a
   type should not appear by itself as an exported name.  Ditto for
   uninstantiated templates.

   The primary entry point for this module is mangle_decl, which
   returns an identifier containing the mangled name for a decl.
   Additional entry points are provided to build mangled names of
   particular constructs when the appropriate decl for that construct
   is not available.  These are:

     mangle_typeinfo_for_type:		typeinfo data
     mangle_typeinfo_string_for_type:	typeinfo type name
     mangle_vtbl_for_type:		virtual table data
     mangle_vtt_for_type:		VTT data
     mangle_ctor_vtbl_for_type:		`C-in-B' constructor virtual table data
     mangle_thunk:			thunk function or entry  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "vtable-verify.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "flags.h"
#include "attribs.h"

/* Debugging support.  */

/* Define DEBUG_MANGLE to enable very verbose trace messages.  */
#ifndef DEBUG_MANGLE
#define DEBUG_MANGLE 0
#endif

/* Macros for tracing the write_* functions.  */
#if DEBUG_MANGLE
# define MANGLE_TRACE(FN, INPUT) \
  fprintf (stderr, "  %-24s: %-24s\n", (FN), (INPUT))
# define MANGLE_TRACE_TREE(FN, NODE) \
  fprintf (stderr, "  %-24s: %-24s (%p)\n", \
	   (FN), get_tree_code_name (TREE_CODE (NODE)), (void *) (NODE))
#else
# define MANGLE_TRACE(FN, INPUT)
# define MANGLE_TRACE_TREE(FN, NODE)
#endif

/* Nonzero if NODE is a class template-id.  We can't rely on
   CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser
   that hard to distinguish A<T> from A, where A<T> is the type as
   instantiated outside of the template, and A is the type used
   without parameters inside the template.  */
#define CLASSTYPE_TEMPLATE_ID_P(NODE)					\
  (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM			\
   || (CLASS_TYPE_P (NODE)						\
       && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL			\
       && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))

/* For deciding whether to set G.need_abi_warning, we need to consider both
   warn_abi_version and flag_abi_compat_version.  */
#define abi_warn_or_compat_version_crosses(N) \
  (abi_version_crosses (N) || abi_compat_version_crosses (N))

/* And sometimes we can simplify the code path if we don't need to worry about
   previous ABIs.  */
#define abi_flag_at_least(flag,N) (flag == 0 || flag >= N)
#define any_abi_below(N) \
  (!abi_version_at_least (N) \
   || !abi_flag_at_least (warn_abi_version, (N)) \
   || !abi_flag_at_least (flag_abi_compat_version, (N)))

/* Things we only need one of.  This module is not reentrant.  */
struct GTY(()) globals {
  /* An array of the current substitution candidates, in the order
     we've seen them.  Contains NULLS, which correspond to module
     substitutions.  */
  vec<tree, va_gc> *substitutions;

  /* The entity that is being mangled.  */
  tree GTY ((skip)) entity;

  /* How many parameter scopes we are inside.  */
  int parm_depth;

  /* True if the mangling will be different in a future version of the
     ABI.  */
  bool need_abi_warning;

  /* True if the mangling will be different in C++17 mode.  */
  bool need_cxx17_warning;

  /* True if we mangled a module name.  */
  bool mod;
};

static GTY (()) globals G;

/* The obstack on which we build mangled names.  */
static struct obstack *mangle_obstack;

/* The obstack on which we build mangled names that are not going to
   be IDENTIFIER_NODEs.  */
static struct obstack name_obstack;

/* The first object on the name_obstack; we use this to free memory
   allocated on the name_obstack.  */
static void *name_base;

/* Indices into subst_identifiers.  These are identifiers used in
   special substitution rules.  */
typedef enum
{
  SUBID_ALLOCATOR,
  SUBID_BASIC_STRING,
  SUBID_CHAR_TRAITS,
  SUBID_BASIC_ISTREAM,
  SUBID_BASIC_OSTREAM,
  SUBID_BASIC_IOSTREAM,
  SUBID_MAX
}
substitution_identifier_index_t;

/* For quick substitution checks, look up these common identifiers
   once only.  */
static GTY(()) tree subst_identifiers[SUBID_MAX];

/* Single-letter codes for builtin integer types, defined in
   <builtin-type>.  These are indexed by integer_type_kind values.  */
static const char
integer_type_codes[itk_none] =
{
  'c',  /* itk_char */
  'a',  /* itk_signed_char */
  'h',  /* itk_unsigned_char */
  's',  /* itk_short */
  't',  /* itk_unsigned_short */
  'i',  /* itk_int */
  'j',  /* itk_unsigned_int */
  'l',  /* itk_long */
  'm',  /* itk_unsigned_long */
  'x',  /* itk_long_long */
  'y',  /* itk_unsigned_long_long */
  /* __intN types are handled separately */
  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};

static tree maybe_template_info (const tree);

/* Functions for handling substitutions.  */

static inline tree canonicalize_for_substitution (tree);
static void add_substitution (tree);
static inline bool is_std_substitution (const tree,
				       const substitution_identifier_index_t);
static inline bool is_std_substitution_char (const tree,
					    const substitution_identifier_index_t);
static int find_substitution (tree);
static void mangle_call_offset (const tree, const tree);

/* Functions for emitting mangled representations of things.  */

static void write_mangled_name (const tree, bool);
static void write_encoding (const tree);
static void write_name (tree, const int);
static void write_abi_tags (tree);
static void write_unscoped_name (const tree);
static void write_unscoped_template_name (const tree);
static void write_nested_name (const tree);
static void write_prefix (const tree);
static void write_template_prefix (const tree);
static void write_unqualified_name (tree);
static void write_conversion_operator_name (const tree);
static void write_source_name (tree);
static void write_literal_operator_name (tree);
static void write_unnamed_type_name (const tree);
static void write_closure_type_name (const tree);
static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *,
			   const unsigned int);
static void write_number (unsigned HOST_WIDE_INT, const int,
			  const unsigned int);
static void write_compact_number (int num);
static void write_integer_cst (const tree);
static void write_real_cst (const tree);
static void write_identifier (const char *);
static void write_special_name_constructor (const tree);
static void write_special_name_destructor (const tree);
static void write_type (tree);
static int write_CV_qualifiers_for_type (const tree);
static void write_builtin_type (tree);
static void write_function_type (const tree);
static void write_bare_function_type (const tree, const int, const tree);
static void write_method_parms (tree, const int, const tree);
static void write_class_enum_type (const tree);
static void write_template_args (tree);
static void write_expression (tree);
static void write_template_arg_literal (const tree);
static void write_template_arg (tree);
static void write_template_template_arg (const tree);
static void write_array_type (const tree);
static void write_pointer_to_member_type (const tree);
static void write_template_param (const tree);
static void write_template_template_param (const tree);
static void write_substitution (const int);
static int discriminator_for_local_entity (tree);
static int discriminator_for_string_literal (tree, tree);
static void write_discriminator (const int);
static void write_local_name (tree, const tree, const tree);
static void dump_substitution_candidates (void);
static tree mangle_decl_string (const tree);
static void maybe_check_abi_tags (tree, tree = NULL_TREE, int = 10);
static bool equal_abi_tags (tree, tree);

/* Control functions.  */

static inline void start_mangling (const tree);
static tree mangle_special_for_type (const tree, const char *);

/* Append a single character to the end of the mangled
   representation.  */
#define write_char(CHAR)						\
  obstack_1grow (mangle_obstack, (CHAR))

/* Append a sized buffer to the end of the mangled representation.  */
#define write_chars(CHAR, LEN)						\
  obstack_grow (mangle_obstack, (CHAR), (LEN))

/* Append a NUL-terminated string to the end of the mangled
   representation.  */
#define write_string(STRING)						\
  obstack_grow (mangle_obstack, (STRING), strlen (STRING))

/* Nonzero if NODE1 and NODE2 are both TREE_LIST nodes and have the
   same purpose (context, which may be a type) and value (template
   decl).  See write_template_prefix for more information on what this
   is used for.  */
#define NESTED_TEMPLATE_MATCH(NODE1, NODE2)				\
  (TREE_CODE (NODE1) == TREE_LIST					\
   && TREE_CODE (NODE2) == TREE_LIST					\
   && ((TYPE_P (TREE_PURPOSE (NODE1))					\
	&& same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2)))	\
       || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2))			\
   && TREE_VALUE (NODE1) == TREE_VALUE (NODE2))

/* Write out an unsigned quantity in base 10.  */
#define write_unsigned_number(NUMBER)					\
  write_number ((NUMBER), /*unsigned_p=*/1, 10)

/* If DECL is a template instance (including the uninstantiated template
   itself), return its TEMPLATE_INFO.  Otherwise return NULL.  */

static tree
maybe_template_info (const tree decl)
{
  if (TREE_CODE (decl) == TYPE_DECL)
    {
      /* TYPE_DECLs are handled specially.  Look at its type to decide
	 if this is a template instantiation.  */
      const tree type = TREE_TYPE (decl);

      if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
	return TYPE_TEMPLATE_INFO (type);
    }
  else
    {
      /* Check if the template is a primary template.  */
      if (DECL_LANG_SPECIFIC (decl) != NULL
	  && VAR_OR_FUNCTION_DECL_P (decl)
	  && DECL_TEMPLATE_INFO (decl)
	  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
	return DECL_TEMPLATE_INFO (decl);
    }

  /* It's not a template id.  */
  return NULL_TREE;
}

/* Produce debugging output of current substitution candidates.  */

static void
dump_substitution_candidates (void)
{
  unsigned i;
  tree el;

  fprintf (stderr, "  ++ substitutions  ");
  FOR_EACH_VEC_ELT (*G.substitutions, i, el)
    {
      const char *name = "???";

      if (i > 0)
	fprintf (stderr, "                    ");
      if (!el)
	name = "module";
      else if (DECL_P (el))
	name = IDENTIFIER_POINTER (DECL_NAME (el));
      else if (TREE_CODE (el) == TREE_LIST)
	name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el)));
      else if (TYPE_NAME (el))
	name = TYPE_NAME_STRING (el);
      fprintf (stderr, " S%d_ = ", i - 1);
      if (el)
	{
	  if (TYPE_P (el) &&
	      (CP_TYPE_RESTRICT_P (el)
	       || CP_TYPE_VOLATILE_P (el)
	       || CP_TYPE_CONST_P (el)))
	    fprintf (stderr, "CV-");
	  fprintf (stderr, "%s (%s at %p)",
		   name, get_tree_code_name (TREE_CODE (el)), (void *) el);
	}
      fprintf (stderr, "\n");
    }
}

/* <exception-spec> ::=
      Do  -- non-throwing exception specification
      DO <expression> E  -- computed (instantiation-dependent) noexcept
      Dw <type>* E  -- throw (types)  */

static void
write_exception_spec (tree spec)
{

  if (!spec || spec == noexcept_false_spec)
    /* Nothing.  */
    return;

  if (!flag_noexcept_type)
    {
      G.need_cxx17_warning = true;
      return;
    }

  if (spec == noexcept_true_spec || spec == empty_except_spec)
    write_string ("Do");
  else if (tree expr = TREE_PURPOSE (spec))
    {
      /* noexcept (expr)  */
      gcc_assert (uses_template_parms (expr));
      write_string ("DO");
      write_expression (expr);
      write_char ('E');
    }
  else
    {
      /* throw (type-list) */
      write_string ("Dw");
      for (tree t = spec; t; t = TREE_CHAIN (t))
	write_type (TREE_VALUE (t));
      write_char ('E');
    }
}

/* Both decls and types can be substitution candidates, but sometimes
   they refer to the same thing.  For instance, a TYPE_DECL and
   RECORD_TYPE for the same class refer to the same thing, and should
   be treated accordingly in substitutions.  This function returns a
   canonicalized tree node representing NODE that is used when adding
   and substitution candidates and finding matches.  */

static inline tree
canonicalize_for_substitution (tree node)
{
  /* For a TYPE_DECL, use the type instead.  */
  if (TREE_CODE (node) == TYPE_DECL)
    node = TREE_TYPE (node);
  if (TYPE_P (node)
      && TYPE_CANONICAL (node) != node
      && TYPE_MAIN_VARIANT (node) != node)
    {
      tree orig = node;
      /* Here we want to strip the topmost typedef only.
         We need to do that so is_std_substitution can do proper
         name matching.  */
      if (TREE_CODE (node) == FUNCTION_TYPE)
	/* Use build_qualified_type and TYPE_QUALS here to preserve
	   the old buggy mangling of attribute noreturn with abi<5.  */
	node = build_qualified_type (TYPE_MAIN_VARIANT (node),
				     TYPE_QUALS (node));
      else
	node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
					cp_type_quals (node));
      if (FUNC_OR_METHOD_TYPE_P (node))
	{
	  node = build_ref_qualified_type (node, type_memfn_rqual (orig));
	  tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig));
	  if (flag_noexcept_type)
	    node = build_exception_variant (node, r);
	  else
	    /* Set the warning flag if appropriate.  */
	    write_exception_spec (r);
	}
    }
  return node;
}

/* Add NODE as a substitution candidate.  NODE must not already be on
   the list of candidates.  */

static void
add_substitution (tree node)
{
  tree c;

  if (DEBUG_MANGLE)
    fprintf (stderr, "  ++ add_substitution (%s at %10p)\n",
	     get_tree_code_name (TREE_CODE (node)), (void *) node);

  /* Get the canonicalized substitution candidate for NODE.  */
  c = canonicalize_for_substitution (node);
  if (DEBUG_MANGLE && c != node)
    fprintf (stderr, "  ++ using candidate (%s at %10p)\n",
	     get_tree_code_name (TREE_CODE (node)), (void *) node);
  node = c;

  /* Make sure NODE isn't already a candidate.  */
  if (flag_checking)
    {
      int i;
      tree candidate;

      FOR_EACH_VEC_SAFE_ELT (G.substitutions, i, candidate)
	if (candidate)
	  {
	    gcc_assert (!(DECL_P (node) && node == candidate));
	    gcc_assert (!(TYPE_P (node) && TYPE_P (candidate)
			  && same_type_p (node, candidate)));
	  }
    }

  /* Put the decl onto the varray of substitution candidates.  */
  vec_safe_push (G.substitutions, node);

  if (DEBUG_MANGLE)
    dump_substitution_candidates ();
}

/* Helper function for find_substitution.  Returns nonzero if NODE,
   which may be a decl or a CLASS_TYPE, is a template-id with template
   name of substitution_index[INDEX] in the ::std namespace, with
   global module attachment.  */

static bool
is_std_substitution (const tree node,
		     const substitution_identifier_index_t index)
{
  tree type = NULL;
  tree decl = NULL;

  if (DECL_P (node))
    {
      type = TREE_TYPE (node);
      decl = node;
    }
  else if (CLASS_TYPE_P (node))
    {
      type = node;
      decl = TYPE_NAME (node);
    }
  else
    /* These are not the droids you're looking for.  */
    return false;

  if (!DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)))
    return false;

  if (!(TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type)))
    return false;

  tree tmpl = TYPE_TI_TEMPLATE (type);
  if (DECL_NAME (tmpl) != subst_identifiers[index])
    return false;

  if (modules_p () && get_originating_module (tmpl, true) >= 0)
    return false;

  return true;
}

/* Return the ABI tags (the TREE_VALUE of the "abi_tag" attribute entry) for T,
   which can be a decl or type.  */

static tree
get_abi_tags (tree t)
{
  if (!t || TREE_CODE (t) == NAMESPACE_DECL)
    return NULL_TREE;

  if (DECL_P (t) && DECL_DECLARES_TYPE_P (t))
    t = TREE_TYPE (t);

  tree attrs;
  if (TYPE_P (t))
    attrs = TYPE_ATTRIBUTES (t);
  else
    attrs = DECL_ATTRIBUTES (t);

  tree tags = lookup_attribute ("abi_tag", attrs);
  if (tags)
    tags = TREE_VALUE (tags);
  return tags;
}

/* Helper function for find_substitution.  Returns nonzero if NODE,
   which may be a decl or a CLASS_TYPE, is the template-id
   ::std::identifier<char>, where identifier is
   substitution_index[INDEX].  */

static bool
is_std_substitution_char (const tree node,
			  const substitution_identifier_index_t index)
{
  tree args;
  /* Check NODE's name is ::std::identifier.  */
  if (!is_std_substitution (node, index))
    return 0;
  /* Figure out its template args.  */
  if (DECL_P (node))
    args = DECL_TI_ARGS (node);
  else if (CLASS_TYPE_P (node))
    args = CLASSTYPE_TI_ARGS (node);
  else
    /* Oops, not a template.  */
    return 0;
  /* NODE's template arg list should be <char>.  */
  return
    TREE_VEC_LENGTH (args) == 1
    && TREE_VEC_ELT (args, 0) == char_type_node;
}

/* Check whether a substitution should be used to represent NODE in
   the mangling.

   First, check standard special-case substitutions.

     <substitution> ::= St
	 # ::std

		    ::= Sa
	 # ::std::allocator

		    ::= Sb
	 # ::std::basic_string

		    ::= Ss
	 # ::std::basic_string<char,
			       ::std::char_traits<char>,
			       ::std::allocator<char> >

		    ::= Si
	 # ::std::basic_istream<char, ::std::char_traits<char> >

		    ::= So
	 # ::std::basic_ostream<char, ::std::char_traits<char> >

		    ::= Sd
	 # ::std::basic_iostream<char, ::std::char_traits<char> >

   Then examine the stack of currently available substitution
   candidates for entities appearing earlier in the same mangling

   If a substitution is found, write its mangled representation and
   return nonzero.  If none is found, just return zero.  */

static int
find_substitution (tree node)
{
  int i;
  const int size = vec_safe_length (G.substitutions);
  tree decl;
  tree type;
  const char *abbr = NULL;

  if (DEBUG_MANGLE)
    fprintf (stderr, "  ++ find_substitution (%s at %p)\n",
	     get_tree_code_name (TREE_CODE (node)), (void *) node);

  /* Obtain the canonicalized substitution representation for NODE.
     This is what we'll compare against.  */
  node = canonicalize_for_substitution (node);

  /* Check for builtin substitutions.  */

  decl = TYPE_P (node) ? TYPE_NAME (node) : node;
  type = TYPE_P (node) ? node : TREE_TYPE (node);

  /* Check for std::allocator.  */
  if (decl
      && is_std_substitution (decl, SUBID_ALLOCATOR)
      && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
    abbr = "Sa";

  /* Check for std::basic_string.  */
  else if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
    {
      if (TYPE_P (node))
	{
	  /* If this is a type (i.e. a fully-qualified template-id),
	     check for
		 std::basic_string <char,
				    std::char_traits<char>,
				    std::allocator<char> > .  */
	  if (cp_type_quals (type) == TYPE_UNQUALIFIED
	      && CLASSTYPE_USE_TEMPLATE (type))
	    {
	      tree args = CLASSTYPE_TI_ARGS (type);
	      if (TREE_VEC_LENGTH (args) == 3
		  && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
		  && is_std_substitution_char (TREE_VEC_ELT (args, 1),
					       SUBID_CHAR_TRAITS)
		  && is_std_substitution_char (TREE_VEC_ELT (args, 2),
					       SUBID_ALLOCATOR))
		abbr = "Ss";
	    }
	}
      else
	/* Substitute for the template name only if this isn't a type.  */
	abbr = "Sb";
    }

  /* Check for basic_{i,o,io}stream.  */
  else if (TYPE_P (node)
	   && cp_type_quals (type) == TYPE_UNQUALIFIED
	   && CLASS_TYPE_P (type)
	   && CLASSTYPE_USE_TEMPLATE (type)
	   && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
    {
      /* First, check for the template
	 args <char, std::char_traits<char> > .  */
      tree args = CLASSTYPE_TI_ARGS (type);
      if (TREE_VEC_LENGTH (args) == 2
	  && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
	  && is_std_substitution_char (TREE_VEC_ELT (args, 1),
				       SUBID_CHAR_TRAITS))
	{
	  /* Got them.  Is this basic_istream?  */
	  if (is_std_substitution (decl, SUBID_BASIC_ISTREAM))
	    abbr = "Si";
	  /* Or basic_ostream?  */
	  else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM))
	    abbr = "So";
	  /* Or basic_iostream?  */
	  else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM))
	    abbr = "Sd";
	}
    }

  /* Check for namespace std.  */
  else if (decl && DECL_NAMESPACE_STD_P (decl))
    {
      write_string ("St");
      return 1;
    }

  tree tags = NULL_TREE;
  if (OVERLOAD_TYPE_P (node) || DECL_CLASS_TEMPLATE_P (node))
    tags = get_abi_tags (type);
  /* Now check the list of available substitutions for this mangling
     operation.  */
  if (!abbr || tags)
    for (i = 0; i < size; ++i)
      if (tree candidate = (*G.substitutions)[i])
	{
	  /* NODE is a matched to a candidate if it's the same decl node or
	     if it's the same type.  */
	  if (decl == candidate
	      || (TYPE_P (candidate) && type && TYPE_P (node)
		  && same_type_p (type, candidate))
	      || NESTED_TEMPLATE_MATCH (node, candidate))
	    {
	      write_substitution (i);
	      return 1;
	    }
	}

  if (!abbr)
    /* No substitution found.  */
    return 0;

  write_string (abbr);
  if (tags)
    {
      /* If there are ABI tags on the abbreviation, it becomes
	 a substitution candidate.  */
      write_abi_tags (tags);
      add_substitution (node);
    }
  return 1;
}

/* Returns whether DECL's symbol name should be the plain unqualified-id
   rather than a more complicated mangled name.  */

static bool
unmangled_name_p (const tree decl)
{
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      /* The names of `extern "C"' functions are not mangled.  */
      return (DECL_EXTERN_C_FUNCTION_P (decl)
	      /* But overloaded operator names *are* mangled.  */
	      && !DECL_OVERLOADED_OPERATOR_P (decl));
    }
  else if (VAR_P (decl))
    {
      /* static variables are mangled.  */
      if (!DECL_EXTERNAL_LINKAGE_P (decl))
	return false;

      /* extern "C" declarations aren't mangled.  */
      if (DECL_EXTERN_C_P (decl))
	return true;

      /* Other variables at non-global scope are mangled.  */
      if (CP_DECL_CONTEXT (decl) != global_namespace)
	return false;

      /* Variable template instantiations are mangled.  */
      if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
	  && variable_template_p (DECL_TI_TEMPLATE (decl)))
	return false;

      /* Declarations with ABI tags are mangled.  */
      if (get_abi_tags (decl))
	return false;

      // Declarations attached to a named module are mangled
      if (modules_p () && get_originating_module (decl, true) >= 0)
	return false;

      /* The names of non-static global variables aren't mangled.  */
      return true;
    }

  return false;
}

/* TOP_LEVEL is true, if this is being called at outermost level of
  mangling. It should be false when mangling a decl appearing in an
  expression within some other mangling.

  <mangled-name>      ::= _Z <encoding>  */

static void
write_mangled_name (const tree decl, bool top_level)
{
  MANGLE_TRACE_TREE ("mangled-name", decl);

  check_abi_tags (decl);

  if (unmangled_name_p (decl))
    {
      if (top_level)
	write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
      else
	{
	  /* The standard notes: "The <encoding> of an extern "C"
	     function is treated like global-scope data, i.e. as its
	     <source-name> without a type."  We cannot write
	     overloaded operators that way though, because it contains
	     characters invalid in assembler.  */
	  write_string ("_Z");
	  write_source_name (DECL_NAME (decl));
	}
    }
  else
    {
      write_string ("_Z");
      write_encoding (decl);
    }
}

/* Returns true if the return type of DECL is part of its signature, and
   therefore its mangling.  */

bool
mangle_return_type_p (tree decl)
{
  return (!DECL_CONSTRUCTOR_P (decl)
	  && !DECL_DESTRUCTOR_P (decl)
	  && !DECL_CONV_FN_P (decl)
	  && maybe_template_info (decl));
}

/*   <encoding>		::= <function name> <bare-function-type>
			::= <data name>  */

static void
write_encoding (const tree decl)
{
  MANGLE_TRACE_TREE ("encoding", decl);

  if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
    {
      /* For overloaded operators write just the mangled name
	 without arguments.  */
      if (DECL_OVERLOADED_OPERATOR_P (decl))
	write_name (decl, /*ignore_local_scope=*/0);
      else
	write_source_name (DECL_NAME (decl));
      return;
    }

  write_name (decl, /*ignore_local_scope=*/0);
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      tree fn_type;
      tree d;

      if (maybe_template_info (decl))
	{
	  fn_type = get_mostly_instantiated_function_type (decl);
	  /* FN_TYPE will not have parameter types for in-charge or
	     VTT parameters.  Therefore, we pass NULL_TREE to
	     write_bare_function_type -- otherwise, it will get
	     confused about which artificial parameters to skip.  */
	  d = NULL_TREE;
	}
      else
	{
	  fn_type = TREE_TYPE (decl);
	  d = decl;
	}

      write_bare_function_type (fn_type,
				mangle_return_type_p (decl),
				d);

      /* If this is the pre/post function for a guarded function, append
	 .pre/post, like something from create_virtual_clone.  */
      if (DECL_IS_PRE_FN_P (decl))
	write_string (".pre");
      else if (DECL_IS_POST_FN_P (decl))
	write_string (".post");

      /* If this is a coroutine helper, then append an appropriate string to
	 identify which.  */
      if (tree ramp = DECL_RAMP_FN (decl))
	{
	  if (DECL_ACTOR_FN (ramp) == decl)
	    write_string (JOIN_STR "actor");
	  else if (DECL_DESTROY_FN (ramp) == decl)
	    write_string (JOIN_STR "destroy");
	  else
	    gcc_unreachable ();
	}
    }
}

/* Interface to substitution and identifier mangling, used by the
   module name mangler.  */

void
mangle_module_substitution (int v)
{
  write_substitution (v - 1);
}

int
mangle_module_component (tree comp, bool partition_p)
{
  write_char ('W');
  if (partition_p)
    write_char ('P');
  write_source_name (comp);

  // Module substitutions use the same number-space as entity
  // substitutions, but are orthogonal.
  vec_safe_push (G.substitutions, NULL_TREE);
  return G.substitutions->length ();
}

/* If the outermost non-namespace context (including DECL itself) is
   a module-linkage decl, mangle the module information.  For module
   global initializers we need to include the partition part.

   <module-name> ::= <module-sub>
		 || <subst>
                 || <module-name> <module-sub>
   <module-sub> :: W [P] <unqualified-name>
*/

static void
write_module (int m, bool include_partition)
{
  G.mod = true;
  mangle_module (m, include_partition);
}

static void
maybe_write_module (tree decl)
{
  if (!DECL_NAMESPACE_SCOPE_P (decl))
    return;

  if (!TREE_PUBLIC (STRIP_TEMPLATE (decl)))
    return;

  if (TREE_CODE (decl) == NAMESPACE_DECL)
    return;

  int m = get_originating_module (decl, true);
  if (m >= 0)
    write_module (m, false);
}

/* Lambdas can have a bit more context for mangling, specifically VAR_DECL
   or PARM_DECL context, which doesn't belong in DECL_CONTEXT.  */

static tree
decl_mangling_context (tree decl)
{
  tree tcontext = targetm.cxx.decl_mangling_context (decl);

  if (tcontext != NULL_TREE)
    return tcontext;

  if (TREE_CODE (decl) == TEMPLATE_DECL
      && DECL_TEMPLATE_RESULT (decl))
    decl = DECL_TEMPLATE_RESULT (decl);

  if (TREE_CODE (decl) == TYPE_DECL
      && LAMBDA_TYPE_P (TREE_TYPE (decl)))
    {
      tree extra = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl));
      if (extra)
	return extra;
    }
  else if (template_type_parameter_p (decl))
     /* template type parms have no mangling context.  */
      return NULL_TREE;

  tcontext = CP_DECL_CONTEXT (decl);

  /* Ignore the artificial declare reduction functions.  */
  if (tcontext
      && TREE_CODE (tcontext) == FUNCTION_DECL
      && DECL_OMP_DECLARE_REDUCTION_P (tcontext))
    return decl_mangling_context (tcontext);

  return tcontext;
}

/* <name> ::= <unscoped-name>
	  ::= <unscoped-template-name> <template-args>
	  ::= <nested-name>
	  ::= <local-name>

   If IGNORE_LOCAL_SCOPE is nonzero, this production of <name> is
   called from <local-name>, which mangles the enclosing scope
   elsewhere and then uses this function to mangle just the part
   underneath the function scope.  So don't use the <local-name>
   production, to avoid an infinite recursion.  */

static void
write_name (tree decl, const int ignore_local_scope)
{
  tree context;

  MANGLE_TRACE_TREE ("name", decl);

  if (TREE_CODE (decl) == TYPE_DECL)
    {
      /* In case this is a typedef, fish out the corresponding
	 TYPE_DECL for the main variant.  */
      decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
    }

  context = decl_mangling_context (decl);

  gcc_assert (context != NULL_TREE);

  if (abi_warn_or_compat_version_crosses (7)
      && ignore_local_scope
      && TREE_CODE (context) == PARM_DECL)
    G.need_abi_warning = 1;

  /* A decl in :: or ::std scope is treated specially.  The former is
     mangled using <unscoped-name> or <unscoped-template-name>, the
     latter with a special substitution.  Also, a name that is
     directly in a local function scope is also mangled with
     <unscoped-name> rather than a full <nested-name>.  */
  if (context == global_namespace
      || DECL_NAMESPACE_STD_P (context)
      || (ignore_local_scope
	  && (TREE_CODE (context) == FUNCTION_DECL
	      || (abi_version_at_least (7)
		  && TREE_CODE (context) == PARM_DECL))))
    {
      /* Is this a template instance?  */
      if (tree info = maybe_template_info (decl))
	{
	  /* Yes: use <unscoped-template-name>.  */
	  write_unscoped_template_name (TI_TEMPLATE (info));
	  write_template_args (TI_ARGS (info));
	}
      else
	/* Everything else gets an <unqualified-name>.  */
	write_unscoped_name (decl);
    }
  else
    {
      /* Handle local names, unless we asked not to (that is, invoked
	 under <local-name>, to handle only the part of the name under
	 the local scope).  */
      if (!ignore_local_scope)
	{
	  /* Scan up the list of scope context, looking for a
	     function.  If we find one, this entity is in local
	     function scope.  local_entity tracks context one scope
	     level down, so it will contain the element that's
	     directly in that function's scope, either decl or one of
	     its enclosing scopes.  */
	  tree local_entity = decl;
	  while (context != global_namespace)
	    {
	      /* Make sure we're always dealing with decls.  */
	      if (TYPE_P (context))
		context = TYPE_NAME (context);
	      /* Is this a function?  */
	      if (TREE_CODE (context) == FUNCTION_DECL
		  || TREE_CODE (context) == PARM_DECL)
		{
		  /* Yes, we have local scope.  Use the <local-name>
		     production for the innermost function scope.  */
		  write_local_name (context, local_entity, decl);
		  return;
		}
	      /* Up one scope level.  */
	      local_entity = context;
	      context = decl_mangling_context (context);
	    }

	  /* No local scope found?  Fall through to <nested-name>.  */
	}

      /* Other decls get a <nested-name> to encode their scope.  */
      write_nested_name (decl);
    }
}

/* <unscoped-name> ::= <unqualified-name>
		   ::= St <unqualified-name>   # ::std::  */

static void
write_unscoped_name (const tree decl)
{
  tree context = decl_mangling_context (decl);

  MANGLE_TRACE_TREE ("unscoped-name", decl);

  /* Is DECL in ::std?  */
  if (DECL_NAMESPACE_STD_P (context))
    {
      write_string ("St");
      write_unqualified_name (decl);
    }
  else
    {
      /* If not, it should be either in the global namespace, or directly
	 in a local function scope.  A lambda can also be mangled in the
	 scope of a default argument.  */
      gcc_assert (context == global_namespace
		  || TREE_CODE (context) == PARM_DECL
		  || TREE_CODE (context) == FUNCTION_DECL);

      write_unqualified_name (decl);
    }
}

/* <unscoped-template-name> ::= <unscoped-name>
			    ::= <substitution>  */

static void
write_unscoped_template_name (const tree decl)
{
  MANGLE_TRACE_TREE ("unscoped-template-name", decl);

  if (find_substitution (decl))
    return;
  write_unscoped_name (decl);
  add_substitution (decl);
}

/* Write the nested name, including CV-qualifiers, of DECL.

   <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
		 ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E

   <ref-qualifier> ::= R # & ref-qualifier
                   ::= O # && ref-qualifier
   <CV-qualifiers> ::= [r] [V] [K]  */

static void
write_nested_name (const tree decl)
{
  MANGLE_TRACE_TREE ("nested-name", decl);

  write_char ('N');

  /* Write CV-qualifiers, if this is a member function.  */
  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
    {
      if (DECL_VOLATILE_MEMFUNC_P (decl))
	write_char ('V');
      if (DECL_CONST_MEMFUNC_P (decl))
	write_char ('K');
      if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)))
	{
	  if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl)))
	    write_char ('O');
	  else
	    write_char ('R');
	}
    }

  /* Is this a template instance?  */
  if (tree info = maybe_template_info (decl))
    {
      /* Yes, use <template-prefix>.  */
      write_template_prefix (decl);
      write_template_args (TI_ARGS (info));
    }
  else if ((!abi_version_at_least (10) || TREE_CODE (decl) == TYPE_DECL)
	   && TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
    {
      tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
	{
	  write_template_prefix (decl);
	  write_template_args (TREE_OPERAND (name, 1));
	}
      else
	{
	  write_prefix (decl_mangling_context (decl));
	  write_unqualified_name (decl);
	}
    }
  else
    {
      /* No, just use <prefix>  */
      write_prefix (decl_mangling_context (decl));
      write_unqualified_name (decl);
    }
  write_char ('E');
}

/* <prefix> ::= <prefix> <unqualified-name>
	    ::= <template-param>
	    ::= <template-prefix> <template-args>
	    ::= <decltype>
	    ::= # empty
	    ::= <substitution>  */

static void
write_prefix (const tree node)
{
  tree decl;

  if (node == NULL
      || node == global_namespace)
    return;

  MANGLE_TRACE_TREE ("prefix", node);

  if (TREE_CODE (node) == DECLTYPE_TYPE)
    {
      write_type (node);
      return;
    }

  if (find_substitution (node))
    return;

  tree template_info = NULL_TREE;
  if (DECL_P (node))
    {
      /* If this is a function or parm decl, that means we've hit function
	 scope, so this prefix must be for a local name.  In this
	 case, we're under the <local-name> production, which encodes
	 the enclosing function scope elsewhere.  So don't continue
	 here.  */
      if (TREE_CODE (node) == FUNCTION_DECL
	  || TREE_CODE (node) == PARM_DECL)
	return;

      decl = node;
      template_info = maybe_template_info (decl);
    }
  else
    {
      /* Node is a type.  */
      decl = TYPE_NAME (node);
      /* The DECL might not point at the node.  */
      if (CLASSTYPE_TEMPLATE_ID_P (node))
	template_info = TYPE_TEMPLATE_INFO (node);
    }

  if (TREE_CODE (node) == TEMPLATE_TYPE_PARM)
    write_template_param (node);
  else if (template_info)
    /* Templated.  */
    {
      write_template_prefix (decl);
      write_template_args (TI_ARGS (template_info));
    }
  else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
    {
      tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
	{
	  write_template_prefix (decl);
	  write_template_args (TREE_OPERAND (name, 1));
	}
      else
	{
	  write_prefix (decl_mangling_context (decl));
	  write_unqualified_name (decl);
	}
    }
  else
    /* Not templated.  */
    {
      write_prefix (decl_mangling_context (decl));
      write_unqualified_name (decl);
      if (VAR_P (decl)
	  || TREE_CODE (decl) == FIELD_DECL)
	{
	  /* <data-member-prefix> := <member source-name> M */
	  write_char ('M');

	  /* Before ABI 18, we did not count these as substitution
	     candidates.  This leads to incorrect demanglings (and
	     ABI divergence to other compilers).  */
	  if (abi_warn_or_compat_version_crosses (18))
	    G.need_abi_warning = true;
	  if (!abi_version_at_least (18))
	    return;
	}
    }

  add_substitution (node);
}

/* <template-prefix> ::= <prefix> <template component>
		     ::= <template-param>
		     ::= <substitution>  */

static void
write_template_prefix (const tree node)
{
  tree decl = DECL_P (node) ? node : TYPE_NAME (node);
  tree type = DECL_P (node) ? TREE_TYPE (node) : node;
  tree context = decl_mangling_context (decl);
  tree templ;
  tree substitution;

  MANGLE_TRACE_TREE ("template-prefix", node);

  /* Find the template decl.  */
  if (tree info = maybe_template_info (decl))
    templ = TI_TEMPLATE (info);
  else if (TREE_CODE (type) == TYPENAME_TYPE)
    /* For a typename type, all we have is the name.  */
    templ = DECL_NAME (decl);
  else
    {
      gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));

      templ = TYPE_TI_TEMPLATE (type);
    }

  /* For a member template, though, the template name for the
     innermost name must have all the outer template levels
     instantiated.  For instance, consider

       template<typename T> struct Outer {
	 template<typename U> struct Inner {};
       };

     The template name for `Inner' in `Outer<int>::Inner<float>' is
     `Outer<int>::Inner<U>'.  In g++, we don't instantiate the template
     levels separately, so there's no TEMPLATE_DECL available for this
     (there's only `Outer<T>::Inner<U>').

     In order to get the substitutions right, we create a special
     TREE_LIST to represent the substitution candidate for a nested
     template.  The TREE_PURPOSE is the template's context, fully
     instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner
     template.

     So, for the example above, `Outer<int>::Inner' is represented as a
     substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
     and whose value is `Outer<T>::Inner<U>'.  */
  if (context && TYPE_P (context))
    substitution = build_tree_list (context, templ);
  else
    substitution = templ;

  if (find_substitution (substitution))
    return;

  if (TREE_TYPE (templ)
      && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM)
    write_template_param (TREE_TYPE (templ));
  else
    {
      write_prefix (context);
      write_unqualified_name (decl);
    }

  add_substitution (substitution);
}

/* As the list of identifiers for the structured binding declaration
   DECL is likely gone, try to recover the DC <source-name>+ E portion
   from its mangled name.  Return pointer to the DC and set len to
   the length up to and including the terminating E.  On failure
   return NULL.  */

static const char *
find_decomp_unqualified_name (tree decl, size_t *len)
{
  const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
  bool nested = false;
  if (!startswith (p, "_Z"))
    return NULL;
  p += 2;
  if (startswith (p, "St"))
    p += 2;
  else if (*p == 'N')
    {
      nested = true;
      ++p;
      while (ISDIGIT (p[0]))
	{
	  char *e;
	  long num = strtol (p, &e, 10);
	  if (num >= 1 && num < end - e)
	    p = e + num;
	  else
	    break;
	}
    }
  if (!startswith (p, "DC"))
    return NULL;
  if (nested)
    {
      if (end[-1] != 'E')
	return NULL;
      --end;
    }
  if (end[-1] != 'E')
    return NULL;
  *len = end - p;
  return p;
}

/* We don't need to handle thunks, vtables, or VTTs here.  Those are
   mangled through special entry points.

    <unqualified-name>  ::= [<module-name>] <operator-name>
			::= <special-name>
			::= [<module-name>] <source-name>
			::= [<module-name>] <unnamed-type-name>
			::= <local-source-name> 

    <local-source-name>	::= L <source-name> <discriminator> */

static void
write_unqualified_id (tree identifier)
{
  if (IDENTIFIER_CONV_OP_P (identifier))
    write_conversion_operator_name (TREE_TYPE (identifier));
  else if (IDENTIFIER_OVL_OP_P (identifier))
    {
      const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (identifier);
      write_string (ovl_op->mangled_name);
    }
  else if (UDLIT_OPER_P (identifier))
    write_literal_operator_name (identifier);
  else
    write_source_name (identifier);
}

static void
write_unqualified_name (tree decl)
{
  MANGLE_TRACE_TREE ("unqualified-name", decl);

  if (modules_p ())
    maybe_write_module (decl);

  if (identifier_p (decl))
    {
      write_unqualified_id (decl);
      return;
    }

  bool found = false;

  if (DECL_NAME (decl) == NULL_TREE)
    {
      found = true;
      gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
      const char *decomp_str = NULL;
      size_t decomp_len = 0;
      if (VAR_P (decl)
	  && DECL_DECOMPOSITION_P (decl)
	  && DECL_NAME (decl) == NULL_TREE
	  && DECL_NAMESPACE_SCOPE_P (decl))
	decomp_str = find_decomp_unqualified_name (decl, &decomp_len);
      if (decomp_str)
	write_chars (decomp_str, decomp_len);
      else
	write_source_name (DECL_ASSEMBLER_NAME (decl));
    }
  else if (DECL_DECLARES_FUNCTION_P (decl))
    {
      found = true;
      if (DECL_CONSTRUCTOR_P (decl))
	write_special_name_constructor (decl);
      else if (DECL_DESTRUCTOR_P (decl))
	write_special_name_destructor (decl);
      else if (DECL_CONV_FN_P (decl))
	{
	  /* Conversion operator. Handle it right here.
	     <operator> ::= cv <type>  */
	  tree type;
	  if (maybe_template_info (decl))
	    {
	      tree fn_type;
	      fn_type = get_mostly_instantiated_function_type (decl);
	      type = TREE_TYPE (fn_type);
	    }
	  else if (FNDECL_USED_AUTO (decl))
	    type = DECL_SAVED_AUTO_RETURN_TYPE (decl);
	  else
	    type = DECL_CONV_FN_TYPE (decl);
	  write_conversion_operator_name (type);
	}
      else if (DECL_OVERLOADED_OPERATOR_P (decl))
	{
	  tree t;
	  if (!(t = DECL_RAMP_FN (decl)))
	    t = decl;
	  const char *mangled_name
	    = (ovl_op_info[DECL_ASSIGNMENT_OPERATOR_P (t)]
	       [DECL_OVERLOADED_OPERATOR_CODE_RAW (t)].mangled_name);
	  write_string (mangled_name);
	}
      else if (UDLIT_OPER_P (DECL_NAME (decl)))
	write_literal_operator_name (DECL_NAME (decl));
      else
	found = false;
    }

  if (found)
    /* OK */;
  else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
	   && DECL_NAMESPACE_SCOPE_P (decl)
	   && decl_linkage (decl) == lk_internal)
    {
      MANGLE_TRACE_TREE ("local-source-name", decl);
      write_char ('L');
      write_source_name (DECL_NAME (decl));
      /* The default discriminator is 1, and that's all we ever use,
	 so there's no code to output one here.  */
    }
  else
    {
      tree type = TREE_TYPE (decl);

      if (TREE_CODE (decl) == TYPE_DECL
          && TYPE_UNNAMED_P (type))
        write_unnamed_type_name (type);
      else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type))
        write_closure_type_name (type);
      else
        write_source_name (DECL_NAME (decl));
    }

  /* We use the ABI tags from the primary class template, ignoring tags on any
     specializations.  This is necessary because C++ doesn't require a
     specialization to be declared before it is used unless the use requires a
     complete type, but we need to get the tags right on incomplete types as
     well.  */
  if (tree tmpl = most_general_template (decl))
    {
      tree res = DECL_TEMPLATE_RESULT (tmpl);
      if (res == NULL_TREE)
	/* UNBOUND_CLASS_TEMPLATE.  */;
      else if (DECL_DECLARES_TYPE_P (decl))
	decl = res;
      else if (any_abi_below (11))
	{
	  /* ABI v10 implicit tags on the template.  */
	  tree mtags = missing_abi_tags (res);
	  /* Explicit tags on the template.  */
	  tree ttags = get_abi_tags (res);
	  /* Tags on the instantiation.  */
	  tree dtags = get_abi_tags (decl);

	  if (mtags && abi_warn_or_compat_version_crosses (10))
	    G.need_abi_warning = 1;

	  /* Add the v10 tags to the explicit tags now.  */
	  mtags = chainon (mtags, ttags);

	  if (!G.need_abi_warning
	      && abi_warn_or_compat_version_crosses (11)
	      && !equal_abi_tags (dtags, mtags))
	    G.need_abi_warning = 1;

	  if (!abi_version_at_least (10))
	    /* In abi <10, we only got the explicit tags.  */
	    decl = res;
	  else if (flag_abi_version == 10)
	    {
	      /* In ABI 10, we want explict and implicit tags.  */
	      write_abi_tags (mtags);
	      return;
	    }
	}
    }

  tree tags = get_abi_tags (decl);
  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CONV_FN_P (decl)
      && any_abi_below (11))
    if (tree mtags = missing_abi_tags (decl))
      {
	if (abi_warn_or_compat_version_crosses (11))
	  G.need_abi_warning = true;
	if (!abi_version_at_least (11))
	  tags = chainon (mtags, tags);
      }
  write_abi_tags (tags);
}

/* Write the unqualified-name for a conversion operator to TYPE.  */

static void
write_conversion_operator_name (const tree type)
{
  write_string ("cv");
  write_type (type);
}

/* Non-terminal <source-name>.  IDENTIFIER is an IDENTIFIER_NODE.

     <source-name> ::= </length/ number> <identifier>  */

static void
write_source_name (tree identifier)
{
  MANGLE_TRACE_TREE ("source-name", identifier);

  write_unsigned_number (IDENTIFIER_LENGTH (identifier));
  write_identifier (IDENTIFIER_POINTER (identifier));
}

/* Compare two TREE_STRINGs like strcmp.  */

int
tree_string_cmp (const void *p1, const void *p2)
{
  if (p1 == p2)
    return 0;
  tree s1 = *(const tree*)p1;
  tree s2 = *(const tree*)p2;
  return strcmp (TREE_STRING_POINTER (s1),
		 TREE_STRING_POINTER (s2));
}

/* Return the TREE_LIST of TAGS as a sorted VEC.  */

static vec<tree, va_gc> *
sorted_abi_tags (tree tags)
{
  vec<tree, va_gc> * vec = make_tree_vector();

  for (tree t = tags; t; t = TREE_CHAIN (t))
    {
      if (ABI_TAG_IMPLICIT (t))
	continue;
      tree str = TREE_VALUE (t);
      vec_safe_push (vec, str);
    }

  vec->qsort (tree_string_cmp);

  return vec;
}

/* ID is the name of a function or type with abi_tags attribute TAGS.
   Write out the name, suitably decorated.  */

static void
write_abi_tags (tree tags)
{
  if (tags == NULL_TREE)
    return;

  vec<tree, va_gc> * vec = sorted_abi_tags (tags);

  unsigned i; tree str;
  FOR_EACH_VEC_ELT (*vec, i, str)
    {
      write_string ("B");
      write_unsigned_number (TREE_STRING_LENGTH (str) - 1);
      write_identifier (TREE_STRING_POINTER (str));
    }

  release_tree_vector (vec);
}

/* True iff the TREE_LISTS T1 and T2 of ABI tags are equivalent.  */

static bool
equal_abi_tags (tree t1, tree t2)
{
  releasing_vec v1 = sorted_abi_tags (t1);
  releasing_vec v2 = sorted_abi_tags (t2);

  unsigned len1 = v1->length();
  if (len1 != v2->length())
    return false;
  for (unsigned i = 0; i < len1; ++i)
    if (tree_string_cmp (v1[i], v2[i]) != 0)
      return false;
  return true;
}

/* Write a user-defined literal operator.
          ::= li <source-name>    # "" <source-name>
   IDENTIFIER is an LITERAL_IDENTIFIER_NODE.  */

static void
write_literal_operator_name (tree identifier)
{
  const char* suffix = UDLIT_OP_SUFFIX (identifier);
  write_identifier (UDLIT_OP_MANGLED_PREFIX);
  write_unsigned_number (strlen (suffix));
  write_identifier (suffix);
}

/* Encode 0 as _, and 1+ as n-1_.  */

static void
write_compact_number (int num)
{
  gcc_checking_assert (num >= 0);
  if (num > 0)
    write_unsigned_number (num - 1);
  write_char ('_');
}

/* Return how many unnamed types precede TYPE in its enclosing class.  */

static int
nested_anon_class_index (tree type)
{
  int index = 0;
  tree member = TYPE_FIELDS (TYPE_CONTEXT (type));
  for (; member; member = DECL_CHAIN (member))
    if (DECL_IMPLICIT_TYPEDEF_P (member))
      {
	tree memtype = TREE_TYPE (member);
	if (memtype == type)
	  return index;
	else if (TYPE_UNNAMED_P (memtype))
	  ++index;
      }

  if (seen_error ())
    return -1;

  gcc_unreachable ();
}

/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */

static void
write_unnamed_type_name (const tree type)
{
  int discriminator;
  MANGLE_TRACE_TREE ("unnamed-type-name", type);

  if (TYPE_FUNCTION_SCOPE_P (type))
    discriminator = discriminator_for_local_entity (TYPE_NAME (type));
  else if (TYPE_CLASS_SCOPE_P (type))
    discriminator = nested_anon_class_index (type);
  else
    {
      gcc_assert (no_linkage_check (type, /*relaxed_p=*/true));
      /* Just use the old mangling at namespace scope.  */
      write_source_name (TYPE_IDENTIFIER (type));
      return;
    }

  write_string ("Ut");
  write_compact_number (discriminator);
}

// A template head, for templated lambdas.
// <template-head> ::=   Tp* Ty
//                       Tp* Tn <type>
//                       Tp* Tt <template-head> E
// New in ABI=18. Returns true iff we emitted anything -- used for ABI
// version warning.

static bool
write_closure_template_head (tree tmpl)
{
  bool any = false;

  // We only need one level of template parms
  tree inner = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));

  for (int ix = 0, len = TREE_VEC_LENGTH (inner); ix != len; ix++)
    {
      tree parm = TREE_VEC_ELT (inner, ix);
      if (parm == error_mark_node)
	continue;
      parm = TREE_VALUE (parm);

      if (DECL_VIRTUAL_P (parm))
	// A synthetic parm, we're done.
	break;

      any = true;
      if (abi_version_at_least (18))
	{
	  if (TREE_CODE (parm) == PARM_DECL
	      ? TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))
	      : TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
	    write_string ("Tp");

	  switch (TREE_CODE (parm))
	    {
	    default:
	      gcc_unreachable ();

	    case TYPE_DECL:
	      write_string ("Ty");
	      break;

	    case PARM_DECL:
	      write_string ("Tn");
	      write_type (TREE_TYPE (parm));
	      break;

	    case TEMPLATE_DECL:
	      write_string ("Tt");
	      write_closure_template_head (parm);
	      write_string ("E");
	      break;
	    }
	}
    }

  return any;
}

/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
   <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters */

static void
write_closure_type_name (const tree type)
{
  tree fn = lambda_function (type);
  tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
  tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));

  MANGLE_TRACE_TREE ("closure-type-name", type);

  write_string ("Ul");

  if (auto ti = maybe_template_info (fn))
    if (write_closure_template_head (TI_TEMPLATE (ti)))
      // If there were any explicit template parms, we may need to
      // issue a mangling diagnostic.
      if (abi_warn_or_compat_version_crosses (18))
	G.need_abi_warning = true;

  write_method_parms (parms, /*method_p=*/1, fn);
  write_char ('E');
  write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
}

/* Convert NUMBER to ascii using base BASE and generating at least
   MIN_DIGITS characters. BUFFER points to the _end_ of the buffer
   into which to store the characters. Returns the number of
   characters generated (these will be laid out in advance of where
   BUFFER points).  */

static int
hwint_to_ascii (unsigned HOST_WIDE_INT number, const unsigned int base,
		char *buffer, const unsigned int min_digits)
{
  static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  unsigned digits = 0;

  while (number)
    {
      unsigned HOST_WIDE_INT d = number / base;

      *--buffer = base_digits[number - d * base];
      digits++;
      number = d;
    }
  while (digits < min_digits)
    {
      *--buffer = base_digits[0];
      digits++;
    }
  return digits;
}

/* Non-terminal <number>.

     <number> ::= [n] </decimal integer/>  */

static void
write_number (unsigned HOST_WIDE_INT number, const int unsigned_p,
	      const unsigned int base)
{
  char buffer[sizeof (HOST_WIDE_INT) * 8];
  unsigned count = 0;

  if (!unsigned_p && (HOST_WIDE_INT) number < 0)
    {
      write_char ('n');
      number = -((HOST_WIDE_INT) number);
    }
  count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1);
  write_chars (buffer + sizeof (buffer) - count, count);
}

/* Write out an integral CST in decimal. Most numbers are small, and
   representable in a HOST_WIDE_INT. Occasionally we'll have numbers
   bigger than that, which we must deal with.  */

static inline void
write_integer_cst (const tree cst)
{
  int sign = tree_int_cst_sgn (cst);
  widest_int abs_value = wi::abs (wi::to_widest (cst));
  if (!wi::fits_uhwi_p (abs_value))
    {
      /* A bignum. We do this in chunks, each of which fits in a
	 HOST_WIDE_INT.  */
      char buffer[sizeof (HOST_WIDE_INT) * 8 * 2];
      unsigned HOST_WIDE_INT chunk;
      unsigned chunk_digits;
      char *ptr = buffer + sizeof (buffer);
      unsigned count = 0;
      tree n, base, type;
      int done;

      /* HOST_WIDE_INT must be at least 32 bits, so 10^9 is
	 representable.  */
      chunk = 1000000000;
      chunk_digits = 9;

      if (sizeof (HOST_WIDE_INT) >= 8)
	{
	  /* It is at least 64 bits, so 10^18 is representable.  */
	  chunk_digits = 18;
	  chunk *= chunk;
	}

      type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst));
      base = build_int_cstu (type, chunk);
      n = wide_int_to_tree (type, wi::to_wide (cst));

      if (sign < 0)
	{
	  write_char ('n');
	  n = fold_build1_loc (input_location, NEGATE_EXPR, type, n);
	}
      do
	{
	  tree d = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, n, base);
	  tree tmp = fold_build2_loc (input_location, MULT_EXPR, type, d, base);
	  unsigned c;

	  done = integer_zerop (d);
	  tmp = fold_build2_loc (input_location, MINUS_EXPR, type, n, tmp);
	  c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
			      done ? 1 : chunk_digits);
	  ptr -= c;
	  count += c;
	  n = d;
	}
      while (!done);
      write_chars (ptr, count);
    }
  else
    {
      /* A small num.  */
      if (sign < 0)
	write_char ('n');
      write_unsigned_number (abs_value.to_uhwi ());
    }
}

/* Write out a floating-point literal.

    "Floating-point literals are encoded using the bit pattern of the
    target processor's internal representation of that number, as a
    fixed-length lowercase hexadecimal string, high-order bytes first
    (even if the target processor would store low-order bytes first).
    The "n" prefix is not used for floating-point literals; the sign
    bit is encoded with the rest of the number.

    Here are some examples, assuming the IEEE standard representation
    for floating point numbers.  (Spaces are for readability, not
    part of the encoding.)

	1.0f			Lf 3f80 0000 E
       -1.0f			Lf bf80 0000 E
	1.17549435e-38f		Lf 0080 0000 E
	1.40129846e-45f		Lf 0000 0001 E
	0.0f			Lf 0000 0000 E"

   Caller is responsible for the Lx and the E.  */
static void
write_real_cst (const tree value)
{
  long target_real[4];  /* largest supported float */
  /* Buffer for eight hex digits in a 32-bit number but big enough
     even for 64-bit long to avoid warnings.  */
  char buffer[17];
  int i, limit, dir;

  tree type = TREE_TYPE (value);
  int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32;

  real_to_target (target_real, &TREE_REAL_CST (value),
		  TYPE_MODE (type));

  /* The value in target_real is in the target word order,
     so we must write it out backward if that happens to be
     little-endian.  write_number cannot be used, it will
     produce uppercase.  */
  if (FLOAT_WORDS_BIG_ENDIAN)
    i = 0, limit = words, dir = 1;
  else
    i = words - 1, limit = -1, dir = -1;

  for (; i != limit; i += dir)
    {
      sprintf (buffer, "%08lx", (unsigned long) target_real[i]);
      write_chars (buffer, 8);
    }
}

/* Non-terminal <identifier>.

     <identifier> ::= </unqualified source code identifier>  */

static void
write_identifier (const char *identifier)
{
  MANGLE_TRACE ("identifier", identifier);
  write_string (identifier);
}

/* Handle constructor productions of non-terminal <special-name>.
   CTOR is a constructor FUNCTION_DECL.

     <special-name> ::= C1   # complete object constructor
		    ::= C2   # base object constructor
		    ::= C3   # complete object allocating constructor

   Currently, allocating constructors are never used.  */

static void
write_special_name_constructor (const tree ctor)
{
  write_char ('C');
  bool new_inh = (flag_new_inheriting_ctors
		  && DECL_INHERITED_CTOR (ctor));
  if (new_inh)
    write_char ('I');
  if (DECL_BASE_CONSTRUCTOR_P (ctor))
    write_char ('2');
  /* This is the old-style "[unified]" constructor.
     In some cases, we may emit this function and call
     it from the clones in order to share code and save space.  */
  else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor))
    write_char ('4');
  else
    {
      gcc_assert (DECL_COMPLETE_CONSTRUCTOR_P (ctor));
      write_char ('1');
    }
  if (new_inh)
    write_type (DECL_INHERITED_CTOR_BASE (ctor));
}

/* Handle destructor productions of non-terminal <special-name>.
   DTOR is a destructor FUNCTION_DECL.

     <special-name> ::= D0 # deleting (in-charge) destructor
		    ::= D1 # complete object (in-charge) destructor
		    ::= D2 # base object (not-in-charge) destructor  */

static void
write_special_name_destructor (const tree dtor)
{
  if (DECL_DELETING_DESTRUCTOR_P (dtor))
    write_string ("D0");
  else if (DECL_BASE_DESTRUCTOR_P (dtor))
    write_string ("D2");
  else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor))
    /* This is the old-style "[unified]" destructor.
       In some cases, we may emit this function and call
       it from the clones in order to share code and save space.  */
    write_string ("D4");
  else
    {
      gcc_assert (DECL_COMPLETE_DESTRUCTOR_P (dtor));
      write_string ("D1");
    }
}

/* Return the discriminator for ENTITY appearing inside
   FUNCTION.  The discriminator is the lexical ordinal of VAR or TYPE among
   entities with the same name and kind in the same FUNCTION.  */

static int
discriminator_for_local_entity (tree entity)
{
  if (!DECL_LANG_SPECIFIC (entity))
    {
      /* Some decls, like __FUNCTION__, don't need a discriminator.  */
      gcc_checking_assert (DECL_ARTIFICIAL (entity));
      return 0;
    }
  else if (tree disc = DECL_DISCRIMINATOR (entity))
    return TREE_INT_CST_LOW (disc);
  else
    /* The first entity with a particular name doesn't get
       DECL_DISCRIMINATOR set up.  */
    return 0;
}

/* Return the discriminator for STRING, a string literal used inside
   FUNCTION.  The discriminator is the lexical ordinal of STRING among
   string literals used in FUNCTION.  */

static int
discriminator_for_string_literal (tree /*function*/,
				  tree /*string*/)
{
  /* For now, we don't discriminate amongst string literals.  */
  return 0;
}

/*   <discriminator> := _ <number>    # when number < 10
                     := __ <number> _ # when number >= 10

   The discriminator is used only for the second and later occurrences
   of the same name within a single function. In this case <number> is
   n - 2, if this is the nth occurrence, in lexical order.  */

static void
write_discriminator (const int discriminator)
{
  /* If discriminator is zero, don't write anything.  Otherwise...  */
  if (discriminator > 0)
    {
      write_char ('_');
      if (discriminator - 1 >= 10)
	{
	  if (abi_warn_or_compat_version_crosses (11))
	    G.need_abi_warning = 1;
	  if (abi_version_at_least (11))
	    write_char ('_');
	}
      write_unsigned_number (discriminator - 1);
      if (abi_version_at_least (11) && discriminator - 1 >= 10)
	write_char ('_');
    }
}

/* Mangle the name of a function-scope entity.  FUNCTION is the
   FUNCTION_DECL for the enclosing function, or a PARM_DECL for lambdas in
   default argument scope.  ENTITY is the decl for the entity itself.
   LOCAL_ENTITY is the entity that's directly scoped in FUNCTION_DECL,
   either ENTITY itself or an enclosing scope of ENTITY.

     <local-name> := Z <function encoding> E <entity name> [<discriminator>]
		  := Z <function encoding> E s [<discriminator>]
		  := Z <function encoding> Ed [ <parameter number> ] _ <entity name> */

static void
write_local_name (tree function, const tree local_entity,
		  const tree entity)
{
  tree parm = NULL_TREE;

  MANGLE_TRACE_TREE ("local-name", entity);

  if (TREE_CODE (function) == PARM_DECL)
    {
      parm = function;
      function = DECL_CONTEXT (parm);
    }

  write_char ('Z');
  write_encoding (function);
  write_char ('E');

  /* For this purpose, parameters are numbered from right-to-left.  */
  if (parm)
    {
      int i = list_length (parm);
      write_char ('d');
      write_compact_number (i - 1);
    }

  if (TREE_CODE (entity) == STRING_CST)
    {
      write_char ('s');
      write_discriminator (discriminator_for_string_literal (function,
							     entity));
    }
  else
    {
      /* Now the <entity name>.  Let write_name know its being called
	 from <local-name>, so it doesn't try to process the enclosing
	 function scope again.  */
      write_name (entity, /*ignore_local_scope=*/1);
      if (DECL_DISCRIMINATOR_P (local_entity)
	  && !(TREE_CODE (local_entity) == TYPE_DECL
	       && TYPE_ANON_P (TREE_TYPE (local_entity))))
	write_discriminator (discriminator_for_local_entity (local_entity));
    }
}

/* Non-terminals <type> and <CV-qualifier>.

     <type> ::= <builtin-type>
	    ::= <function-type>
	    ::= <class-enum-type>
	    ::= <array-type>
	    ::= <pointer-to-member-type>
	    ::= <template-param>
	    ::= <substitution>
	    ::= <CV-qualifier>
	    ::= P <type>    # pointer-to
	    ::= R <type>    # reference-to
	    ::= C <type>    # complex pair (C 2000)
	    ::= G <type>    # imaginary (C 2000)     [not supported]
	    ::= U <source-name> <type>   # vendor extended type qualifier

   C++0x extensions

     <type> ::= RR <type>   # rvalue reference-to
     <type> ::= Dt <expression> # decltype of an id-expression or 
                                # class member access
     <type> ::= DT <expression> # decltype of an expression
     <type> ::= Dn              # decltype of nullptr

   TYPE is a type node.  */

static void
write_type (tree type)
{
  /* This gets set to nonzero if TYPE turns out to be a (possibly
     CV-qualified) builtin type.  */
  int is_builtin_type = 0;

  MANGLE_TRACE_TREE ("type", type);

  if (type == error_mark_node)
    return;

  type = canonicalize_for_substitution (type);
  if (find_substitution (type))
    return;


  if (write_CV_qualifiers_for_type (type) > 0)
    /* If TYPE was CV-qualified, we just wrote the qualifiers; now
       mangle the unqualified type.  The recursive call is needed here
       since both the qualified and unqualified types are substitution
       candidates.  */
    {
      tree t = TYPE_MAIN_VARIANT (type);
      if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t))
	{
	  tree attrs = NULL_TREE;
	  if (tx_safe_fn_type_p (type))
	    attrs = tree_cons (get_identifier ("transaction_safe"),
			       NULL_TREE, attrs);
	  t = cp_build_type_attribute_variant (t, attrs);
	}
      gcc_assert (t != type);
      if (FUNC_OR_METHOD_TYPE_P (t))
	{
	  t = build_ref_qualified_type (t, type_memfn_rqual (type));
	  if (flag_noexcept_type)
	    {
	      tree r = TYPE_RAISES_EXCEPTIONS (type);
	      t = build_exception_variant (t, r);
	    }
	  if (abi_version_at_least (8)
	      || type == TYPE_MAIN_VARIANT (type))
	    /* Avoid adding the unqualified function type as a substitution.  */
	    write_function_type (t);
	  else
	    write_type (t);
	  if (abi_warn_or_compat_version_crosses (8))
	    G.need_abi_warning = 1;
	}
      else
	write_type (t);
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
       so that the cv-qualification of the element type is available
       in write_array_type.  */
    write_array_type (type);
  else
    {
      tree type_orig = type;

      /* See through any typedefs.  */
      type = TYPE_MAIN_VARIANT (type);
      if (FUNC_OR_METHOD_TYPE_P (type))
	type = cxx_copy_lang_qualifiers (type, type_orig);

      /* According to the C++ ABI, some library classes are passed the
	 same as the scalar type of their single member and use the same
	 mangling.  */
      if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
	type = TREE_TYPE (first_field (type));

      if (TYPE_PTRDATAMEM_P (type))
	write_pointer_to_member_type (type);
      else
        {
	  /* Handle any target-specific fundamental types.  */
	  const char *target_mangling
	    = targetm.mangle_type (type_orig);

	  if (target_mangling)
	    {
	      write_string (target_mangling);
	      /* Add substitutions for types other than fundamental
		 types.  */
	      if (!VOID_TYPE_P (type)
		  && TREE_CODE (type) != INTEGER_TYPE
		  && TREE_CODE (type) != REAL_TYPE
		  && TREE_CODE (type) != BOOLEAN_TYPE)
		add_substitution (type);
	      return;
	    }

	  switch (TREE_CODE (type))
	    {
	    case VOID_TYPE:
	    case BOOLEAN_TYPE:
	    case INTEGER_TYPE:  /* Includes wchar_t.  */
	    case REAL_TYPE:
	    case FIXED_POINT_TYPE:
	      {
		/* If this is a typedef, TYPE may not be one of
		   the standard builtin type nodes, but an alias of one.  Use
		   TYPE_MAIN_VARIANT to get to the underlying builtin type.  */
		write_builtin_type (TYPE_MAIN_VARIANT (type));
		++is_builtin_type;
	      }
	      break;

	    case COMPLEX_TYPE:
	      write_char ('C');
	      write_type (TREE_TYPE (type));
	      break;

	    case FUNCTION_TYPE:
	    case METHOD_TYPE:
	      write_function_type (type);
	      break;

	    case UNION_TYPE:
	    case RECORD_TYPE:
	    case ENUMERAL_TYPE:
	      /* A pointer-to-member function is represented as a special
		 RECORD_TYPE, so check for this first.  */
	      if (TYPE_PTRMEMFUNC_P (type))
		write_pointer_to_member_type (type);
	      else
		write_class_enum_type (type);
	      break;

	    case TYPENAME_TYPE:
	    case UNBOUND_CLASS_TEMPLATE:
	      /* We handle TYPENAME_TYPEs and UNBOUND_CLASS_TEMPLATEs like
		 ordinary nested names.  */
	      write_nested_name (TYPE_STUB_DECL (type));
	      break;

	    case POINTER_TYPE:
	    case REFERENCE_TYPE:
	      if (TYPE_PTR_P (type))
		write_char ('P');
	      else if (TYPE_REF_IS_RVALUE (type))
		write_char ('O');
              else
                write_char ('R');
	      {
		tree target = TREE_TYPE (type);
		/* Attribute const/noreturn are not reflected in mangling.
		   We strip them here rather than at a lower level because
		   a typedef or template argument can have function type
		   with function-cv-quals (that use the same representation),
		   but you can't have a pointer/reference to such a type.  */
		if (TREE_CODE (target) == FUNCTION_TYPE)
		  {
		    if (abi_warn_or_compat_version_crosses (5)
			&& TYPE_QUALS (target) != TYPE_UNQUALIFIED)
		      G.need_abi_warning = 1;
		    if (abi_version_at_least (5))
		      target = build_qualified_type (target, TYPE_UNQUALIFIED);
		  }
		write_type (target);
	      }
	      break;

	    case TEMPLATE_TYPE_PARM:
	      if (is_auto (type))
		{
		  if (AUTO_IS_DECLTYPE (type))
		    write_identifier ("Dc");
		  else
		    write_identifier ("Da");
		  ++is_builtin_type;
		  break;
		}
	      /* fall through.  */
	    case TEMPLATE_PARM_INDEX:
	      write_template_param (type);
	      break;

	    case TEMPLATE_TEMPLATE_PARM:
	      write_template_template_param (type);
	      break;

	    case BOUND_TEMPLATE_TEMPLATE_PARM:
	      write_template_template_param (type);
	      write_template_args
		(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
	      break;

	    case VECTOR_TYPE:
	      if (abi_version_at_least (4))
		{
		  write_string ("Dv");
		  /* Non-constant vector size would be encoded with
		     _ expression, but we don't support that yet.  */
		  write_unsigned_number (TYPE_VECTOR_SUBPARTS (type)
					 .to_constant ());
		  write_char ('_');
		}
	      else
		write_string ("U8__vector");
	      if (abi_warn_or_compat_version_crosses (4))
		G.need_abi_warning = 1;
	      write_type (TREE_TYPE (type));
	      break;

            case TYPE_PACK_EXPANSION:
              write_string ("Dp");
              write_type (PACK_EXPANSION_PATTERN (type));
              break;

            case DECLTYPE_TYPE:
	      /* These shouldn't make it into mangling.  */
	      gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type)
			  && !DECLTYPE_FOR_LAMBDA_PROXY (type));

	      /* In ABI <5, we stripped decltype of a plain decl.  */
	      if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
		{
		  tree expr = DECLTYPE_TYPE_EXPR (type);
		  tree etype = NULL_TREE;
		  switch (TREE_CODE (expr))
		    {
		    case VAR_DECL:
		    case PARM_DECL:
		    case RESULT_DECL:
		    case FUNCTION_DECL:
		    case CONST_DECL:
		    case TEMPLATE_PARM_INDEX:
		      etype = TREE_TYPE (expr);
		      break;

		    default:
		      break;
		    }

		  if (etype && !type_uses_auto (etype))
		    {
		      if (abi_warn_or_compat_version_crosses (5))
			G.need_abi_warning = 1;
		      if (!abi_version_at_least (5))
			{
			  write_type (etype);
			  return;
			}
		    }
		}

              write_char ('D');
              if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
                write_char ('t');
              else
                write_char ('T');
	      ++cp_unevaluated_operand;
              write_expression (DECLTYPE_TYPE_EXPR (type));
	      --cp_unevaluated_operand;
              write_char ('E');
              break;

	    case NULLPTR_TYPE:
	      write_string ("Dn");
	      if (abi_version_at_least (7))
		++is_builtin_type;
	      if (abi_warn_or_compat_version_crosses (7))
		G.need_abi_warning = 1;
	      break;

	    case TYPEOF_TYPE:
	      sorry ("mangling %<typeof%>, use %<decltype%> instead");
	      break;

	    case TRAIT_TYPE:
	      error ("use of built-in trait %qT in function signature; "
		     "use library traits instead", type);
	      break;

	    case LANG_TYPE:
	      /* fall through.  */

	    default:
	      gcc_unreachable ();
	    }
	}
    }

  /* Types other than builtin types are substitution candidates.  */
  if (!is_builtin_type)
    add_substitution (type);
}

/* qsort callback for sorting a vector of attribute entries.  */

static int
attr_strcmp (const void *p1, const void *p2)
{
  tree a1 = *(const tree*)p1;
  tree a2 = *(const tree*)p2;

  const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1));
  const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2));

  return strcmp (as1->name, as2->name);
}

/* Return true if we should mangle a type attribute with name NAME.  */

static bool
mangle_type_attribute_p (tree name)
{
  const attribute_spec *as = lookup_attribute_spec (name);
  if (!as || !as->affects_type_identity)
    return false;

  /* Skip internal-only attributes, which are distinguished from others
     by having a space.  At present, all internal-only attributes that
     affect type identity are target-specific and are handled by
     targetm.mangle_type instead.

     Another reason to do this is that a space isn't a valid identifier
     character for most file formats.  */
  if (strchr (IDENTIFIER_POINTER (name), ' '))
    return false;

  /* The following attributes are mangled specially.  */
  if (is_attribute_p ("transaction_safe", name))
    return false;
  if (is_attribute_p ("abi_tag", name))
    return false;

  return true;
}

/* Non-terminal <CV-qualifiers> for type nodes.  Returns the number of
   CV-qualifiers written for TYPE.

     <CV-qualifiers> ::= [r] [V] [K]  */

static int
write_CV_qualifiers_for_type (const tree type)
{
  int num_qualifiers = 0;

  /* The order is specified by:

       "In cases where multiple order-insensitive qualifiers are
       present, they should be ordered 'K' (closest to the base type),
       'V', 'r', and 'U' (farthest from the base type) ..."  */

  /* Mangle attributes that affect type identity as extended qualifiers.

     We don't do this with classes and enums because their attributes
     are part of their definitions, not something added on.  */

  if (!OVERLOAD_TYPE_P (type))
    {
      auto_vec<tree> vec;
      for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
	if (mangle_type_attribute_p (get_attribute_name (a)))
	  vec.safe_push (a);
      if (abi_warn_or_compat_version_crosses (10) && !vec.is_empty ())
	G.need_abi_warning = true;
      if (abi_version_at_least (10))
	{
	  vec.qsort (attr_strcmp);
	  while (!vec.is_empty())
	    {
	      tree a = vec.pop();
	      const attribute_spec *as
		= lookup_attribute_spec (get_attribute_name (a));

	      write_char ('U');
	      write_unsigned_number (strlen (as->name));
	      write_string (as->name);
	      if (TREE_VALUE (a))
		{
		  write_char ('I');
		  for (tree args = TREE_VALUE (a); args;
		       args = TREE_CHAIN (args))
		    {
		      tree arg = TREE_VALUE (args);
		      write_template_arg (arg);
		    }
		  write_char ('E');
		}

	      ++num_qualifiers;
	    }
	}
    }

  /* Note that we do not use cp_type_quals below; given "const
     int[3]", the "const" is emitted with the "int", not with the
     array.  */
  cp_cv_quals quals = TYPE_QUALS (type);

  if (quals & TYPE_QUAL_RESTRICT)
    {
      write_char ('r');
      ++num_qualifiers;
    }
  if (quals & TYPE_QUAL_VOLATILE)
    {
      write_char ('V');
      ++num_qualifiers;
    }
  if (quals & TYPE_QUAL_CONST)
    {
      write_char ('K');
      ++num_qualifiers;
    }

  return num_qualifiers;
}

/* Non-terminal <builtin-type>.

     <builtin-type> ::= v   # void
		    ::= b   # bool
		    ::= w   # wchar_t
		    ::= c   # char
		    ::= a   # signed char
		    ::= h   # unsigned char
		    ::= s   # short
		    ::= t   # unsigned short
		    ::= i   # int
		    ::= j   # unsigned int
		    ::= l   # long
		    ::= m   # unsigned long
		    ::= x   # long long, __int64
		    ::= y   # unsigned long long, __int64
		    ::= n   # __int128
		    ::= o   # unsigned __int128
		    ::= f   # float
		    ::= d   # double
		    ::= e   # long double, __float80
		    ::= g   # __float128          [not supported]
		    ::= u <source-name>  # vendor extended type */

static void
write_builtin_type (tree type)
{
  if (TYPE_CANONICAL (type))
    type = TYPE_CANONICAL (type);

  switch (TREE_CODE (type))
    {
    case VOID_TYPE:
      write_char ('v');
      break;

    case BOOLEAN_TYPE:
      write_char ('b');
      break;

    case INTEGER_TYPE:
      /* TYPE may still be wchar_t, char8_t, char16_t, or char32_t, since that
	 isn't in integer_type_nodes.  */
      if (type == wchar_type_node)
	write_char ('w');
      else if (type == char8_type_node)
	write_string ("Du");
      else if (type == char16_type_node)
	write_string ("Ds");
      else if (type == char32_type_node)
	write_string ("Di");
      else
	{
	  size_t itk;
	  /* Assume TYPE is one of the shared integer type nodes.  Find
	     it in the array of these nodes.  */
	iagain:
	  for (itk = 0; itk < itk_none; ++itk)
	    if (integer_types[itk] != NULL_TREE
		&& integer_type_codes[itk] != '\0'
		&& type == integer_types[itk])
	      {
		/* Print the corresponding single-letter code.  */
		write_char (integer_type_codes[itk]);
		break;
	      }

	  if (itk == itk_none)
	    {
	      tree t = c_common_type_for_mode (TYPE_MODE (type),
					       TYPE_UNSIGNED (type));
	      if (type != t)
		{
		  type = t;
		  goto iagain;
		}

	      if (TYPE_PRECISION (type) == 128)
		write_char (TYPE_UNSIGNED (type) ? 'o' : 'n');
	      else
		{
		  /* Allow for cases where TYPE is not one of the shared
		     integer type nodes and write a "vendor extended builtin
		     type" with a name the form intN or uintN, respectively.
		     Situations like this can happen if you have an
		     __attribute__((__mode__(__SI__))) type and use exotic
		     switches like '-mint8' on AVR.  Of course, this is
		     undefined by the C++ ABI (and '-mint8' is not even
		     Standard C conforming), but when using such special
		     options you're pretty much in nowhere land anyway.  */
		  const char *prefix;
		  char prec[11];	/* up to ten digits for an unsigned */

		  prefix = TYPE_UNSIGNED (type) ? "uint" : "int";
		  sprintf (prec, "%u", (unsigned) TYPE_PRECISION (type));
		  write_char ('u');	/* "vendor extended builtin type" */
		  write_unsigned_number (strlen (prefix) + strlen (prec));
		  write_string (prefix);
		  write_string (prec);
		}
	    }
	}
      break;

    case REAL_TYPE:
      if (type == float_type_node)
	write_char ('f');
      else if (type == double_type_node)
	write_char ('d');
      else if (type == long_double_type_node)
	write_char ('e');
      else if (type == dfloat32_type_node || type == fallback_dfloat32_type)
	write_string ("Df");
      else if (type == dfloat64_type_node || type == fallback_dfloat64_type)
	write_string ("Dd");
      else if (type == dfloat128_type_node || type == fallback_dfloat128_type)
	write_string ("De");
      else if (type == float16_type_node)
	write_string ("DF16_");
      else if (type == float32_type_node)
	write_string ("DF32_");
      else if (type == float64_type_node)
	write_string ("DF64_");
      else if (type == float128_type_node)
	write_string ("DF128_");
      else if (type == float32x_type_node)
	write_string ("DF32x");
      else if (type == float64x_type_node)
	write_string ("DF64x");
      else if (type == float128x_type_node)
	write_string ("DF128x");
      else
	gcc_unreachable ();
      break;

    default:
      gcc_unreachable ();
    }
}

/* Non-terminal <function-type>.  NODE is a FUNCTION_TYPE or
   METHOD_TYPE.  The return type is mangled before the parameter
   types.

     <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E   */

static void
write_function_type (const tree type)
{
  MANGLE_TRACE_TREE ("function-type", type);

  /* For a pointer to member function, the function type may have
     cv-qualifiers, indicating the quals for the artificial 'this'
     parameter.  */
  if (TREE_CODE (type) == METHOD_TYPE)
    {
      /* The first parameter must be a POINTER_TYPE pointing to the
	 `this' parameter.  */
      tree this_type = class_of_this_parm (type);
      write_CV_qualifiers_for_type (this_type);
    }

  write_exception_spec (TYPE_RAISES_EXCEPTIONS (type));

  if (tx_safe_fn_type_p (type))
    write_string ("Dx");

  write_char ('F');
  /* We don't track whether or not a type is `extern "C"'.  Note that
     you can have an `extern "C"' function that does not have
     `extern "C"' type, and vice versa:

       extern "C" typedef void function_t();
       function_t f; // f has C++ linkage, but its type is
		     // `extern "C"'

       typedef void function_t();
       extern "C" function_t f; // Vice versa.

     See [dcl.link].  */
  write_bare_function_type (type, /*include_return_type_p=*/1,
			    /*decl=*/NULL);
  if (FUNCTION_REF_QUALIFIED (type))
    {
      if (FUNCTION_RVALUE_QUALIFIED (type))
	write_char ('O');
      else
	write_char ('R');
    }
  write_char ('E');
}

/* Non-terminal <bare-function-type>.  TYPE is a FUNCTION_TYPE or
   METHOD_TYPE.  If INCLUDE_RETURN_TYPE is nonzero, the return value
   is mangled before the parameter types.  If non-NULL, DECL is
   FUNCTION_DECL for the function whose type is being emitted.  */

static void
write_bare_function_type (const tree type, const int include_return_type_p,
			  const tree decl)
{
  MANGLE_TRACE_TREE ("bare-function-type", type);

  /* Mangle the return type, if requested.  */
  if (include_return_type_p)
    write_type (TREE_TYPE (type));

  /* Now mangle the types of the arguments.  */
  ++G.parm_depth;
  write_method_parms (TYPE_ARG_TYPES (type),
		      TREE_CODE (type) == METHOD_TYPE,
		      decl);
  --G.parm_depth;
}

/* Write the mangled representation of a method parameter list of
   types given in PARM_TYPES.  If METHOD_P is nonzero, the function is
   considered a non-static method, and the this parameter is omitted.
   If non-NULL, DECL is the FUNCTION_DECL for the function whose
   parameters are being emitted.  */

static void
write_method_parms (tree parm_types, const int method_p, const tree decl)
{
  tree first_parm_type;
  tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;

  /* Assume this parameter type list is variable-length.  If it ends
     with a void type, then it's not.  */
  int varargs_p = 1;

  /* If this is a member function, skip the first arg, which is the
     this pointer.
       "Member functions do not encode the type of their implicit this
       parameter."

     Similarly, there's no need to mangle artificial parameters, like
     the VTT parameters for constructors and destructors.  */
  if (method_p)
    {
      parm_types = TREE_CHAIN (parm_types);
      parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE;

      while (parm_decl && DECL_ARTIFICIAL (parm_decl))
	{
	  parm_types = TREE_CHAIN (parm_types);
	  parm_decl = DECL_CHAIN (parm_decl);
	}

      if (decl && ctor_omit_inherited_parms (decl))
	/* Bring back parameters omitted from an inherited ctor.  */
	parm_types = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (decl));
    }

  for (first_parm_type = parm_types;
       parm_types;
       parm_types = TREE_CHAIN (parm_types))
    {
      tree parm = TREE_VALUE (parm_types);
      if (parm == void_type_node)
	{
	  /* "Empty parameter lists, whether declared as () or
	     conventionally as (void), are encoded with a void parameter
	     (v)."  */
	  if (parm_types == first_parm_type)
	    write_type (parm);
	  /* If the parm list is terminated with a void type, it's
	     fixed-length.  */
	  varargs_p = 0;
	  /* A void type better be the last one.  */
	  gcc_assert (TREE_CHAIN (parm_types) == NULL);
	}
      else
	write_type (parm);
    }

  if (varargs_p)
    /* <builtin-type> ::= z  # ellipsis  */
    write_char ('z');
}

/* <class-enum-type> ::= <name>  */

static void
write_class_enum_type (const tree type)
{
  write_name (TYPE_NAME (type), /*ignore_local_scope=*/0);
}

/* Non-terminal <template-args>.  ARGS is a TREE_VEC of template
   arguments.

     <template-args> ::= I <template-arg>* E  */

static void
write_template_args (tree args)
{
  int i;
  int length = 0;

  MANGLE_TRACE_TREE ("template-args", args);

  write_char ('I');

  if (args)
    length = TREE_VEC_LENGTH (args);

  if (args && length && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
    {
      /* We have nested template args.  We want the innermost template
	 argument list.  */
      args = TREE_VEC_ELT (args, length - 1);
      length = TREE_VEC_LENGTH (args);
    }
  for (i = 0; i < length; ++i)
    write_template_arg (TREE_VEC_ELT (args, i));

  write_char ('E');
}

/* Write out the
   <unqualified-name>
   <unqualified-name> <template-args>
   part of SCOPE_REF or COMPONENT_REF mangling.  */

static void
write_member_name (tree member)
{
  if (identifier_p (member))
    {
      if (IDENTIFIER_ANY_OP_P (member))
	{
	  if (abi_version_at_least (11))
	    write_string ("on");
	  if (abi_warn_or_compat_version_crosses (11))
	    G.need_abi_warning = 1;
	}
      write_unqualified_id (member);
    }
  else if (DECL_P (member))
    {
      gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member));
      write_unqualified_name (member);
    }
  else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
    {
      tree name = TREE_OPERAND (member, 0);
      name = OVL_FIRST (name);
      write_member_name (name);
      write_template_args (TREE_OPERAND (member, 1));
    }
  else
    write_expression (member);
}

/* EXPR is a base COMPONENT_REF; write the minimized base conversion path for
   converting to BASE, or just the conversion of EXPR if BASE is null.

   "Given a fully explicit base path P := C_n -> ... -> C_0, the minimized base
   path Min(P) is defined as follows: let C_i be the last element for which the
   conversion to C_0 is unambiguous; if that element is C_n, the minimized path
   is C_n -> C_0; otherwise, the minimized path is Min(C_n -> ... -> C_i) ->
   C_0."

   We mangle the conversion to C_i if it's different from C_n.  */

static bool
write_base_ref (tree expr, tree base = NULL_TREE)
{
  if (TREE_CODE (expr) != COMPONENT_REF)
    return false;

  tree field = TREE_OPERAND (expr, 1);

  if (TREE_CODE (field) != FIELD_DECL || !DECL_FIELD_IS_BASE (field))
    return false;

  tree object = TREE_OPERAND (expr, 0);

  tree binfo = NULL_TREE;
  if (base)
    {
      tree cur = TREE_TYPE (object);
      binfo = lookup_base (cur, base, ba_unique, NULL, tf_none);
    }
  else
    /* We're at the end of the base conversion chain, so it can't be
       ambiguous.  */
    base = TREE_TYPE (field);

  if (binfo == error_mark_node)
    {
      /* cur->base is ambiguous, so make the conversion to
	 last explicit, expressed as a cast (last&)object.  */
      tree last = TREE_TYPE (expr);
      write_string (OVL_OP_INFO (false, CAST_EXPR)->mangled_name);
      write_type (build_reference_type (last));
      write_expression (object);
    }
  else if (write_base_ref (object, base))
    /* cur->base is unambiguous, but we had another base conversion
       underneath and wrote it out.  */;
  else
    /* No more base conversions, just write out the object.  */
    write_expression (object);

  return true;
}

/* The number of elements spanned by a RANGE_EXPR.  */

unsigned HOST_WIDE_INT
range_expr_nelts (tree expr)
{
  tree lo = TREE_OPERAND (expr, 0);
  tree hi = TREE_OPERAND (expr, 1);
  return tree_to_uhwi (hi) - tree_to_uhwi (lo) + 1;
}

/* <expression> ::= <unary operator-name> <expression>
		::= <binary operator-name> <expression> <expression>
		::= <expr-primary>

   <expr-primary> ::= <template-param>
		  ::= L <type> <value number> E		# literal
		  ::= L <mangled-name> E		# external name
		  ::= st <type>				# sizeof
		  ::= sr <type> <unqualified-name>	# dependent name
		  ::= sr <type> <unqualified-name> <template-args> */

static void
write_expression (tree expr)
{
  enum tree_code code = TREE_CODE (expr);

  if (TREE_CODE (expr) == TARGET_EXPR)
    {
      expr = TARGET_EXPR_INITIAL (expr);
      code = TREE_CODE (expr);
    }

  /* Skip NOP_EXPR and CONVERT_EXPR.  They can occur when (say) a pointer
     argument is converted (via qualification conversions) to another type.  */
  while (CONVERT_EXPR_CODE_P (code)
	 || code == IMPLICIT_CONV_EXPR
	 || location_wrapper_p (expr)
	 /* Parentheses aren't mangled.  */
	 || code == PAREN_EXPR
	 || code == NON_LVALUE_EXPR
	 || (code == VIEW_CONVERT_EXPR
	     && TREE_CODE (TREE_OPERAND (expr, 0)) == TEMPLATE_PARM_INDEX))
    {
      expr = TREE_OPERAND (expr, 0);
      code = TREE_CODE (expr);
    }

  if (code == BASELINK
      && (!type_unknown_p (expr)
	  || !BASELINK_QUALIFIED_P (expr)))
    {
      expr = BASELINK_FUNCTIONS (expr);
      code = TREE_CODE (expr);
    }

  /* Handle pointers-to-members by making them look like expression
     nodes.  */
  if (code == PTRMEM_CST)
    {
      expr = build_nt (ADDR_EXPR,
		       build_qualified_name (/*type=*/NULL_TREE,
					     PTRMEM_CST_CLASS (expr),
					     PTRMEM_CST_MEMBER (expr),
					     /*template_p=*/false));
      code = TREE_CODE (expr);
    }

  /* Handle template parameters.  */
  if (code == TEMPLATE_TYPE_PARM
      || code == TEMPLATE_TEMPLATE_PARM
      || code == BOUND_TEMPLATE_TEMPLATE_PARM
      || code == TEMPLATE_PARM_INDEX)
    write_template_param (expr);
  /* Handle literals.  */
  else if (TREE_CODE_CLASS (code) == tcc_constant
	   || code == CONST_DECL)
    write_template_arg_literal (expr);
  else if (code == PARM_DECL && DECL_ARTIFICIAL (expr))
    {
      gcc_assert (id_equal (DECL_NAME (expr), "this"));
      write_string ("fpT");
    }
  else if (code == PARM_DECL)
    {
      /* A function parameter used in a late-specified return type.  */
      int index = DECL_PARM_INDEX (expr);
      int level = DECL_PARM_LEVEL (expr);
      int delta = G.parm_depth - level + 1;
      gcc_assert (index >= 1);
      write_char ('f');
      if (delta != 0)
	{
	  if (abi_version_at_least (5))
	    {
	      /* Let L be the number of function prototype scopes from the
		 innermost one (in which the parameter reference occurs) up
		 to (and including) the one containing the declaration of
		 the referenced parameter.  If the parameter declaration
		 clause of the innermost function prototype scope has been
		 completely seen, it is not counted (in that case -- which
		 is perhaps the most common -- L can be zero).  */
	      write_char ('L');
	      write_unsigned_number (delta - 1);
	    }
	  if (abi_warn_or_compat_version_crosses (5))
	    G.need_abi_warning = true;
	}
      write_char ('p');
      write_compact_number (index - 1);
    }
  else if (DECL_P (expr))
    {
      write_char ('L');
      write_mangled_name (expr, false);
      write_char ('E');
    }
  else if (TREE_CODE (expr) == SIZEOF_EXPR)
    {
      tree op = TREE_OPERAND (expr, 0);

      if (PACK_EXPANSION_P (op))
	{
	  if (abi_warn_or_compat_version_crosses (11))
	    G.need_abi_warning = true;
	  if (abi_version_at_least (11))
	    {
	      /* sZ rather than szDp.  */
	      write_string ("sZ");
	      write_expression (PACK_EXPANSION_PATTERN (op));
	      return;
	    }
	}

      if (SIZEOF_EXPR_TYPE_P (expr))
	{
	  write_string ("st");
	  write_type (TREE_TYPE (op));
	}
      else if (ARGUMENT_PACK_P (op))
	{
	  tree args = ARGUMENT_PACK_ARGS (op);
	  int length = TREE_VEC_LENGTH (args);
	  if (abi_warn_or_compat_version_crosses (10))
	    G.need_abi_warning = true;
	  if (abi_version_at_least (10))
	    {
	      /* sP <template-arg>* E # sizeof...(T), size of a captured
		 template parameter pack from an alias template */
	      write_string ("sP");
	      for (int i = 0; i < length; ++i)
		write_template_arg (TREE_VEC_ELT (args, i));
	      write_char ('E');
	    }
	  else
	    {
	      /* In GCC 5 we represented this sizeof wrong, with the effect
		 that we mangled it as the last element of the pack.  */
	      tree arg = TREE_VEC_ELT (args, length-1);
	      if (TYPE_P (op))
		{
		  write_string ("st");
		  write_type (arg);
		}
	      else
		{
		  write_string ("sz");
		  write_expression (arg);
		}
	    }
	}
      else if (TYPE_P (TREE_OPERAND (expr, 0)))
	{
	  write_string ("st");
	  write_type (TREE_OPERAND (expr, 0));
	}
      else
	goto normal_expr;
    }
  else if (TREE_CODE (expr) == ALIGNOF_EXPR)
    {
      if (!ALIGNOF_EXPR_STD_P (expr))
	{
	  if (abi_warn_or_compat_version_crosses (16))
	    G.need_abi_warning = true;
	  if (abi_version_at_least (16))
	    {
	      /* We used to mangle __alignof__ like alignof.  */
	      write_string ("u11__alignof__");
	      write_template_arg (TREE_OPERAND (expr, 0));
	      write_char ('E');
	      return;
	    }
	}
      if (TYPE_P (TREE_OPERAND (expr, 0)))
	{
	  write_string ("at");
	  write_type (TREE_OPERAND (expr, 0));
	}
      else
	goto normal_expr;
    }
  else if (code == SCOPE_REF
	   || code == BASELINK)
    {
      tree scope, member;
      if (code == SCOPE_REF)
	{
	  scope = TREE_OPERAND (expr, 0);
	  member = TREE_OPERAND (expr, 1);
	  if (BASELINK_P (member))
	    member = BASELINK_FUNCTIONS (member);
	}
      else
	{
	  scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (expr));
	  member = BASELINK_FUNCTIONS (expr);
	}

      /* If the MEMBER is a real declaration, then the qualifying
	 scope was not dependent.  Ideally, we would not have a
	 SCOPE_REF in those cases, but sometimes we do.  If the second
	 argument is a DECL, then the name must not have been
	 dependent.  */
      if (DECL_P (member))
	write_expression (member);
      else
	{
	  gcc_assert (code != BASELINK || BASELINK_QUALIFIED_P (expr));
	  write_string ("sr");
	  write_type (scope);
	  write_member_name (member);
	}
    }
  else if (INDIRECT_REF_P (expr)
	   && TREE_TYPE (TREE_OPERAND (expr, 0))
	   && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
    {
      write_expression (TREE_OPERAND (expr, 0));
    }
  else if (identifier_p (expr))
    {
      /* An operator name appearing as a dependent name needs to be
	 specially marked to disambiguate between a use of the operator
	 name and a use of the operator in an expression.  */
      if (IDENTIFIER_ANY_OP_P (expr))
	write_string ("on");
      write_unqualified_id (expr);
    }
  else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
    {
      tree fn = TREE_OPERAND (expr, 0);
      fn = OVL_NAME (fn);
      if (IDENTIFIER_ANY_OP_P (fn))
	write_string ("on");
      write_unqualified_id (fn);
      write_template_args (TREE_OPERAND (expr, 1));
    }
  else if (TREE_CODE (expr) == MODOP_EXPR)
    {
      enum tree_code subop = TREE_CODE (TREE_OPERAND (expr, 1));
      const char *name = OVL_OP_INFO (true, subop)->mangled_name;

      write_string (name);
      write_expression (TREE_OPERAND (expr, 0));
      write_expression (TREE_OPERAND (expr, 2));
    }
  else if (code == NEW_EXPR || code == VEC_NEW_EXPR)
    {
      /* ::= [gs] nw <expression>* _ <type> E
	 ::= [gs] nw <expression>* _ <type> <initializer>
	 ::= [gs] na <expression>* _ <type> E
	 ::= [gs] na <expression>* _ <type> <initializer>
	 <initializer> ::= pi <expression>* E  */
      tree placement = TREE_OPERAND (expr, 0);
      tree type = TREE_OPERAND (expr, 1);
      tree nelts = TREE_OPERAND (expr, 2);
      tree init = TREE_OPERAND (expr, 3);
      tree t;

      gcc_assert (code == NEW_EXPR);
      if (TREE_OPERAND (expr, 2))
	code = VEC_NEW_EXPR;

      if (NEW_EXPR_USE_GLOBAL (expr))
	write_string ("gs");

      write_string (OVL_OP_INFO (false, code)->mangled_name);

      for (t = placement; t; t = TREE_CHAIN (t))
	write_expression (TREE_VALUE (t));

      write_char ('_');

      if (nelts)
	{
	  tree domain;
	  ++processing_template_decl;
	  domain = compute_array_index_type (NULL_TREE, nelts,
					     tf_warning_or_error);
	  type = build_cplus_array_type (type, domain);
	  --processing_template_decl;
	}
      write_type (type);

      if (init && TREE_CODE (init) == TREE_LIST
	  && DIRECT_LIST_INIT_P (TREE_VALUE (init)))
	write_expression (TREE_VALUE (init));
      else
	{
	  if (init)
	    write_string ("pi");
	  if (init && init != void_node)
	    for (t = init; t; t = TREE_CHAIN (t))
	      write_expression (TREE_VALUE (t));
	  write_char ('E');
	}
    }
  else if (code == DELETE_EXPR || code == VEC_DELETE_EXPR)
    {
      gcc_assert (code == DELETE_EXPR);
      if (DELETE_EXPR_USE_VEC (expr))
	code = VEC_DELETE_EXPR;

      if (DELETE_EXPR_USE_GLOBAL (expr))
	write_string ("gs");

      write_string (OVL_OP_INFO (false, code)->mangled_name);

      write_expression (TREE_OPERAND (expr, 0));
    }
  else if (code == THROW_EXPR)
    {
      tree op = TREE_OPERAND (expr, 0);
      if (op)
	{
	  write_string ("tw");
	  write_expression (op);
	}
      else
	write_string ("tr");
    }
  else if (code == CONSTRUCTOR)
    {
      bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr);
      tree etype = TREE_TYPE (expr);

      if (braced_init)
	write_string ("il");
      else
	{
	  write_string ("tl");
	  write_type (etype);
	}

      /* If this is an undigested initializer, mangle it as written.
	 COMPOUND_LITERAL_P doesn't actually distinguish between digested and
	 undigested braced casts, but it should work to use it to distinguish
	 between braced casts in a template signature (undigested) and template
	 parm object values (digested), and all CONSTRUCTORS that get here
	 should be one of those two cases.  */
      bool undigested = braced_init || COMPOUND_LITERAL_P (expr);
      if (undigested || !zero_init_expr_p (expr))
	{
	  /* Convert braced initializer lists to STRING_CSTs so that
	     A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while
	     still using the latter mangling for strings that
	     originated as braced initializer lists.  */
	  expr = braced_lists_to_strings (etype, expr);

	  if (TREE_CODE (expr) == CONSTRUCTOR)
	    {
	      vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr);
	      unsigned last_nonzero = UINT_MAX;
	      constructor_elt *ce;

	      if (!undigested)
		for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
		  if ((TREE_CODE (etype) == UNION_TYPE
		       && ce->index != first_field (etype))
		      || !zero_init_expr_p (ce->value))
		    last_nonzero = i;

	      if (undigested || last_nonzero != UINT_MAX)
		for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
		  {
		    if (i > last_nonzero)
		      break;
		    if (!undigested && TREE_CODE (etype) == UNION_TYPE)
		      {
			/* Express the active member as a designator.  */
			write_string ("di");
			write_unqualified_name (ce->index);
		      }
		    unsigned reps = 1;
		    if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
		      reps = range_expr_nelts (ce->index);
		    for (unsigned j = 0; j < reps; ++j)
		      write_expression (ce->value);
		  }
	    }
	  else
	    {
	      gcc_assert (TREE_CODE (expr) == STRING_CST);
	      write_expression (expr);
	    }
	}
      write_char ('E');
    }
  else if (code == LAMBDA_EXPR)
    {
      /* [temp.over.link] Two lambda-expressions are never considered
	 equivalent.

	 So just use the closure type mangling.  */
      write_string ("tl");
      write_type (LAMBDA_EXPR_CLOSURE (expr));
      write_char ('E');
    }
  else if (dependent_name (expr))
    {
      tree name = dependent_name (expr);
      if (IDENTIFIER_ANY_OP_P (name))
	{
	  if (abi_version_at_least (16))
	    write_string ("on");
	  if (abi_warn_or_compat_version_crosses (16))
	    G.need_abi_warning = 1;
	}
      write_unqualified_id (name);
    }
  else
    {
    normal_expr:
      int i, len;
      const char *name;

      /* When we bind a variable or function to a non-type template
	 argument with reference type, we create an ADDR_EXPR to show
	 the fact that the entity's address has been taken.  But, we
	 don't actually want to output a mangling code for the `&'.  */
      if (TREE_CODE (expr) == ADDR_EXPR
	  && TREE_TYPE (expr)
	  && TYPE_REF_P (TREE_TYPE (expr)))
	{
	  expr = TREE_OPERAND (expr, 0);
	  if (DECL_P (expr))
	    {
	      write_expression (expr);
	      return;
	    }

	  code = TREE_CODE (expr);
	}

      if (code == COMPONENT_REF)
	{
	  tree ob = TREE_OPERAND (expr, 0);

	  if (TREE_CODE (ob) == ARROW_EXPR)
	    {
	      write_string (OVL_OP_INFO (false, code)->mangled_name);
	      ob = TREE_OPERAND (ob, 0);
	      write_expression (ob);
	    }
	  else if (write_base_ref (expr))
	    return;
	  else if (!is_dummy_object (ob))
	    {
	      write_string ("dt");
	      write_expression (ob);
	    }
	  /* else, for a non-static data member with no associated object (in
	     unevaluated context), use the unresolved-name mangling.  */

	  write_member_name (TREE_OPERAND (expr, 1));
	  return;
	}

      /* If it wasn't any of those, recursively expand the expression.  */
      name = OVL_OP_INFO (false, code)->mangled_name;

      /* We used to mangle const_cast and static_cast like a C cast.  */
      if (code == CONST_CAST_EXPR
	  || code == STATIC_CAST_EXPR)
	{
	  if (abi_warn_or_compat_version_crosses (6))
	    G.need_abi_warning = 1;
	  if (!abi_version_at_least (6))
	    name = OVL_OP_INFO (false, CAST_EXPR)->mangled_name;
	}

      if (name == NULL)
	{
	  switch (code)
	    {
	    case TRAIT_EXPR:
	      error ("use of built-in trait %qE in function signature; "
		     "use library traits instead", expr);
	      break;

	    default:
	      sorry ("mangling %C", code);
	      break;
	    }
	  return;
	}
      else
	write_string (name);	

      switch (code)
	{
	case CALL_EXPR:
	  {
	    tree fn = CALL_EXPR_FN (expr);

	    if (TREE_CODE (fn) == ADDR_EXPR)
	      fn = TREE_OPERAND (fn, 0);

	    /* Mangle a dependent name as the name, not whatever happens to
	       be the first function in the overload set.  */
	    if (OVL_P (fn)
		&& type_dependent_expression_p_push (expr))
	      fn = OVL_NAME (fn);

	    write_expression (fn);
	  }

	  for (i = 0; i < call_expr_nargs (expr); ++i)
	    write_expression (CALL_EXPR_ARG (expr, i));
	  write_char ('E');
	  break;

	case CAST_EXPR:
	  write_type (TREE_TYPE (expr));
	  if (list_length (TREE_OPERAND (expr, 0)) == 1)	  
	    write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
	  else
	    {
	      tree args = TREE_OPERAND (expr, 0);
	      write_char ('_');
	      for (; args; args = TREE_CHAIN (args))
		write_expression (TREE_VALUE (args));
	      write_char ('E');
	    }
	  break;

	case DYNAMIC_CAST_EXPR:
	case REINTERPRET_CAST_EXPR:
	case STATIC_CAST_EXPR:
	case CONST_CAST_EXPR:
	  write_type (TREE_TYPE (expr));
	  write_expression (TREE_OPERAND (expr, 0));
	  break;

	case PREINCREMENT_EXPR:
	case PREDECREMENT_EXPR:
	  if (abi_version_at_least (6))
	    write_char ('_');
	  if (abi_warn_or_compat_version_crosses (6))
	    G.need_abi_warning = 1;
	  /* Fall through.  */

	default:
	  /* In the middle-end, some expressions have more operands than
	     they do in templates (and mangling).  */
	  len = cp_tree_operand_length (expr);

	  for (i = 0; i < len; ++i)
	    {
	      tree operand = TREE_OPERAND (expr, i);
	      /* As a GNU extension, the middle operand of a
		 conditional may be omitted.  Since expression
		 manglings are supposed to represent the input token
		 stream, there's no good way to mangle such an
		 expression without extending the C++ ABI.  */
	      if (code == COND_EXPR && i == 1 && !operand)
		{
		  error ("omitted middle operand to %<?:%> operand "
			 "cannot be mangled");
		  continue;
		}
	      else if (FOLD_EXPR_P (expr))
		{
		  /* The first 'operand' of a fold-expression is the operator
		     that it folds over.  */
		  if (i == 0)
		    {
		      int fcode = TREE_INT_CST_LOW (operand);
		      write_string (OVL_OP_INFO (false, fcode)->mangled_name);
		      continue;
		    }
		  else if (code == BINARY_LEFT_FOLD_EXPR)
		    {
		      /* The order of operands of the binary left and right
			 folds is the same, but we want to mangle them in
			 lexical order, i.e. non-pack first.  */
		      if (i == 1)
			operand = FOLD_EXPR_INIT (expr);
		      else
			operand = FOLD_EXPR_PACK (expr);
		    }
		  if (PACK_EXPANSION_P (operand))
		    operand = PACK_EXPANSION_PATTERN (operand);
		}
	      write_expression (operand);
	    }
	}
    }
}

/* Literal subcase of non-terminal <template-arg>.

     "Literal arguments, e.g. "A<42L>", are encoded with their type
     and value. Negative integer values are preceded with "n"; for
     example, "A<-42L>" becomes "1AILln42EE". The bool value false is
     encoded as 0, true as 1."  */

static void
write_template_arg_literal (const tree value)
{
  if (TREE_CODE (value) == STRING_CST)
    /* Temporarily mangle strings as braced initializer lists.  */
    write_string ("tl");
  else
    write_char ('L');

  tree valtype = TREE_TYPE (value);
  write_type (valtype);

  /* Write a null member pointer value as (type)0, regardless of its
     real representation.  */
  if (null_member_pointer_value_p (value))
    write_integer_cst (integer_zero_node);
  else
    switch (TREE_CODE (value))
      {
      case CONST_DECL:
	write_integer_cst (DECL_INITIAL (value));
	break;

      case INTEGER_CST:
	gcc_assert (!same_type_p (TREE_TYPE (value), boolean_type_node)
		    || integer_zerop (value) || integer_onep (value));
	if (!(abi_version_at_least (14)
	      && NULLPTR_TYPE_P (TREE_TYPE (value))))
	  write_integer_cst (value);
	break;

      case REAL_CST:
	write_real_cst (value);
	break;

      case COMPLEX_CST:
	if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST
	    && TREE_CODE (TREE_IMAGPART (value)) == INTEGER_CST)
	  {
	    write_integer_cst (TREE_REALPART (value));
	    write_char ('_');
	    write_integer_cst (TREE_IMAGPART (value));
	  }
	else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST
		 && TREE_CODE (TREE_IMAGPART (value)) == REAL_CST)
	  {
	    write_real_cst (TREE_REALPART (value));
	    write_char ('_');
	    write_real_cst (TREE_IMAGPART (value));
	  }
	else
	  gcc_unreachable ();
	break;

      case STRING_CST:
	{
	  /* Mangle strings the same as braced initializer lists.  */
	  unsigned n = TREE_STRING_LENGTH (value);
	  const char *str = TREE_STRING_POINTER (value);

	  /* Count the number of trailing nuls and subtract them from
	     STRSIZE because they don't need to be mangled.  */
	  for (const char *p = str + n - 1; ; --p)
	    {
	      if (*p || p == str)
		{
		  n -= str + n - !!*p - p;
		  break;
		}
	    }
	  tree eltype = TREE_TYPE (valtype);
	  for (const char *p = str; n--; ++p)
	    {
	      write_char ('L');
	      write_type (eltype);
	      write_unsigned_number (*(const unsigned char*)p);
	      write_string ("E");
	    }
	  break;
	}

      default:
	gcc_unreachable ();
      }

  write_char ('E');
}

/* Non-terminal <template-arg>.

     <template-arg> ::= <type>				# type
		    ::= L <type> </value/ number> E	# literal
		    ::= LZ <name> E			# external name
		    ::= X <expression> E		# expression  */

static void
write_template_arg (tree node)
{
  enum tree_code code = TREE_CODE (node);

  MANGLE_TRACE_TREE ("template-arg", node);

  /* A template template parameter's argument list contains TREE_LIST
     nodes of which the value field is the actual argument.  */
  if (code == TREE_LIST)
    {
      node = TREE_VALUE (node);
      /* If it's a decl, deal with its type instead.  */
      if (DECL_P (node))
	{
	  node = TREE_TYPE (node);
	  code = TREE_CODE (node);
	}
    }

  if (TREE_CODE (node) == VAR_DECL && DECL_NTTP_OBJECT_P (node))
    /* We want to mangle the argument, not the var we stored it in.  */
    node = tparm_object_argument (node);

  /* Strip a conversion added by convert_nontype_argument.  */
  if (TREE_CODE (node) == IMPLICIT_CONV_EXPR)
    node = TREE_OPERAND (node, 0);
  if (REFERENCE_REF_P (node))
    node = TREE_OPERAND (node, 0);
  if (TREE_CODE (node) == NOP_EXPR
      && TYPE_REF_P (TREE_TYPE (node)))
    {
      /* Template parameters can be of reference type. To maintain
	 internal consistency, such arguments use a conversion from
	 address of object to reference type.  */
      gcc_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR);
      node = TREE_OPERAND (TREE_OPERAND (node, 0), 0);
    }

  if (TREE_CODE (node) == BASELINK
      && !type_unknown_p (node))
    {
      if (abi_version_at_least (6))
	node = BASELINK_FUNCTIONS (node);
      if (abi_warn_or_compat_version_crosses (6))
	/* We wrongly wrapped a class-scope function in X/E.  */
	G.need_abi_warning = 1;
    }

  if (ARGUMENT_PACK_P (node))
    {
      /* Expand the template argument pack. */
      tree args = ARGUMENT_PACK_ARGS (node);
      int i, length = TREE_VEC_LENGTH (args);
      if (abi_version_at_least (6))
	write_char ('J');
      else
	write_char ('I');
      if (abi_warn_or_compat_version_crosses (6))
	G.need_abi_warning = 1;
      for (i = 0; i < length; ++i)
        write_template_arg (TREE_VEC_ELT (args, i));
      write_char ('E');
    }
  else if (TYPE_P (node))
    write_type (node);
  else if (code == TEMPLATE_DECL)
    /* A template appearing as a template arg is a template template arg.  */
    write_template_template_arg (node);
  else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST)
	   || code == CONST_DECL
	   || null_member_pointer_value_p (node))
    write_template_arg_literal (node);
  else if (DECL_P (node))
    {
      write_char ('L');
      /* Until ABI version 3, the underscore before the mangled name
	 was incorrectly omitted.  */
      if (!abi_version_at_least (3))
	write_char ('Z');
      else
	write_string ("_Z");
      if (abi_warn_or_compat_version_crosses (3))
	G.need_abi_warning = 1;
      write_encoding (node);
      write_char ('E');
    }
  else
    {
      /* Template arguments may be expressions.  */
      write_char ('X');
      write_expression (node);
      write_char ('E');
    }
}

/*  <template-template-arg>
			::= <name>
			::= <substitution>  */

static void
write_template_template_arg (const tree decl)
{
  MANGLE_TRACE_TREE ("template-template-arg", decl);

  if (find_substitution (decl))
    return;
  write_name (decl, /*ignore_local_scope=*/0);
  add_substitution (decl);
}


/* Non-terminal <array-type>.  TYPE is an ARRAY_TYPE.

     <array-type> ::= A [</dimension/ number>] _ </element/ type>
		  ::= A <expression> _ </element/ type>

     "Array types encode the dimension (number of elements) and the
     element type.  For variable length arrays, the dimension (but not
     the '_' separator) is omitted."
     Note that for flexible array members, like for other arrays of
     unspecified size, the dimension is also omitted.  */

static void
write_array_type (const tree type)
{
  write_char ('A');
  if (TYPE_DOMAIN (type))
    {
      tree index_type;

      index_type = TYPE_DOMAIN (type);
      /* The INDEX_TYPE gives the upper and lower bounds of the array.
	 It's null for flexible array members which have no upper bound
	 (this is a change from GCC 5 and prior where such members were
	 incorrectly mangled as zero-length arrays).  */
      if (tree max = TYPE_MAX_VALUE (index_type))
	{
	  if (TREE_CODE (max) == INTEGER_CST)
	    {
	      /* The ABI specifies that we should mangle the number of
		 elements in the array, not the largest allowed index.  */
	      offset_int wmax = wi::to_offset (max) + 1;
	      /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
		 number of elements as zero.  */
	      wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
	      gcc_assert (wi::fits_uhwi_p (wmax));
	      write_unsigned_number (wmax.to_uhwi ());
	    }
	  else
	    {
	      max = TREE_OPERAND (max, 0);
	      write_expression (max);
	    }
	}
    }
  write_char ('_');
  write_type (TREE_TYPE (type));
}

/* Non-terminal <pointer-to-member-type> for pointer-to-member
   variables.  TYPE is a pointer-to-member POINTER_TYPE.

     <pointer-to-member-type> ::= M </class/ type> </member/ type>  */

static void
write_pointer_to_member_type (const tree type)
{
  write_char ('M');
  write_type (TYPE_PTRMEM_CLASS_TYPE (type));
  write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type));
}

/* Non-terminal <template-param>.  PARM is a TEMPLATE_TYPE_PARM,
   TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
   TEMPLATE_PARM_INDEX.

     <template-param> ::= T </parameter/ number> _  */

static void
write_template_param (const tree parm)
{
  int parm_index;

  MANGLE_TRACE_TREE ("template-parm", parm);

  switch (TREE_CODE (parm))
    {
    case TEMPLATE_TYPE_PARM:
    case TEMPLATE_TEMPLATE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
      parm_index = TEMPLATE_TYPE_IDX (parm);
      break;

    case TEMPLATE_PARM_INDEX:
      parm_index = TEMPLATE_PARM_IDX (parm);
      break;

    default:
      gcc_unreachable ();
    }

  write_char ('T');
  /* NUMBER as it appears in the mangling is (-1)-indexed, with the
     earliest template param denoted by `_'.  */
  write_compact_number (parm_index);
}

/*  <template-template-param>
			::= <template-param>
			::= <substitution>  */

static void
write_template_template_param (const tree parm)
{
  tree templ = NULL_TREE;

  /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
     template template parameter.  The substitution candidate here is
     only the template.  */
  if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
    {
      templ
	= TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
      if (find_substitution (templ))
	return;
    }

  /* <template-param> encodes only the template parameter position,
     not its template arguments, which is fine here.  */
  write_template_param (parm);
  if (templ)
    add_substitution (templ);
}

/* Non-terminal <substitution>.

      <substitution> ::= S <seq-id> _
		     ::= S_  */

static void
write_substitution (const int seq_id)
{
  MANGLE_TRACE ("substitution", "");

  write_char ('S');
  if (seq_id > 0)
    write_number (seq_id - 1, /*unsigned=*/1, 36);
  write_char ('_');
}

/* Start mangling ENTITY.  */

static inline void
start_mangling (const tree entity)
{
  G.entity = entity;
  G.need_abi_warning = false;
  G.need_cxx17_warning = false;
  G.mod = false;
  obstack_free (&name_obstack, name_base);
  mangle_obstack = &name_obstack;
  name_base = obstack_alloc (&name_obstack, 0);
}

/* Done with mangling.  Release the data.  */

static void
finish_mangling_internal (void)
{
  /* Clear all the substitutions.  */
  vec_safe_truncate (G.substitutions, 0);

  if (G.mod)
    mangle_module_fini ();

  /* Null-terminate the string.  */
  write_char ('\0');
}


/* Like finish_mangling_internal, but return the mangled string.  */

static inline const char *
finish_mangling (void)
{
  finish_mangling_internal ();
  return (const char *) obstack_finish (mangle_obstack);
}

/* Like finish_mangling_internal, but return an identifier.  */

static tree
finish_mangling_get_identifier (void)
{
  finish_mangling_internal ();
  /* Don't obstack_finish here, and the next start_mangling will
     remove the identifier.  */
  return get_identifier ((const char *) obstack_base (mangle_obstack));
}

/* Initialize data structures for mangling.  */

void
init_mangle (void)
{
  gcc_obstack_init (&name_obstack);
  name_base = obstack_alloc (&name_obstack, 0);
  vec_alloc (G.substitutions, 0);

  /* Cache these identifiers for quick comparison when checking for
     standard substitutions.  */
  subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator");
  subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string");
  subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits");
  subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream");
  subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream");
  subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
}

/* Generate a mangling for MODULE's global initializer fn.  */

tree
mangle_module_global_init (int module)
{
  start_mangling (NULL_TREE);

  write_string ("_ZGI");
  write_module (module, true);

  return finish_mangling_get_identifier ();
}

/* Generate the mangled name of DECL.  */

static tree
mangle_decl_string (const tree decl)
{
  tree result;
  tree saved_fn = NULL_TREE;
  bool template_p = false;

  /* We shouldn't be trying to mangle an uninstantiated template.  */
  gcc_assert (!type_dependent_expression_p (decl));

  if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
    {
      struct tinst_level *tl = current_instantiation ();
      if ((!tl || tl->maybe_get_node () != decl)
	  && push_tinst_level (decl))
	{
	  template_p = true;
	  saved_fn = current_function_decl;
	  current_function_decl = NULL_TREE;
	}
    }
  iloc_sentinel ils (DECL_SOURCE_LOCATION (decl));

  start_mangling (decl);

  if (TREE_CODE (decl) == TYPE_DECL)
    write_type (TREE_TYPE (decl));
  else
    write_mangled_name (decl, true);

  result = finish_mangling_get_identifier ();
  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_decl_string = '%s'\n\n",
	     IDENTIFIER_POINTER (result));

  if (template_p)
    {
      pop_tinst_level ();
      current_function_decl = saved_fn;
    }

  return result;
}

/* Return an identifier for the external mangled name of DECL.  */

static tree
get_mangled_id (tree decl)
{
  tree id = mangle_decl_string (decl);
  return targetm.mangle_decl_assembler_name (decl, id);
}

/* Create an identifier for the external mangled name of DECL.  */

void
mangle_decl (const tree decl)
{
  tree id;
  bool dep;

  /* Don't bother mangling uninstantiated templates.  */
  ++processing_template_decl;
  if (TREE_CODE (decl) == TYPE_DECL)
    dep = dependent_type_p (TREE_TYPE (decl));
  else
    dep = (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
	   && any_dependent_template_arguments_p (DECL_TI_ARGS (decl)));
  --processing_template_decl;
  if (dep)
    return;

  /* During LTO we keep mangled names of TYPE_DECLs for ODR type merging.
     It is not needed to assign names to anonymous namespace, but we use the
     "<anon>" marker to be able to tell if type is C++ ODR type or type
     produced by other language.  */
  if (TREE_CODE (decl) == TYPE_DECL
      && TYPE_STUB_DECL (TREE_TYPE (decl))
      && !TREE_PUBLIC (TYPE_STUB_DECL (TREE_TYPE (decl))))
    id = get_identifier ("<anon>");
  else
    {
      gcc_assert (TREE_CODE (decl) != TYPE_DECL
		  || !no_linkage_check (TREE_TYPE (decl), true));
      if (abi_version_at_least (10))
	if (tree fn = decl_function_context (decl))
	  maybe_check_abi_tags (fn, decl);
      id = get_mangled_id (decl);
    }
  SET_DECL_ASSEMBLER_NAME (decl, id);

  if (G.need_cxx17_warning
      && (TREE_PUBLIC (decl) || DECL_REALLY_EXTERN (decl)))
    warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wnoexcept_type,
		"mangled name for %qD will change in C++17 because the "
		"exception specification is part of a function type",
		decl);

  if (id != DECL_NAME (decl)
      /* Don't do this for a fake symbol we aren't going to emit anyway.  */
      && TREE_CODE (decl) != TYPE_DECL
      && !DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
    {
      int save_ver = flag_abi_version;
      tree id2 = NULL_TREE;

      if (!DECL_REALLY_EXTERN (decl))
	{
	  record_mangling (decl, G.need_abi_warning);

	  if (!G.need_abi_warning)
	    return;

	  flag_abi_version = flag_abi_compat_version;
	  id2 = mangle_decl_string (decl);
	  id2 = targetm.mangle_decl_assembler_name (decl, id2);
	  flag_abi_version = save_ver;

	  if (id2 != id)
	    note_mangling_alias (decl, id2);
	}

      if (warn_abi)
	{
	  const char fabi_version[] = "-fabi-version";

	  if (flag_abi_compat_version != warn_abi_version
	      || id2 == NULL_TREE)
	    {
	      flag_abi_version = warn_abi_version;
	      id2 = mangle_decl_string (decl);
	      id2 = targetm.mangle_decl_assembler_name (decl, id2);
	    }
	  flag_abi_version = save_ver;

	  if (id2 == id)
	    /* OK.  */;
	  else if (warn_abi_version != 0
		   && abi_version_at_least (warn_abi_version))
	    warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
			"the mangled name of %qD changed between "
			"%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
			G.entity, fabi_version, warn_abi_version, id2,
			fabi_version, save_ver, id);
	  else
	    warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
			"the mangled name of %qD changes between "
			"%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
			G.entity, fabi_version, save_ver, id,
			fabi_version, warn_abi_version, id2);
	}

      flag_abi_version = save_ver;
    }
}

/* Generate the mangled representation of TYPE.  */

const char *
mangle_type_string (const tree type)
{
  const char *result;

  start_mangling (type);
  write_type (type);
  result = finish_mangling ();
  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
  return result;
}

/* Create an identifier for the mangled name of a special component
   for belonging to TYPE.  CODE is the ABI-specified code for this
   component.  */

static tree
mangle_special_for_type (const tree type, const char *code)
{
  tree result;

  /* We don't have an actual decl here for the special component, so
     we can't just process the <encoded-name>.  Instead, fake it.  */
  start_mangling (type);

  /* Start the mangling.  */
  write_string ("_Z");
  write_string (code);

  /* Add the type.  */
  write_type (type);
  result = finish_mangling_get_identifier ();

  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_special_for_type = %s\n\n",
	     IDENTIFIER_POINTER (result));

  return result;
}

/* Create an identifier for the mangled representation of the typeinfo
   structure for TYPE.  */

tree
mangle_typeinfo_for_type (const tree type)
{
  return mangle_special_for_type (type, "TI");
}

/* Create an identifier for the mangled name of the NTBS containing
   the mangled name of TYPE.  */

tree
mangle_typeinfo_string_for_type (const tree type)
{
  return mangle_special_for_type (type, "TS");
}

/* Create an identifier for the mangled name of the vtable for TYPE.  */

tree
mangle_vtbl_for_type (const tree type)
{
  return mangle_special_for_type (type, "TV");
}

/* Returns an identifier for the mangled name of the VTT for TYPE.  */

tree
mangle_vtt_for_type (const tree type)
{
  return mangle_special_for_type (type, "TT");
}

/* Returns an identifier for the mangled name of the decomposition
   artificial variable DECL.  DECLS is the vector of the VAR_DECLs
   for the identifier-list.  */

tree
mangle_decomp (const tree decl, vec<tree> &decls)
{
  gcc_assert (!type_dependent_expression_p (decl));

  location_t saved_loc = input_location;
  input_location = DECL_SOURCE_LOCATION (decl);

  start_mangling (decl);
  write_string ("_Z");

  tree context = decl_mangling_context (decl);
  gcc_assert (context != NULL_TREE);

  bool nested = false;
  if (DECL_NAMESPACE_STD_P (context))
    write_string ("St");
  else if (context != global_namespace)
    {
      nested = true;
      write_char ('N');
      write_prefix (decl_mangling_context (decl));
    }

  write_string ("DC");
  unsigned int i;
  tree d;
  FOR_EACH_VEC_ELT (decls, i, d)
    write_unqualified_name (d);
  write_char ('E');

  if (nested)
    write_char ('E');

  tree id = finish_mangling_get_identifier ();
  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_decomp = '%s'\n\n",
             IDENTIFIER_POINTER (id));

  input_location = saved_loc;
  return id;
}

/* Return an identifier for a construction vtable group.  TYPE is
   the most derived class in the hierarchy; BINFO is the base
   subobject for which this construction vtable group will be used.

   This mangling isn't part of the ABI specification; in the ABI
   specification, the vtable group is dumped in the same COMDAT as the
   main vtable, and is referenced only from that vtable, so it doesn't
   need an external name.  For binary formats without COMDAT sections,
   though, we need external names for the vtable groups.

   We use the production

    <special-name> ::= CT <type> <offset number> _ <base type>  */

tree
mangle_ctor_vtbl_for_type (const tree type, const tree binfo)
{
  tree result;

  start_mangling (type);

  write_string ("_Z");
  write_string ("TC");
  write_type (type);
  write_integer_cst (BINFO_OFFSET (binfo));
  write_char ('_');
  write_type (BINFO_TYPE (binfo));

  result = finish_mangling_get_identifier ();
  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n",
	     IDENTIFIER_POINTER (result));
  return result;
}

/* Mangle a this pointer or result pointer adjustment.

   <call-offset> ::= h <fixed offset number> _
		 ::= v <fixed offset number> _ <virtual offset number> _ */

static void
mangle_call_offset (const tree fixed_offset, const tree virtual_offset)
{
  write_char (virtual_offset ? 'v' : 'h');

  /* For either flavor, write the fixed offset.  */
  write_integer_cst (fixed_offset);
  write_char ('_');

  /* For a virtual thunk, add the virtual offset.  */
  if (virtual_offset)
    {
      write_integer_cst (virtual_offset);
      write_char ('_');
    }
}

/* Return an identifier for the mangled name of a this-adjusting or
   covariant thunk to FN_DECL.  FIXED_OFFSET is the initial adjustment
   to this used to find the vptr.  If VIRTUAL_OFFSET is non-NULL, this
   is a virtual thunk, and it is the vtbl offset in
   bytes. THIS_ADJUSTING is nonzero for a this adjusting thunk and
   zero for a covariant thunk. Note, that FN_DECL might be a covariant
   thunk itself. A covariant thunk name always includes the adjustment
   for the this pointer, even if there is none.

   <special-name> ::= T <call-offset> <base encoding>
		  ::= Tc <this_adjust call-offset> <result_adjust call-offset>
					<base encoding>  */

tree
mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
	      tree virtual_offset, tree thunk)
{
  tree result;

  if (abi_version_at_least (11))
    maybe_check_abi_tags (fn_decl, thunk, 11);

  start_mangling (fn_decl);

  write_string ("_Z");
  write_char ('T');

  if (!this_adjusting)
    {
      /* Covariant thunk with no this adjustment */
      write_char ('c');
      mangle_call_offset (integer_zero_node, NULL_TREE);
      mangle_call_offset (fixed_offset, virtual_offset);
    }
  else if (!DECL_THUNK_P (fn_decl))
    /* Plain this adjusting thunk.  */
    mangle_call_offset (fixed_offset, virtual_offset);
  else
    {
      /* This adjusting thunk to covariant thunk.  */
      write_char ('c');
      mangle_call_offset (fixed_offset, virtual_offset);
      fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl));
      virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl);
      if (virtual_offset)
	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
      mangle_call_offset (fixed_offset, virtual_offset);
      fn_decl = THUNK_TARGET (fn_decl);
    }

  /* Scoped name.  */
  write_encoding (fn_decl);

  result = finish_mangling_get_identifier ();
  if (DEBUG_MANGLE)
    fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result));
  return result;
}

/* Handle ABI backwards compatibility for past bugs where we didn't call
   check_abi_tags in places where it's needed: call check_abi_tags and warn if
   it makes a difference.  If FOR_DECL is non-null, it's the declaration
   that we're actually trying to mangle; if it's null, we're mangling the
   guard variable for T.  */

static void
maybe_check_abi_tags (tree t, tree for_decl, int ver)
{
  if (DECL_ASSEMBLER_NAME_SET_P (t))
    return;

  tree oldtags = get_abi_tags (t);

  mangle_decl (t);

  tree newtags = get_abi_tags (t);
  if (newtags && newtags != oldtags
      && abi_version_crosses (ver))
    {
      if (for_decl && DECL_THUNK_P (for_decl))
	warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
		    "the mangled name of a thunk for %qD changes between "
		    "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
		    t, flag_abi_version, warn_abi_version);
      else if (for_decl)
	warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi,
		    "the mangled name of %qD changes between "
		    "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
		    for_decl, flag_abi_version, warn_abi_version);
      else
	warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
		    "the mangled name of the initialization guard variable "
		    "for %qD changes between %<-fabi-version=%d%> and "
		    "%<-fabi-version=%d%>",
		    t, flag_abi_version, warn_abi_version);
    }
}

/* Write out the appropriate string for this variable when generating
   another mangled name based on this one.  */

static void
write_guarded_var_name (const tree variable)
{
  if (DECL_NAME (variable)
      && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR"))
    /* The name of a guard variable for a reference temporary should refer
       to the reference, not the temporary.  */
    write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
  else
    write_name (variable, /*ignore_local_scope=*/0);
}

/* Return an identifier for the name of an initialization guard
   variable for indicated VARIABLE.  */

tree
mangle_guard_variable (const tree variable)
{
  if (abi_version_at_least (10))
    maybe_check_abi_tags (variable);
  start_mangling (variable);
  write_string ("_ZGV");
  write_guarded_var_name (variable);
  return finish_mangling_get_identifier ();
}

/* Return an identifier for the name of a thread_local initialization
   function for VARIABLE.  */

tree
mangle_tls_init_fn (const tree variable)
{
  check_abi_tags (variable);
  start_mangling (variable);
  write_string ("_ZTH");
  write_guarded_var_name (variable);
  return finish_mangling_get_identifier ();
}

/* Return an identifier for the name of a thread_local wrapper
   function for VARIABLE.  */

#define TLS_WRAPPER_PREFIX "_ZTW"

tree
mangle_tls_wrapper_fn (const tree variable)
{
  check_abi_tags (variable);
  start_mangling (variable);
  write_string (TLS_WRAPPER_PREFIX);
  write_guarded_var_name (variable);
  return finish_mangling_get_identifier ();
}

/* Return true iff FN is a thread_local wrapper function.  */

bool
decl_tls_wrapper_p (const tree fn)
{
  if (TREE_CODE (fn) != FUNCTION_DECL)
    return false;
  tree name = DECL_NAME (fn);
  return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX);
}

/* Return an identifier for the name of a temporary variable used to
   initialize a static reference.  This is now part of the ABI.  */

tree
mangle_ref_init_variable (const tree variable)
{
  start_mangling (variable);
  write_string ("_ZGR");
  check_abi_tags (variable);
  write_name (variable, /*ignore_local_scope=*/0);
  /* Avoid name clashes with aggregate initialization of multiple
     references at once.  */
  write_compact_number (current_ref_temp_count++);
  return finish_mangling_get_identifier ();
}

/* Return an identifier for the mangled name of a C++20 template parameter
   object for template argument EXPR.  */

tree
mangle_template_parm_object (tree expr)
{
  start_mangling (expr);
  write_string ("_ZTAX");
  write_expression (expr);
  write_char ('E');
  return finish_mangling_get_identifier ();
}

/* Given a CLASS_TYPE, such as a record for std::bad_exception this
   function generates a mangled name for the vtable map variable of
   the class type.  For example, if the class type is
   "std::bad_exception", the mangled name for the class is
   "St13bad_exception".  This function would generate the name
   "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as:
   "_VTV<std::bad_exception>::__vtable_map".  */


char *
get_mangled_vtable_map_var_name (tree class_type)
{
  char *var_name = NULL;
  const char *prefix = "_ZN4_VTVI";
  const char *postfix = "E12__vtable_mapE";

  gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);

  tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));

  if (strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL)
    {
      class_id = get_mangled_id (TYPE_NAME (class_type));
      vtbl_register_mangled_name (TYPE_NAME (class_type), class_id);
    }

  unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
                     strlen (prefix) +
                     strlen (postfix) + 1;

  var_name = (char *) xmalloc (len);

  sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), postfix);

  return var_name;
}

#include "gt-cp-mangle.h"
