LCOV - code coverage report
Current view: top level - gcc/cp - mangle.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.2 % 2343 2207
Test Date: 2026-10-24 16:24:59 Functions: 97.3 % 112 109
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Name mangling for the 3.0 C++ ABI.
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              :    Written by Alex Samuel <samuel@codesourcery.com>
       4              : 
       5              :    This file is part of GCC.
       6              : 
       7              :    GCC is free software; you can redistribute it and/or modify it
       8              :    under the terms of the GNU General Public License as published by
       9              :    the Free Software Foundation; either version 3, or (at your option)
      10              :    any later version.
      11              : 
      12              :    GCC is distributed in the hope that it will be useful, but
      13              :    WITHOUT ANY WARRANTY; without even the implied warranty of
      14              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              :    General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /* This file implements mangling of C++ names according to the IA64
      22              :    C++ ABI specification.  A mangled name encodes a function or
      23              :    variable's name, scope, type, and/or template arguments into a text
      24              :    identifier.  This identifier is used as the function's or
      25              :    variable's linkage name, to preserve compatibility between C++'s
      26              :    language features (templates, scoping, and overloading) and C
      27              :    linkers.
      28              : 
      29              :    Additionally, g++ uses mangled names internally.  To support this,
      30              :    mangling of types is allowed, even though the mangled name of a
      31              :    type should not appear by itself as an exported name.  Ditto for
      32              :    uninstantiated templates.
      33              : 
      34              :    The primary entry point for this module is mangle_decl, which
      35              :    returns an identifier containing the mangled name for a decl.
      36              :    Additional entry points are provided to build mangled names of
      37              :    particular constructs when the appropriate decl for that construct
      38              :    is not available.  These are:
      39              : 
      40              :      mangle_typeinfo_for_type:          typeinfo data
      41              :      mangle_typeinfo_string_for_type:   typeinfo type name
      42              :      mangle_vtbl_for_type:              virtual table data
      43              :      mangle_vtt_for_type:               VTT data
      44              :      mangle_ctor_vtbl_for_type:         `C-in-B' constructor virtual table data
      45              :      mangle_thunk:                      thunk function or entry  */
      46              : 
      47              : #include "config.h"
      48              : #include "system.h"
      49              : #include "coretypes.h"
      50              : #include "target.h"
      51              : #include "vtable-verify.h"
      52              : #include "cp-tree.h"
      53              : #include "stringpool.h"
      54              : #include "cgraph.h"
      55              : #include "stor-layout.h"
      56              : #include "flags.h"
      57              : #include "attribs.h"
      58              : #include "contracts.h"
      59              : 
      60              : /* Debugging support.  */
      61              : 
      62              : /* Define DEBUG_MANGLE to enable very verbose trace messages.  */
      63              : #ifndef DEBUG_MANGLE
      64              : #define DEBUG_MANGLE 0
      65              : #endif
      66              : 
      67              : /* Macros for tracing the write_* functions.  */
      68              : #if DEBUG_MANGLE
      69              : # define MANGLE_TRACE(FN, INPUT) \
      70              :   fprintf (stderr, "  %-24s: %-24s\n", (FN), (INPUT))
      71              : # define MANGLE_TRACE_TREE(FN, NODE) \
      72              :   fprintf (stderr, "  %-24s: %-24s (%p)\n", \
      73              :            (FN), get_tree_code_name (TREE_CODE (NODE)), (void *) (NODE))
      74              : #else
      75              : # define MANGLE_TRACE(FN, INPUT)
      76              : # define MANGLE_TRACE_TREE(FN, NODE)
      77              : #endif
      78              : 
      79              : /* Nonzero if NODE is a class template-id.  We can't rely on
      80              :    CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser
      81              :    that hard to distinguish A<T> from A, where A<T> is the type as
      82              :    instantiated outside of the template, and A is the type used
      83              :    without parameters inside the template.  */
      84              : #define CLASSTYPE_TEMPLATE_ID_P(NODE)                                   \
      85              :   (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM                     \
      86              :    || (CLASS_TYPE_P (NODE)                                              \
      87              :        && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL                        \
      88              :        && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))
      89              : 
      90              : /* For deciding whether to set G.need_abi_warning, we need to consider both
      91              :    warn_abi_version and flag_abi_compat_version.  */
      92              : #define abi_warn_or_compat_version_crosses(N) \
      93              :   (abi_version_crosses (N) || abi_compat_version_crosses (N))
      94              : 
      95              : /* And sometimes we can simplify the code path if we don't need to worry about
      96              :    previous ABIs.  */
      97              : #define abi_flag_at_least(flag,N) (flag == 0 || flag >= N)
      98              : #define any_abi_below(N) \
      99              :   (!abi_version_at_least (N) \
     100              :    || !abi_flag_at_least (warn_abi_version, (N)) \
     101              :    || !abi_flag_at_least (flag_abi_compat_version, (N)))
     102              : 
     103              : /* Things we only need one of.  This module is not reentrant.  */
     104              : struct GTY(()) globals {
     105              :   /* An array of the current substitution candidates, in the order
     106              :      we've seen them.  Contains NULLS, which correspond to module
     107              :      substitutions.  */
     108              :   vec<tree, va_gc> *substitutions;
     109              : 
     110              :   /* The entity that is being mangled.  */
     111              :   tree GTY ((skip)) entity;
     112              : 
     113              :   /* How many parameter scopes we are inside.  */
     114              :   int parm_depth;
     115              : 
     116              :   /* True if the mangling will be different in a future version of the
     117              :      ABI.  */
     118              :   bool need_abi_warning;
     119              : 
     120              :   /* True if the mangling will be different in C++17 mode.  */
     121              :   bool need_cxx17_warning;
     122              : 
     123              :   /* True if we mangled a module name.  */
     124              :   bool mod;
     125              : };
     126              : 
     127              : static GTY (()) globals G;
     128              : 
     129              : /* The obstack on which we build mangled names.  */
     130              : static struct obstack *mangle_obstack;
     131              : 
     132              : /* The obstack on which we build mangled names that are not going to
     133              :    be IDENTIFIER_NODEs.  */
     134              : static struct obstack name_obstack;
     135              : 
     136              : /* The first object on the name_obstack; we use this to free memory
     137              :    allocated on the name_obstack.  */
     138              : static void *name_base;
     139              : 
     140              : /* Indices into subst_identifiers.  These are identifiers used in
     141              :    special substitution rules.  */
     142              : typedef enum
     143              : {
     144              :   SUBID_ALLOCATOR,
     145              :   SUBID_BASIC_STRING,
     146              :   SUBID_CHAR_TRAITS,
     147              :   SUBID_BASIC_ISTREAM,
     148              :   SUBID_BASIC_OSTREAM,
     149              :   SUBID_BASIC_IOSTREAM,
     150              :   SUBID_MAX
     151              : }
     152              : substitution_identifier_index_t;
     153              : 
     154              : /* For quick substitution checks, look up these common identifiers
     155              :    once only.  */
     156              : static GTY(()) tree subst_identifiers[SUBID_MAX];
     157              : 
     158              : /* Single-letter codes for builtin integer types, defined in
     159              :    <builtin-type>.  These are indexed by integer_type_kind values.  */
     160              : static const char
     161              : integer_type_codes[itk_none] =
     162              : {
     163              :   'c',  /* itk_char */
     164              :   'a',  /* itk_signed_char */
     165              :   'h',  /* itk_unsigned_char */
     166              :   's',  /* itk_short */
     167              :   't',  /* itk_unsigned_short */
     168              :   'i',  /* itk_int */
     169              :   'j',  /* itk_unsigned_int */
     170              :   'l',  /* itk_long */
     171              :   'm',  /* itk_unsigned_long */
     172              :   'x',  /* itk_long_long */
     173              :   'y',  /* itk_unsigned_long_long */
     174              :   /* __intN types are handled separately */
     175              :   '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
     176              : };
     177              : 
     178              : static tree maybe_template_info (const tree);
     179              : 
     180              : /* Functions for handling substitutions.  */
     181              : 
     182              : static inline tree canonicalize_for_substitution (tree);
     183              : static void add_substitution (tree);
     184              : static inline bool is_std_substitution (const tree,
     185              :                                        const substitution_identifier_index_t);
     186              : static inline bool is_std_substitution_char (const tree,
     187              :                                             const substitution_identifier_index_t);
     188              : static int find_substitution (tree);
     189              : static void mangle_call_offset (const tree, const tree);
     190              : 
     191              : /* Functions for emitting mangled representations of things.  */
     192              : 
     193              : static void write_mangled_name (const tree, bool);
     194              : static void write_encoding (const tree);
     195              : static void write_name (tree, const bool = false);
     196              : static void write_abi_tags (tree);
     197              : static void write_unscoped_name (const tree);
     198              : static void write_unscoped_template_name (const tree);
     199              : static void write_nested_name (const tree);
     200              : static void write_prefix (const tree);
     201              : static void write_template_prefix (const tree);
     202              : static void write_unqualified_name (tree);
     203              : static void write_conversion_operator_name (const tree);
     204              : static void write_source_name (tree);
     205              : static void write_literal_operator_name (tree);
     206              : static void write_unnamed_type_name (const tree);
     207              : static void write_unnamed_enum_name (const tree);
     208              : static void write_closure_type_name (const tree);
     209              : static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *,
     210              :                            const unsigned int);
     211              : static void write_number (unsigned HOST_WIDE_INT, const int,
     212              :                           const unsigned int);
     213              : static void write_compact_number (int num);
     214              : static void write_integer_cst (const tree);
     215              : static void write_real_cst (const tree);
     216              : static void write_identifier (const char *);
     217              : static void write_special_name_constructor (const tree);
     218              : static void write_special_name_destructor (const tree);
     219              : static void write_type (tree);
     220              : static int write_CV_qualifiers_for_type (const tree);
     221              : static void write_builtin_type (tree);
     222              : static void write_function_type (const tree);
     223              : static void write_bare_function_type (const tree, const int, const tree);
     224              : static void write_method_parms (tree, const int, const tree);
     225              : static void write_class_enum_type (const tree);
     226              : static void write_template_args (tree, tree = NULL_TREE);
     227              : static void write_expression (tree);
     228              : static void write_template_arg_literal (const tree);
     229              : static void write_template_arg (tree);
     230              : static void write_template_template_arg (const tree);
     231              : static void write_array_type (const tree);
     232              : static void write_pointer_to_member_type (const tree);
     233              : static void write_template_param (const tree);
     234              : static void write_template_template_param (const tree);
     235              : static void write_substitution (const int);
     236              : static int discriminator_for_local_entity (tree);
     237              : static int discriminator_for_string_literal (tree, tree);
     238              : static void write_discriminator (const int);
     239              : static void write_local_name (tree, const tree, const tree);
     240              : static void dump_substitution_candidates (void);
     241              : static tree mangle_decl_string (const tree);
     242              : static void maybe_check_abi_tags (tree, tree = NULL_TREE, int = 10);
     243              : static void write_splice (tree);
     244              : 
     245              : /* Control functions.  */
     246              : 
     247              : static inline void start_mangling (const tree);
     248              : static tree mangle_special_for_type (const tree, const char *);
     249              : 
     250              : /* Append a single character to the end of the mangled
     251              :    representation.  */
     252              : #define write_char(CHAR)                                                \
     253              :   obstack_1grow (mangle_obstack, (CHAR))
     254              : 
     255              : /* Append a sized buffer to the end of the mangled representation.  */
     256              : #define write_chars(CHAR, LEN)                                          \
     257              :   obstack_grow (mangle_obstack, (CHAR), (LEN))
     258              : 
     259              : /* Append a NUL-terminated string to the end of the mangled
     260              :    representation.  */
     261              : #define write_string(STRING)                                            \
     262              :   obstack_grow (mangle_obstack, (STRING), strlen (STRING))
     263              : 
     264              : /* Nonzero if NODE1 and NODE2 are both TREE_LIST nodes and have the
     265              :    same purpose (context, which may be a type) and value (template
     266              :    decl).  See write_template_prefix for more information on what this
     267              :    is used for.  */
     268              : #define NESTED_TEMPLATE_MATCH(NODE1, NODE2)                             \
     269              :   (TREE_CODE (NODE1) == TREE_LIST                                       \
     270              :    && TREE_CODE (NODE2) == TREE_LIST                                    \
     271              :    && ((TYPE_P (TREE_PURPOSE (NODE1))                                   \
     272              :         && same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2)))    \
     273              :        || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2))                 \
     274              :    && TREE_VALUE (NODE1) == TREE_VALUE (NODE2))
     275              : 
     276              : /* Write out an unsigned quantity in base 10.  */
     277              : #define write_unsigned_number(NUMBER)                                   \
     278              :   write_number ((NUMBER), /*unsigned_p=*/1, 10)
     279              : 
     280              : /* Check for -fabi-version dependent mangling and also set the need_abi_warning
     281              :    flag as appropriate.  */
     282              : 
     283              : static bool
     284     14649348 : abi_check (int ver)
     285              : {
     286     73076815 :   if (abi_warn_or_compat_version_crosses (ver))
     287        90171 :     G.need_abi_warning = true;
     288     14649348 :   return abi_version_at_least (ver);
     289              : }
     290              : 
     291              : /* If DECL is a template instance (including the uninstantiated template
     292              :    itself), return its TEMPLATE_INFO.  Otherwise return NULL.  */
     293              : 
     294              : static tree
     295   1419159585 : maybe_template_info (const tree decl)
     296              : {
     297   1419159585 :   if (TREE_CODE (decl) == TYPE_DECL)
     298              :     {
     299              :       /* TYPE_DECLs are handled specially.  Look at its type to decide
     300              :          if this is a template instantiation.  */
     301    541655421 :       const tree type = TREE_TYPE (decl);
     302              : 
     303    541655421 :       if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
     304    431057416 :         return TYPE_TEMPLATE_INFO (type);
     305              :     }
     306              :   else
     307              :     {
     308              :       /* Check if the template is a primary template.  */
     309    877504164 :       if (DECL_LANG_SPECIFIC (decl) != NULL
     310    876191589 :           && VAR_OR_FUNCTION_DECL_P (decl)
     311    745254008 :           && DECL_TEMPLATE_INFO (decl)
     312   1460507058 :           && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
     313     89735293 :         return DECL_TEMPLATE_INFO (decl);
     314              :     }
     315              : 
     316              :   /* It's not a template id.  */
     317              :   return NULL_TREE;
     318              : }
     319              : 
     320              : /* Produce debugging output of current substitution candidates.  */
     321              : 
     322              : static void
     323            0 : dump_substitution_candidates (void)
     324              : {
     325            0 :   unsigned i;
     326            0 :   tree el;
     327              : 
     328            0 :   fprintf (stderr, "  ++ substitutions  ");
     329            0 :   FOR_EACH_VEC_ELT (*G.substitutions, i, el)
     330              :     {
     331            0 :       const char *name = "???";
     332              : 
     333            0 :       if (i > 0)
     334            0 :         fprintf (stderr, "                    ");
     335            0 :       if (!el)
     336              :         name = "module";
     337            0 :       else if (DECL_P (el))
     338            0 :         name = IDENTIFIER_POINTER (DECL_NAME (el));
     339            0 :       else if (TREE_CODE (el) == TREE_LIST)
     340            0 :         name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el)));
     341            0 :       else if (TYPE_NAME (el))
     342            0 :         name = TYPE_NAME_STRING (el);
     343            0 :       fprintf (stderr, " S%d_ = ", i - 1);
     344            0 :       if (el)
     345              :         {
     346            0 :           if (TYPE_P (el) &&
     347            0 :               (CP_TYPE_RESTRICT_P (el)
     348            0 :                || CP_TYPE_VOLATILE_P (el)
     349            0 :                || CP_TYPE_CONST_P (el)))
     350            0 :             fprintf (stderr, "CV-");
     351            0 :           fprintf (stderr, "%s (%s at %p)",
     352            0 :                    name, get_tree_code_name (TREE_CODE (el)), (void *) el);
     353              :         }
     354            0 :       fprintf (stderr, "\n");
     355              :     }
     356            0 : }
     357              : 
     358              : /* <exception-spec> ::=
     359              :       Do  -- non-throwing exception specification
     360              :       DO <expression> E  -- computed (instantiation-dependent) noexcept
     361              :       Dw <type>* E  -- throw (types)  */
     362              : 
     363              : static void
     364      3326713 : write_exception_spec (tree spec)
     365              : {
     366              : 
     367      3326713 :   if (!spec || spec == noexcept_false_spec)
     368              :     /* Nothing.  */
     369              :     return;
     370              : 
     371        37638 :   if (!flag_noexcept_type)
     372              :     {
     373           17 :       G.need_cxx17_warning = true;
     374           17 :       return;
     375              :     }
     376              : 
     377        37621 :   if (spec == noexcept_true_spec || spec == empty_except_spec)
     378        37606 :     write_string ("Do");
     379           15 :   else if (tree expr = TREE_PURPOSE (spec))
     380              :     {
     381              :       /* noexcept (expr)  */
     382           15 :       gcc_assert (uses_template_parms (expr));
     383           15 :       write_string ("DO");
     384           15 :       write_expression (expr);
     385           15 :       write_char ('E');
     386              :     }
     387              :   else
     388              :     {
     389              :       /* throw (type-list) */
     390            0 :       write_string ("Dw");
     391            0 :       for (tree t = spec; t; t = TREE_CHAIN (t))
     392            0 :         write_type (TREE_VALUE (t));
     393            0 :       write_char ('E');
     394              :     }
     395              : }
     396              : 
     397              : /* Both decls and types can be substitution candidates, but sometimes
     398              :    they refer to the same thing.  For instance, a TYPE_DECL and
     399              :    RECORD_TYPE for the same class refer to the same thing, and should
     400              :    be treated accordingly in substitutions.  This function returns a
     401              :    canonicalized tree node representing NODE that is used when adding
     402              :    and substitution candidates and finding matches.  */
     403              : 
     404              : static inline tree
     405   4977854354 : canonicalize_for_substitution (tree node)
     406              : {
     407              :   /* For a TYPE_DECL, use the type instead.  */
     408   4977854354 :   if (TREE_CODE (node) == TYPE_DECL)
     409         5104 :     node = TREE_TYPE (node);
     410   4977854354 :   if (TYPE_P (node)
     411   3658816111 :       && TYPE_CANONICAL (node) != node
     412   5391160610 :       && TYPE_MAIN_VARIANT (node) != node)
     413              :     {
     414    117474358 :       tree orig = node;
     415              :       /* Here we want to strip the topmost typedef only.
     416              :          We need to do that so is_std_substitution can do proper
     417              :          name matching.  */
     418    117474358 :       if (TREE_CODE (node) == FUNCTION_TYPE)
     419              :         /* Use build_qualified_type and TYPE_QUALS here to preserve
     420              :            the old buggy mangling of attribute noreturn with abi<5.  */
     421        28549 :         node = build_qualified_type (TYPE_MAIN_VARIANT (node),
     422        28549 :                                      TYPE_QUALS (node));
     423              :       else
     424    117445809 :         node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
     425              :                                         cp_type_quals (node));
     426    117474358 :       if (FUNC_OR_METHOD_TYPE_P (node))
     427              :         {
     428        28558 :           node = build_ref_qualified_type (node, type_memfn_rqual (orig));
     429        28558 :           tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig));
     430        28558 :           if (flag_noexcept_type)
     431        28514 :             node = build_exception_variant (node, r);
     432              :           else
     433              :             /* Set the warning flag if appropriate.  */
     434           44 :             write_exception_spec (r);
     435              :         }
     436              :     }
     437   4977854354 :   return node;
     438              : }
     439              : 
     440              : /* Add NODE as a substitution candidate.  NODE must not already be on
     441              :    the list of candidates.  */
     442              : 
     443              : static void
     444   1290677818 : add_substitution (tree node)
     445              : {
     446   1290677818 :   tree c;
     447              : 
     448   1290677818 :   if (DEBUG_MANGLE)
     449              :     fprintf (stderr, "  ++ add_substitution (%s at %10p)\n",
     450              :              get_tree_code_name (TREE_CODE (node)), (void *) node);
     451              : 
     452              :   /* Get the canonicalized substitution candidate for NODE.  */
     453   1290677818 :   c = canonicalize_for_substitution (node);
     454   1290677818 :   if (DEBUG_MANGLE && c != node)
     455              :     fprintf (stderr, "  ++ using candidate (%s at %10p)\n",
     456              :              get_tree_code_name (TREE_CODE (node)), (void *) node);
     457   1290677818 :   node = c;
     458              : 
     459              :   /* Make sure NODE isn't already a candidate.  */
     460   1290677818 :   if (flag_checking)
     461              :     {
     462              :       int i;
     463              :       tree candidate;
     464              : 
     465   6695442556 :       FOR_EACH_VEC_SAFE_ELT (G.substitutions, i, candidate)
     466   5404764854 :         if (candidate)
     467              :           {
     468   5404757334 :             gcc_assert (!(DECL_P (node) && node == candidate));
     469   5404757334 :             gcc_assert (!(TYPE_P (node) && TYPE_P (candidate)
     470              :                           && same_type_p (node, candidate)));
     471              :           }
     472              :     }
     473              : 
     474              :   /* Put the decl onto the varray of substitution candidates.  */
     475   1290677818 :   vec_safe_push (G.substitutions, node);
     476              : 
     477   1290677818 :   if (DEBUG_MANGLE)
     478              :     dump_substitution_candidates ();
     479   1290677818 : }
     480              : 
     481              : /* Helper function for find_substitution.  Returns nonzero if NODE,
     482              :    which may be a class or a class template, is a template-id with template
     483              :    name of substitution_index[INDEX] in the ::std namespace, with
     484              :    global module attachment.  */
     485              : 
     486              : static bool
     487   4367739631 : is_std_substitution (const tree node,
     488              :                      const substitution_identifier_index_t index)
     489              : {
     490   4367739631 :   tree type = NULL_TREE;
     491   4367739631 :   tree decl = NULL_TREE;
     492              : 
     493   8710424611 :   auto std_substitution_p = [&] (tree decl, tree type)
     494              :     {
     495   4342684980 :       if (!DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)))
     496              :         return false;
     497              : 
     498   1677872266 :       if (!(TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type)))
     499              :         return false;
     500              : 
     501   1247416392 :       tree tmpl = TYPE_TI_TEMPLATE (type);
     502   1247416392 :       if (DECL_NAME (tmpl) != subst_identifiers[index])
     503              :         return false;
     504              : 
     505    148887960 :       if (modules_p () && get_originating_module (tmpl, true) >= 0)
     506           27 :         return false;
     507              : 
     508              :       return true;
     509   4367739631 :     };
     510              : 
     511   4367739631 :   if (TREE_CODE (node) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (node))
     512              :     {
     513   3451346578 :       type = TREE_TYPE (node);
     514   3451346578 :       decl = node;
     515              :     }
     516    916393053 :   else if (CLASS_TYPE_P (node))
     517              :     {
     518      4910347 :       type = node;
     519      4910347 :       decl = TYPE_NAME (node);
     520              :     }
     521              :   else
     522              :     {
     523              :       /* We used to accept all _DECL nodes in this function but now we
     524              :          only accept classes or class templates.  Verify that we don't
     525              :          return false for something that used to yield true.  */
     526    911482706 :       gcc_checking_assert (!DECL_P (node)
     527              :                            || !std_substitution_p (node, TREE_TYPE (node)));
     528              :       /* These are not the droids you're looking for.  */
     529              :       return false;
     530              :     }
     531              : 
     532   3456256925 :   return std_substitution_p (decl, type);
     533              : }
     534              : 
     535              : /* Return the ABI tags (the TREE_VALUE of the "abi_tag" attribute entry) for T,
     536              :    which can be a decl or type.  */
     537              : 
     538              : static tree
     539   1915115318 : get_abi_tags (tree t)
     540              : {
     541   1915115318 :   if (!t || TREE_CODE (t) == NAMESPACE_DECL)
     542              :     return NULL_TREE;
     543              : 
     544   1785053713 :   if (DECL_P (t) && DECL_DECLARES_TYPE_P (t))
     545    479931338 :     t = TREE_TYPE (t);
     546              : 
     547   1785053713 :   if (TREE_CODE (t) == TEMPLATE_DECL && DECL_TEMPLATE_RESULT (t))
     548              :     {
     549     17661655 :       tree tags = get_abi_tags (DECL_TEMPLATE_RESULT (t));
     550              :       /* We used to overlook abi_tag on function and variable templates.  */
     551     17661655 :       if (tags && abi_check (19))
     552           10 :         return tags;
     553              :       else
     554              :         return NULL_TREE;
     555              :     }
     556              : 
     557   1767392058 :   tree attrs;
     558   1767392058 :   if (TYPE_P (t))
     559   1536761654 :     attrs = TYPE_ATTRIBUTES (t);
     560              :   else
     561    230630404 :     attrs = DECL_ATTRIBUTES (t);
     562              : 
     563   1767392058 :   tree tags = lookup_attribute ("abi_tag", attrs);
     564   1767392058 :   if (tags)
     565     12258262 :     tags = TREE_VALUE (tags);
     566              :   return tags;
     567              : }
     568              : 
     569              : /* Helper function for find_substitution.  Returns nonzero if NODE,
     570              :    which may be a decl or a CLASS_TYPE, is the template-id
     571              :    ::std::identifier<char>, where identifier is
     572              :    substitution_index[INDEX].  */
     573              : 
     574              : static bool
     575      7001135 : is_std_substitution_char (const tree node,
     576              :                           const substitution_identifier_index_t index)
     577              : {
     578      7001135 :   tree args;
     579              :   /* Check NODE's name is ::std::identifier.  */
     580      7001135 :   if (!is_std_substitution (node, index))
     581              :     return 0;
     582              :   /* Figure out its template args.  */
     583      4433111 :   if (DECL_P (node))
     584            0 :     args = DECL_TI_ARGS (node);
     585      4433111 :   else if (CLASS_TYPE_P (node))
     586      4433111 :     args = CLASSTYPE_TI_ARGS (node);
     587              :   else
     588              :     /* Oops, not a template.  */
     589              :     return 0;
     590              :   /* NODE's template arg list should be <char>.  */
     591      4433111 :   return
     592      4433111 :     TREE_VEC_LENGTH (args) == 1
     593      4433111 :     && TREE_VEC_ELT (args, 0) == char_type_node;
     594              : }
     595              : 
     596              : /* Check whether a substitution should be used to represent NODE in
     597              :    the mangling.
     598              : 
     599              :    First, check standard special-case substitutions.
     600              : 
     601              :      <substitution> ::= St
     602              :          # ::std
     603              : 
     604              :                     ::= Sa
     605              :          # ::std::allocator
     606              : 
     607              :                     ::= Sb
     608              :          # ::std::basic_string
     609              : 
     610              :                     ::= Ss
     611              :          # ::std::basic_string<char,
     612              :                                ::std::char_traits<char>,
     613              :                                ::std::allocator<char> >
     614              : 
     615              :                     ::= Si
     616              :          # ::std::basic_istream<char, ::std::char_traits<char> >
     617              : 
     618              :                     ::= So
     619              :          # ::std::basic_ostream<char, ::std::char_traits<char> >
     620              : 
     621              :                     ::= Sd
     622              :          # ::std::basic_iostream<char, ::std::char_traits<char> >
     623              : 
     624              :    Then examine the stack of currently available substitution
     625              :    candidates for entities appearing earlier in the same mangling
     626              : 
     627              :    If a substitution is found, write its mangled representation and
     628              :    return nonzero.  If none is found, just return zero.  */
     629              : 
     630              : static int
     631   2377345532 : find_substitution (tree node)
     632              : {
     633   2377345532 :   int i;
     634   2377345532 :   const int size = vec_safe_length (G.substitutions);
     635   2377345532 :   tree decl;
     636   2377345532 :   tree type;
     637   2377345532 :   const char *abbr = NULL;
     638              : 
     639   2377345532 :   if (DEBUG_MANGLE)
     640              :     fprintf (stderr, "  ++ find_substitution (%s at %p)\n",
     641              :              get_tree_code_name (TREE_CODE (node)), (void *) node);
     642              : 
     643              :   /* Obtain the canonicalized substitution representation for NODE.
     644              :      This is what we'll compare against.  */
     645   2377345532 :   node = canonicalize_for_substitution (node);
     646              : 
     647              :   /* Check for builtin substitutions.  */
     648              : 
     649   2377345532 :   decl = TYPE_P (node) ? TYPE_NAME (node) : node;
     650   2377345532 :   type = TYPE_P (node) ? node : TREE_TYPE (node);
     651              : 
     652              :   /* Check for std::allocator.  */
     653   2377345532 :   if (decl
     654   2207136506 :       && is_std_substitution (decl, SUBID_ALLOCATOR)
     655   2520688595 :       && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
     656              :     abbr = "Sa";
     657              : 
     658              :   /* Check for std::basic_string.  */
     659   2311777386 :   else if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
     660              :     {
     661       155877 :       if (TYPE_P (node))
     662              :         {
     663              :           /* If this is a type (i.e. a fully-qualified template-id),
     664              :              check for
     665              :                  std::basic_string <char,
     666              :                                     std::char_traits<char>,
     667              :                                     std::allocator<char> > .  */
     668       108764 :           if (cp_type_quals (type) == TYPE_UNQUALIFIED
     669       108764 :               && CLASSTYPE_USE_TEMPLATE (type))
     670              :             {
     671        97215 :               tree args = CLASSTYPE_TI_ARGS (type);
     672        97215 :               if (TREE_VEC_LENGTH (args) == 3
     673        97197 :                   && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
     674        39521 :                   && is_std_substitution_char (TREE_VEC_ELT (args, 1),
     675              :                                                SUBID_CHAR_TRAITS)
     676       136725 :                   && is_std_substitution_char (TREE_VEC_ELT (args, 2),
     677              :                                                SUBID_ALLOCATOR))
     678              :                 abbr = "Ss";
     679              :             }
     680              :         }
     681              :       else
     682              :         /* Substitute for the template name only if this isn't a type.  */
     683              :         abbr = "Sb";
     684              :     }
     685              : 
     686              :   /* Check for basic_{i,o,io}stream.  */
     687   2311621509 :   else if (TYPE_P (node)
     688   1536062974 :            && cp_type_quals (type) == TYPE_UNQUALIFIED
     689   1447836955 :            && CLASS_TYPE_P (type)
     690    610176254 :            && CLASSTYPE_USE_TEMPLATE (type)
     691   2761544958 :            && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
     692              :     {
     693              :       /* First, check for the template
     694              :          args <char, std::char_traits<char> > .  */
     695    449923449 :       tree args = CLASSTYPE_TI_ARGS (type);
     696    449923449 :       if (TREE_VEC_LENGTH (args) == 2
     697    140520297 :           && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
     698    456845553 :           && is_std_substitution_char (TREE_VEC_ELT (args, 1),
     699              :                                        SUBID_CHAR_TRAITS))
     700              :         {
     701              :           /* Got them.  Is this basic_istream?  */
     702      4354086 :           if (is_std_substitution (decl, SUBID_BASIC_ISTREAM))
     703              :             abbr = "Si";
     704              :           /* Or basic_ostream?  */
     705      4041325 :           else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM))
     706              :             abbr = "So";
     707              :           /* Or basic_iostream?  */
     708      3638219 :           else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM))
     709   2146674283 :             abbr = "Sd";
     710              :         }
     711              :     }
     712              : 
     713              :   /* Check for namespace std.  */
     714   1861698060 :   else if (decl && DECL_NAMESPACE_STD_P (decl))
     715              :     {
     716    230671249 :       write_string ("St");
     717    230671249 :       return 1;
     718              :     }
     719              : 
     720   2146674283 :   tree tags = NULL_TREE;
     721   2146674283 :   if (OVERLOAD_TYPE_P (node) || DECL_CLASS_TEMPLATE_P (node))
     722   1056830316 :     tags = get_abi_tags (type);
     723              :   /* Now check the list of available substitutions for this mangling
     724              :      operation.  */
     725   2146674283 :   if (!abbr || tags)
     726   9320158965 :     for (i = 0; i < size; ++i)
     727   7422728944 :       if (tree candidate = (*G.substitutions)[i])
     728              :         {
     729              :           /* NODE is a matched to a candidate if it's the same decl node or
     730              :              if it's the same type.  */
     731   7422718823 :           if (decl == candidate
     732   7359274965 :               || (TYPE_P (candidate) && type && TYPE_P (node)
     733   3242845966 :                   && same_type_p (type, candidate))
     734  14663870122 :               || NESTED_TEMPLATE_MATCH (node, candidate))
     735              :             {
     736    182633620 :               write_substitution (i);
     737    182633620 :               return 1;
     738              :             }
     739              :         }
     740              : 
     741   1897430021 :   if (!abbr)
     742              :     /* No substitution found.  */
     743              :     return 0;
     744              : 
     745     66610648 :   write_string (abbr);
     746     66610648 :   if (tags)
     747              :     {
     748              :       /* If there are ABI tags on the abbreviation, it becomes
     749              :          a substitution candidate.  */
     750            6 :       write_abi_tags (tags);
     751            6 :       add_substitution (node);
     752              :     }
     753              :   return 1;
     754              : }
     755              : 
     756              : /* Returns whether DECL's symbol name should be the plain unqualified-id
     757              :    rather than a more complicated mangled name.  */
     758              : 
     759              : static bool
     760    225449215 : unmangled_name_p (const tree decl)
     761              : {
     762    225449215 :   if (TREE_CODE (decl) == FUNCTION_DECL)
     763              :     {
     764              :       /* The names of `extern "C"' functions are not mangled.  */
     765    191135415 :       return (DECL_EXTERN_C_FUNCTION_P (decl)
     766              :               /* But overloaded operator names *are* mangled.  */
     767      2298065 :               && !DECL_OVERLOADED_OPERATOR_P (decl));
     768              :     }
     769     34313800 :   else if (VAR_P (decl))
     770              :     {
     771              :       /* extern "C" declarations aren't mangled.  */
     772     34310417 :       if (DECL_NAMESPACE_SCOPE_P (decl) && DECL_EXTERN_C_P (decl))
     773              :         return true;
     774              : 
     775              :       /* static variables are mangled.  */
     776     34095313 :       if (!DECL_EXTERNAL_LINKAGE_P (decl))
     777              :         return false;
     778              : 
     779              :       /* Other variables at non-global scope are mangled.  */
     780     33875689 :       if (CP_DECL_CONTEXT (decl) != global_namespace)
     781              :         return false;
     782              : 
     783              :       /* Variable template instantiations are mangled.  */
     784       124946 :       if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
     785       123539 :           && variable_template_p (DECL_TI_TEMPLATE (decl)))
     786              :         return false;
     787              : 
     788              :       /* Declarations with ABI tags are mangled.  */
     789       114191 :       if (get_abi_tags (decl))
     790              :         return false;
     791              : 
     792              :       // Declarations attached to a named module are mangled
     793       113845 :       if (modules_p () && get_originating_module (decl, true) >= 0)
     794          121 :         return false;
     795              : 
     796              :       /* The names of non-static global variables aren't mangled.  */
     797              :       return true;
     798              :     }
     799              : 
     800              :   return false;
     801              : }
     802              : 
     803              : /* TOP_LEVEL is true, if this is being called at outermost level of
     804              :   mangling. It should be false when mangling a decl appearing in an
     805              :   expression within some other mangling.
     806              : 
     807              :   <mangled-name>      ::= _Z <encoding>  */
     808              : 
     809              : static void
     810    225449215 : write_mangled_name (const tree decl, bool top_level)
     811              : {
     812    225449215 :   MANGLE_TRACE_TREE ("mangled-name", decl);
     813              : 
     814    225449215 :   check_abi_tags (decl);
     815              : 
     816    225449215 :   if (unmangled_name_p (decl))
     817              :     {
     818      2626890 :       if (top_level)
     819      2626603 :         write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
     820              :       else
     821              :         {
     822              :           /* The standard notes: "The <encoding> of an extern "C"
     823              :              function is treated like global-scope data, i.e. as its
     824              :              <source-name> without a type."  We cannot write
     825              :              overloaded operators that way though, because it contains
     826              :              characters invalid in assembler.  */
     827          287 :           write_string ("_Z");
     828          287 :           write_source_name (DECL_NAME (decl));
     829              :         }
     830              :     }
     831              :   else
     832              :     {
     833    222822325 :       write_string ("_Z");
     834    222822325 :       write_encoding (decl);
     835              :     }
     836              : 
     837              :   /* If this is a coroutine helper, then append an appropriate string to
     838              :      identify which.  */
     839    225449215 :   if (tree ramp = DECL_RAMP_FN (decl))
     840              :     {
     841         3082 :       if (DECL_ACTOR_FN (ramp) == decl)
     842         1541 :         write_string (JOIN_STR "actor");
     843         1541 :       else if (DECL_DESTROY_FN (ramp) == decl)
     844         1541 :         write_string (JOIN_STR "destroy");
     845              :       else
     846            0 :         gcc_unreachable ();
     847              :     }
     848    225449215 : }
     849              : 
     850              : /* Returns true if the return type of DECL is part of its signature, and
     851              :    therefore its mangling.  */
     852              : 
     853              : bool
     854    382943737 : mangle_return_type_p (tree decl)
     855              : {
     856    382943737 :   return (!DECL_CONSTRUCTOR_P (decl)
     857    321296445 :           && !DECL_DESTRUCTOR_P (decl)
     858    306780714 :           && !DECL_CONV_FN_P (decl)
     859    686957630 :           && maybe_template_info (decl));
     860              : }
     861              : 
     862              : /* <constraint-expression> ::= <expression> */
     863              : 
     864              : static void
     865      3308010 : write_constraint_expression (tree expr)
     866              : {
     867            0 :   write_expression (expr);
     868            0 : }
     869              : 
     870              : /* Mangle a requires-clause following a template-head, if any.
     871              : 
     872              :    Q <constraint_expression> E  */
     873              : 
     874              : static void
     875    426172995 : write_tparms_constraints (tree constraints)
     876              : {
     877              :   /* In a declaration with shorthand constraints in the template-head, followed
     878              :      by a requires-clause, followed by shorthand constraints in the
     879              :      function-parameter-list, the full constraints will be some && with the
     880              :      parameter constraints on the RHS, around an && with the requires-clause on
     881              :      the RHS.  Find the requires-clause, if any.
     882              : 
     883              :      This logic relies on the && and ... from combine_constraint_expressions,
     884              :      finish_shorthand_constraint, and convert_generic_types_to_packs having
     885              :      UNKNOWN_LOCATION.  If they need to have an actual location, we could move
     886              :      to using a TREE_LANG_FLAG.  */
     887    426172995 :   if (constraints && abi_check (19))
     888              :     {
     889              :       tree probe = constraints;
     890              :       while (probe
     891       349733 :              && !cp_expr_location (probe)
     892       386681 :              && TREE_CODE (probe) == TRUTH_ANDIF_EXPR)
     893              :         {
     894          372 :           tree op1 = TREE_OPERAND (probe, 1);
     895          715 :           probe = (cp_expr_location (op1) ? op1
     896          343 :                    : TREE_OPERAND (probe, 0));
     897              :         }
     898       349361 :       if (probe && cp_expr_location (probe))
     899              :         {
     900       312785 :           write_char ('Q');
     901       312785 :           write_constraint_expression (probe);
     902              :         }
     903              :     }
     904    426172995 : }
     905              : 
     906              : /* <type-constraint> ::= <name> */
     907              : 
     908              : static void
     909       145760 : write_type_constraint (tree cnst)
     910              : {
     911       145760 :   if (!cnst)
     912              :     return;
     913              : 
     914       145760 :   gcc_checking_assert (TREE_CODE (cnst) == TEMPLATE_ID_EXPR);
     915              : 
     916       145760 :   tree concept_decl = get_concept_check_template (cnst);
     917       145760 :   write_name (concept_decl);
     918       145760 :   tree args = TREE_OPERAND (cnst, 1);
     919       145760 :   if (TREE_VEC_LENGTH (args) > 1)
     920              :     {
     921        53040 :       TEMPLATE_ARGS_TYPE_CONSTRAINT_P (args) = true;
     922        53040 :       write_template_args (args);
     923              :     }
     924              : }
     925              : 
     926              : /*   <encoding>           ::= <function name> <bare-function-type>
     927              :                         ::= <data name>  */
     928              : 
     929              : static void
     930    228482869 : write_encoding (const tree decl)
     931              : {
     932    228482869 :   MANGLE_TRACE_TREE ("encoding", decl);
     933              : 
     934    228482869 :   if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
     935              :     {
     936              :       /* For overloaded operators write just the mangled name
     937              :          without arguments.  */
     938        11159 :       if (DECL_OVERLOADED_OPERATOR_P (decl))
     939            3 :         write_name (decl);
     940              :       else
     941        11156 :         write_source_name (DECL_NAME (decl));
     942              :       return;
     943              :     }
     944              : 
     945    228471710 :   write_name (decl);
     946    228471710 :   if (TREE_CODE (decl) == FUNCTION_DECL)
     947              :     {
     948    194486535 :       tree fn_type;
     949    194486535 :       tree d;
     950              : 
     951    194486535 :       if (maybe_template_info (decl))
     952              :         {
     953     17456626 :           fn_type = get_mostly_instantiated_function_type (decl);
     954              :           /* FN_TYPE will not have parameter types for in-charge or
     955              :              VTT parameters.  Therefore, we pass NULL_TREE to
     956              :              write_bare_function_type -- otherwise, it will get
     957              :              confused about which artificial parameters to skip.  */
     958     17456626 :           d = NULL_TREE;
     959              :         }
     960              :       else
     961              :         {
     962    177029909 :           fn_type = TREE_TYPE (decl);
     963    177029909 :           d = decl;
     964              :         }
     965              : 
     966    194486535 :       write_bare_function_type (fn_type,
     967    194486535 :                                 mangle_return_type_p (decl),
     968              :                                 d);
     969              : 
     970    194486535 :       if (tree c = get_trailing_function_requirements (decl))
     971      3014833 :         if (abi_check (19))
     972              :           {
     973      2995219 :             ++G.parm_depth;
     974      2995219 :             write_char ('Q');
     975      2995219 :             write_constraint_expression (c);
     976      2995219 :             --G.parm_depth;
     977              :           }
     978              :     }
     979              : }
     980              : 
     981              : /* Interface to substitution and identifier mangling, used by the
     982              :    module name mangler.  */
     983              : 
     984              : void
     985          425 : mangle_module_substitution (int v)
     986              : {
     987          425 :   write_substitution (v - 1);
     988          425 : }
     989              : 
     990              : int
     991         8601 : mangle_module_component (tree comp, bool partition_p)
     992              : {
     993         8601 :   write_char ('W');
     994         8601 :   if (partition_p)
     995          226 :     write_char ('P');
     996         8601 :   write_source_name (comp);
     997              : 
     998              :   // Module substitutions use the same number-space as entity
     999              :   // substitutions, but are orthogonal.
    1000         8601 :   vec_safe_push (G.substitutions, NULL_TREE);
    1001         8601 :   return G.substitutions->length ();
    1002              : }
    1003              : 
    1004              : /* If the outermost non-namespace context (including DECL itself) is
    1005              :    a module-linkage decl, mangle the module information.  For module
    1006              :    global initializers we need to include the partition part.
    1007              : 
    1008              :    <module-name> ::= <module-sub>
    1009              :                  || <subst>
    1010              :                  || <module-name> <module-sub>
    1011              :    <module-sub> :: W [P] <unqualified-name>
    1012              : */
    1013              : 
    1014              : static void
    1015         8344 : write_module (int m, bool include_partition)
    1016              : {
    1017         8344 :   G.mod = true;
    1018            0 :   mangle_module (m, include_partition);
    1019            0 : }
    1020              : 
    1021              : static void
    1022      1857360 : maybe_write_module (tree decl)
    1023              : {
    1024      1857360 :   if (!DECL_NAMESPACE_SCOPE_P (decl))
    1025              :     return;
    1026              : 
    1027      1324287 :   if (!TREE_PUBLIC (STRIP_TEMPLATE (decl)))
    1028              :     return;
    1029              : 
    1030      1315044 :   if (TREE_CODE (decl) == NAMESPACE_DECL)
    1031              :     return;
    1032              : 
    1033       999368 :   int m = get_originating_module (decl, true);
    1034       999368 :   if (m >= 0)
    1035         6242 :     write_module (m, false);
    1036              : }
    1037              : 
    1038              : /* Lambdas can have a bit more context for mangling, specifically VAR_DECL
    1039              :    or PARM_DECL context, which doesn't belong in DECL_CONTEXT.  */
    1040              : 
    1041              : static tree
    1042   2118015927 : decl_mangling_context (tree decl)
    1043              : {
    1044   2118016075 :   tree tcontext = targetm.cxx.decl_mangling_context (decl);
    1045              : 
    1046   2118016075 :   if (tcontext != NULL_TREE)
    1047              :     return tcontext;
    1048              : 
    1049   2118016075 :   if (TREE_CODE (decl) == TEMPLATE_DECL
    1050   2118016075 :       && DECL_TEMPLATE_RESULT (decl))
    1051              :     decl = DECL_TEMPLATE_RESULT (decl);
    1052              : 
    1053   2118016075 :   if (TREE_CODE (decl) == TYPE_DECL
    1054   3116338665 :       && LAMBDA_TYPE_P (TREE_TYPE (decl)))
    1055              :     {
    1056      6091656 :       tree extra = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl));
    1057      6091656 :       if (extra)
    1058              :         return extra;
    1059         6081 :       tcontext = CP_DECL_CONTEXT (decl);
    1060         6251 :       if (LAMBDA_TYPE_P (tcontext))
    1061              :         /* Lambda type context means this lambda appears between the
    1062              :            lambda-introducer and the open brace of another lambda (c++/119175).
    1063              :            That isn't a real scope; look further into the enclosing scope.  */
    1064           60 :         return decl_mangling_context (TYPE_NAME (tcontext));
    1065              :     }
    1066   2111924419 :   else if (template_type_parameter_p (decl))
    1067              :      /* template type parms have no mangling context.  */
    1068              :       return NULL_TREE;
    1069              : 
    1070   2111929454 :   tcontext = CP_DECL_CONTEXT (decl);
    1071              : 
    1072   2111929454 :   if (member_like_constrained_friend_p (decl))
    1073        90440 :     tcontext = DECL_FRIEND_CONTEXT (decl);
    1074              : 
    1075              :   /* Ignore the artificial declare reduction functions.  */
    1076   2111929454 :   if (tcontext
    1077   2111929454 :       && TREE_CODE (tcontext) == FUNCTION_DECL
    1078   2117909685 :       && DECL_OMP_DECLARE_REDUCTION_P (tcontext))
    1079              :     return decl_mangling_context (tcontext);
    1080              : 
    1081              :   return tcontext;
    1082              : }
    1083              : 
    1084              : /* <name> ::= <unscoped-name>
    1085              :           ::= <unscoped-template-name> <template-args>
    1086              :           ::= <nested-name>
    1087              :           ::= <local-name>
    1088              : 
    1089              :    If IGNORE_LOCAL_SCOPE is true, this production of <name> is
    1090              :    called from <local-name>, which mangles the enclosing scope
    1091              :    elsewhere and then uses this function to mangle just the part
    1092              :    underneath the function scope.  So don't use the <local-name>
    1093              :    production, to avoid an infinite recursion.  */
    1094              : 
    1095              : static void
    1096    564455699 : write_name (tree decl, const bool ignore_local_scope/*=false*/)
    1097              : {
    1098    564455699 :   tree context;
    1099              : 
    1100    564455699 :   MANGLE_TRACE_TREE ("name", decl);
    1101              : 
    1102    564455699 :   if (TREE_CODE (decl) == TYPE_DECL)
    1103              :     {
    1104              :       /* In case this is a typedef, fish out the corresponding
    1105              :          TYPE_DECL for the main variant.  */
    1106    331354411 :       decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
    1107              :     }
    1108              : 
    1109    564455699 :   context = decl_mangling_context (decl);
    1110              : 
    1111    564455699 :   gcc_assert (context != NULL_TREE);
    1112              : 
    1113   2821797554 :   if (abi_warn_or_compat_version_crosses (7)
    1114       160059 :       && ignore_local_scope
    1115           40 :       && TREE_CODE (context) == PARM_DECL)
    1116            0 :     G.need_abi_warning = 1;
    1117              : 
    1118              :   /* A decl in :: or ::std scope is treated specially.  The former is
    1119              :      mangled using <unscoped-name> or <unscoped-template-name>, the
    1120              :      latter with a special substitution.  Also, a name that is
    1121              :      directly in a local function scope is also mangled with
    1122              :      <unscoped-name> rather than a full <nested-name>.  */
    1123    564455699 :   if (context == global_namespace
    1124    552540501 :       || DECL_NAMESPACE_STD_P (context)
    1125    328754295 :       || (ignore_local_scope
    1126      5167255 :           && (TREE_CODE (context) == FUNCTION_DECL
    1127      3574810 :               || (abi_version_at_least (7)
    1128      3574810 :                   && TREE_CODE (context) == PARM_DECL))))
    1129              :     {
    1130              :       /* Is this a template instance?  */
    1131    237293879 :       if (tree info = maybe_template_info (decl))
    1132              :         {
    1133              :           /* Yes: use <unscoped-template-name>.  */
    1134    197931790 :           write_unscoped_template_name (TI_TEMPLATE (info));
    1135              :           /* Pass down the parms of a function template in case we need to
    1136              :              mangle them; we don't mangle the parms of a non-overloadable
    1137              :              template.  */
    1138    197931790 :           tree parms = (TREE_CODE (decl) == FUNCTION_DECL
    1139    202921662 :                         ? DECL_TEMPLATE_PARMS (TI_TEMPLATE (info))
    1140      4989872 :                         : NULL_TREE);
    1141    197931790 :           write_template_args (TI_ARGS (info), parms);
    1142              :         }
    1143              :       else
    1144              :         /* Everything else gets an <unqualified-name>.  */
    1145     39362089 :         write_unscoped_name (decl);
    1146              :     }
    1147              :   else
    1148              :     {
    1149              :       /* Handle local names, unless we asked not to (that is, invoked
    1150              :          under <local-name>, to handle only the part of the name under
    1151              :          the local scope).  */
    1152    327161820 :       if (!ignore_local_scope)
    1153              :         {
    1154              :           /* Scan up the list of scope context, looking for a
    1155              :              function.  If we find one, this entity is in local
    1156              :              function scope.  local_entity tracks context one scope
    1157              :              level down, so it will contain the element that's
    1158              :              directly in that function's scope, either decl or one of
    1159              :              its enclosing scopes.  */
    1160              :           tree local_entity = decl;
    1161   1032289995 :           while (context != global_namespace)
    1162              :             {
    1163              :               /* Make sure we're always dealing with decls.  */
    1164    713870210 :               if (TYPE_P (context))
    1165    226333117 :                 context = TYPE_NAME (context);
    1166              :               /* Is this a function?  */
    1167    713870210 :               if (TREE_CODE (context) == FUNCTION_DECL
    1168    708703321 :                   || TREE_CODE (context) == PARM_DECL)
    1169              :                 {
    1170              :                   /* Yes, we have local scope.  Use the <local-name>
    1171              :                      production for the innermost function scope.  */
    1172      5167255 :                   write_local_name (context, local_entity, decl);
    1173      5167255 :                   return;
    1174              :                 }
    1175              :               /* Up one scope level.  */
    1176    708702955 :               local_entity = context;
    1177    708702955 :               context = decl_mangling_context (context);
    1178              :             }
    1179              : 
    1180              :           /* No local scope found?  Fall through to <nested-name>.  */
    1181              :         }
    1182              : 
    1183              :       /* Other decls get a <nested-name> to encode their scope.  */
    1184    321994565 :       write_nested_name (decl);
    1185              :     }
    1186              : }
    1187              : 
    1188              : /* <unscoped-name> ::= <unqualified-name>
    1189              :                    ::= St <unqualified-name>   # ::std::  */
    1190              : 
    1191              : static void
    1192    169168915 : write_unscoped_name (const tree decl)
    1193              : {
    1194    169168915 :   tree context = decl_mangling_context (decl);
    1195              : 
    1196    169168915 :   MANGLE_TRACE_TREE ("unscoped-name", decl);
    1197              : 
    1198              :   /* Is DECL in ::std?  */
    1199    169168915 :   if (DECL_NAMESPACE_STD_P (context))
    1200              :     {
    1201    158614903 :       write_string ("St");
    1202    158614903 :       write_unqualified_name (decl);
    1203              :     }
    1204              :   else
    1205              :     {
    1206              :       /* If not, it should be either in the global namespace, or directly
    1207              :          in a local function scope.  A lambda can also be mangled in the
    1208              :          scope of a default argument.  */
    1209     10554012 :       gcc_assert (context == global_namespace
    1210              :                   || TREE_CODE (context) == PARM_DECL
    1211              :                   || TREE_CODE (context) == FUNCTION_DECL);
    1212              : 
    1213     10554012 :       write_unqualified_name (decl);
    1214              :     }
    1215    169168915 : }
    1216              : 
    1217              : /* <unscoped-template-name> ::= <unscoped-name>
    1218              :                             ::= <substitution>  */
    1219              : 
    1220              : static void
    1221    197931790 : write_unscoped_template_name (const tree decl)
    1222              : {
    1223    197931790 :   MANGLE_TRACE_TREE ("unscoped-template-name", decl);
    1224              : 
    1225    197931790 :   if (find_substitution (decl))
    1226              :     return;
    1227    129806826 :   write_unscoped_name (decl);
    1228    129806826 :   add_substitution (decl);
    1229              : }
    1230              : 
    1231              : /* Write the nested name, including CV-qualifiers, of DECL.
    1232              : 
    1233              :    <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
    1234              :                  ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
    1235              : 
    1236              :    <ref-qualifier> ::= R # & ref-qualifier
    1237              :                    ::= O # && ref-qualifier
    1238              :    <CV-qualifiers> ::= [r] [V] [K]  */
    1239              : 
    1240              : static void
    1241    324724546 : write_nested_name (const tree decl)
    1242              : {
    1243    324724546 :   MANGLE_TRACE_TREE ("nested-name", decl);
    1244              : 
    1245    324724546 :   write_char ('N');
    1246              : 
    1247              :   /* Write CV-qualifiers, if this is an iobj member function.  */
    1248    324724546 :   if (TREE_CODE (decl) == FUNCTION_DECL
    1249    324724546 :       && DECL_IOBJ_MEMBER_FUNCTION_P (decl))
    1250              :     {
    1251    153503171 :       if (DECL_VOLATILE_MEMFUNC_P (decl))
    1252      8898862 :         write_char ('V');
    1253    153503171 :       if (DECL_CONST_MEMFUNC_P (decl))
    1254     46601404 :         write_char ('K');
    1255    153503171 :       if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)))
    1256              :         {
    1257       155946 :           if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl)))
    1258        97360 :             write_char ('O');
    1259              :           else
    1260        58586 :             write_char ('R');
    1261              :         }
    1262              :     }
    1263    142175104 :   else if (DECL_DECLARES_FUNCTION_P (decl)
    1264    171221375 :            && DECL_XOBJ_MEMBER_FUNCTION_P (decl))
    1265         5471 :     write_char ('H');
    1266              : 
    1267              :   /* Is this a template instance?  */
    1268    324724546 :   if (tree info = maybe_template_info (decl))
    1269              :     {
    1270              :       /* Yes, use <template-prefix>.  */
    1271     56178085 :       write_template_prefix (decl);
    1272     56178085 :       write_template_args (TI_ARGS (info));
    1273              :     }
    1274    268546461 :   else if ((!abi_version_at_least (10) || TREE_CODE (decl) == TYPE_DECL)
    1275    347797292 :            && TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
    1276              :     {
    1277      2729978 :       tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
    1278      2729978 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    1279              :         {
    1280        50717 :           write_template_prefix (decl);
    1281        50717 :           write_template_args (TREE_OPERAND (name, 1));
    1282              :         }
    1283              :       else
    1284              :         {
    1285      2679261 :           write_prefix (decl_mangling_context (decl));
    1286      2679261 :           write_unqualified_name (decl);
    1287              :         }
    1288              :     }
    1289              :   else
    1290              :     {
    1291              :       /* No, just use <prefix>  */
    1292    265816483 :       write_prefix (decl_mangling_context (decl));
    1293    265816483 :       write_unqualified_name (decl);
    1294              :     }
    1295    324724546 :   write_char ('E');
    1296    324724546 : }
    1297              : 
    1298              : /* <prefix> ::= <prefix> <unqualified-name>
    1299              :             ::= <template-param>
    1300              :             ::= <template-prefix> <template-args>
    1301              :             ::= <decltype>
    1302              :             ::= # empty
    1303              :             ::= <substitution>
    1304              :             ::= <splice>      # C++26 dependent splice [proposed]  */
    1305              : 
    1306              : static void
    1307    669516026 : write_prefix (const tree node)
    1308              : {
    1309    669516026 :   tree decl;
    1310              : 
    1311    669516026 :   if (node == NULL
    1312    669516026 :       || node == global_namespace)
    1313              :     return;
    1314              : 
    1315    645399592 :   MANGLE_TRACE_TREE ("prefix", node);
    1316              : 
    1317    645399592 :   if (TREE_CODE (node) == DECLTYPE_TYPE
    1318    645399484 :       || TREE_CODE (node) == TRAIT_TYPE)
    1319              :     {
    1320          111 :       write_type (node);
    1321          111 :       return;
    1322              :     }
    1323              : 
    1324    645399481 :   if (TREE_CODE (node) == SPLICE_SCOPE)
    1325              :     {
    1326           10 :       write_splice (node);
    1327           10 :       return;
    1328              :     }
    1329              : 
    1330    645399471 :   if (find_substitution (node))
    1331              :     return;
    1332              : 
    1333    354548815 :   tree template_info = NULL_TREE;
    1334    354548815 :   if (DECL_P (node))
    1335              :     {
    1336              :       /* If this is a function or parm decl, that means we've hit function
    1337              :          scope, so this prefix must be for a local name.  In this
    1338              :          case, we're under the <local-name> production, which encodes
    1339              :          the enclosing function scope elsewhere.  So don't continue
    1340              :          here.  */
    1341    133705010 :       if (TREE_CODE (node) == FUNCTION_DECL
    1342    130131204 :           || TREE_CODE (node) == PARM_DECL)
    1343              :         return;
    1344              : 
    1345    130130868 :       decl = node;
    1346    130130868 :       template_info = maybe_template_info (decl);
    1347              :     }
    1348              :   else
    1349              :     {
    1350              :       /* Node is a type.  */
    1351    220843805 :       decl = TYPE_NAME (node);
    1352              :       /* The DECL might not point at the node.  */
    1353    220843805 :       if (CLASSTYPE_TEMPLATE_ID_P (node))
    1354    166984189 :         template_info = TYPE_TEMPLATE_INFO (node);
    1355              :     }
    1356              : 
    1357    350974673 :   if (TREE_CODE (node) == TEMPLATE_TYPE_PARM)
    1358        12438 :     write_template_param (node);
    1359    350962235 :   else if (template_info)
    1360              :     /* Templated.  */
    1361              :     {
    1362    167026520 :       write_template_prefix (decl);
    1363    167026520 :       write_template_args (TI_ARGS (template_info));
    1364              :     }
    1365    183935715 :   else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
    1366              :     {
    1367       138547 :       tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
    1368       138547 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    1369              :         {
    1370       119826 :           write_template_prefix (decl);
    1371       119826 :           write_template_args (TREE_OPERAND (name, 1));
    1372              :         }
    1373              :       else
    1374              :         {
    1375        18721 :           write_prefix (decl_mangling_context (decl));
    1376        18721 :           write_unqualified_name (decl);
    1377              :         }
    1378              :     }
    1379              :   else
    1380              :     /* Not templated.  */
    1381              :     {
    1382    183797168 :       write_prefix (decl_mangling_context (decl));
    1383    183797168 :       write_unqualified_name (decl);
    1384    183797168 :       if (VAR_P (decl)
    1385    183797168 :           || TREE_CODE (decl) == FIELD_DECL)
    1386              :         {
    1387              :           /* <data-member-prefix> := <member source-name> M */
    1388        26885 :           write_char ('M');
    1389              : 
    1390              :           /* Before ABI 18, we did not count these as substitution
    1391              :              candidates.  This leads to incorrect demanglings (and
    1392              :              ABI divergence to other compilers).  */
    1393        26885 :           if (!abi_check (18))
    1394              :             return;
    1395              :         }
    1396              :     }
    1397              : 
    1398    350974541 :   add_substitution (node);
    1399              : }
    1400              : 
    1401              : /* <template-prefix> ::= <prefix> <template component>
    1402              :                      ::= <template-param>
    1403              :                      ::= <substitution>  */
    1404              : 
    1405              : static void
    1406    223375148 : write_template_prefix (const tree node)
    1407              : {
    1408    223375148 :   tree decl = DECL_P (node) ? node : TYPE_NAME (node);
    1409    223375148 :   tree type = DECL_P (node) ? TREE_TYPE (node) : node;
    1410    223375148 :   tree context = decl_mangling_context (decl);
    1411    223375148 :   tree templ;
    1412    223375148 :   tree substitution;
    1413              : 
    1414    223375148 :   MANGLE_TRACE_TREE ("template-prefix", node);
    1415              : 
    1416              :   /* Find the template decl.  */
    1417    223375148 :   if (tree info = maybe_template_info (decl))
    1418    223203619 :     templ = TI_TEMPLATE (info);
    1419       171529 :   else if (TREE_CODE (type) == TYPENAME_TYPE)
    1420              :     /* For a typename type, all we have is the name.  */
    1421       170543 :     templ = DECL_NAME (decl);
    1422              :   else
    1423              :     {
    1424          986 :       gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));
    1425              : 
    1426          986 :       templ = TYPE_TI_TEMPLATE (type);
    1427              :     }
    1428              : 
    1429              :   /* For a member template, though, the template name for the
    1430              :      innermost name must have all the outer template levels
    1431              :      instantiated.  For instance, consider
    1432              : 
    1433              :        template<typename T> struct Outer {
    1434              :          template<typename U> struct Inner {};
    1435              :        };
    1436              : 
    1437              :      The template name for `Inner' in `Outer<int>::Inner<float>' is
    1438              :      `Outer<int>::Inner<U>'.  In g++, we don't instantiate the template
    1439              :      levels separately, so there's no TEMPLATE_DECL available for this
    1440              :      (there's only `Outer<T>::Inner<U>').
    1441              : 
    1442              :      In order to get the substitutions right, we create a special
    1443              :      TREE_LIST to represent the substitution candidate for a nested
    1444              :      template.  The TREE_PURPOSE is the template's context, fully
    1445              :      instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner
    1446              :      template.
    1447              : 
    1448              :      So, for the example above, `Outer<int>::Inner' is represented as a
    1449              :      substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
    1450              :      and whose value is `Outer<T>::Inner<U>'.  */
    1451    223375148 :   if (context && TYPE_P (context))
    1452     11489746 :     substitution = build_tree_list (context, templ);
    1453              :   else
    1454              :     substitution = templ;
    1455              : 
    1456    223375148 :   if (find_substitution (substitution))
    1457              :     return;
    1458              : 
    1459    217204607 :   if (TREE_TYPE (templ)
    1460    217204607 :       && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM)
    1461          986 :     write_template_param (TREE_TYPE (templ));
    1462              :   else
    1463              :     {
    1464    217203621 :       write_prefix (context);
    1465    217203621 :       write_unqualified_name (decl);
    1466              :     }
    1467              : 
    1468    217204607 :   add_substitution (substitution);
    1469              : }
    1470              : 
    1471              : /* "For the purposes of mangling, the name of an anonymous union is considered
    1472              :    to be the name of the first named data member found by a pre-order,
    1473              :    depth-first, declaration-order walk of the data members of the anonymous
    1474              :    union. If there is no such data member (i.e., if all of the data members in
    1475              :    the union are unnamed), then there is no way for a program to refer to the
    1476              :    anonymous union, and there is therefore no need to mangle its name."  */
    1477              : 
    1478              : static tree
    1479           51 : anon_aggr_naming_decl (tree type)
    1480              : {
    1481           51 :   tree field = next_aggregate_field (TYPE_FIELDS (type));
    1482          102 :   for (; field; field = next_aggregate_field (DECL_CHAIN (field)))
    1483              :     {
    1484           21 :       if (DECL_NAME (field))
    1485              :         return field;
    1486            0 :       if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
    1487            0 :         if (tree sub = anon_aggr_naming_decl (TREE_TYPE (field)))
    1488              :           return sub;
    1489              :     }
    1490              :   return NULL_TREE;
    1491              : }
    1492              : 
    1493              : /* We don't need to handle thunks, vtables, or VTTs here.  Those are
    1494              :    mangled through special entry points.
    1495              : 
    1496              :     <unqualified-name>  ::= [<module-name>] <operator-name>
    1497              :                         ::= <special-name>
    1498              :                         ::= [<module-name>] <source-name>
    1499              :                         ::= [<module-name>] <unnamed-type-name>
    1500              :                         ::= <local-source-name>
    1501              :                         ::= F <source-name> # member-like constrained friend
    1502              : 
    1503              :     <local-source-name>   ::= L <source-name> <discriminator> */
    1504              : 
    1505              : static void
    1506      5045675 : write_unqualified_id (tree identifier)
    1507              : {
    1508      5045675 :   if (IDENTIFIER_CONV_OP_P (identifier))
    1509           15 :     write_conversion_operator_name (TREE_TYPE (identifier));
    1510      5045660 :   else if (IDENTIFIER_OVL_OP_P (identifier))
    1511              :     {
    1512        54203 :       const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (identifier);
    1513        54203 :       write_string (ovl_op->mangled_name);
    1514        54203 :     }
    1515      4991457 :   else if (UDLIT_OPER_P (identifier))
    1516            0 :     write_literal_operator_name (identifier);
    1517              :   else
    1518      4991457 :     write_source_name (identifier);
    1519      5045675 : }
    1520              : 
    1521              : static void
    1522    838688195 : write_unqualified_name (tree decl)
    1523              : {
    1524    838688195 :   MANGLE_TRACE_TREE ("unqualified-name", decl);
    1525              : 
    1526    838688195 :   if (modules_p ())
    1527      1857360 :     maybe_write_module (decl);
    1528              : 
    1529    838688195 :   if (identifier_p (decl))
    1530              :     {
    1531            0 :       write_unqualified_id (decl);
    1532            0 :       return;
    1533              :     }
    1534              : 
    1535    838688195 :   bool found = false;
    1536              : 
    1537    838688195 :   if (DECL_NAME (decl) == NULL_TREE
    1538    838688195 :       && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
    1539           21 :     decl = anon_aggr_naming_decl (TREE_TYPE (decl));
    1540    838688174 :   else if (DECL_NAME (decl) == NULL_TREE)
    1541              :     {
    1542        11805 :       found = true;
    1543        11805 :       gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
    1544        11805 :       write_source_name (DECL_ASSEMBLER_NAME (decl));
    1545              :     }
    1546    838676369 :   else if (DECL_DECLARES_FUNCTION_P (decl))
    1547              :     {
    1548    194485995 :       found = true;
    1549              : 
    1550              :       /* A constrained hidden friend is mangled like a member function, with
    1551              :          the name prefixed by 'F'.  */
    1552    194485995 :       if (member_like_constrained_friend_p (decl))
    1553        22610 :         write_char ('F');
    1554              : 
    1555    388971990 :       if (DECL_CONSTRUCTOR_P (decl))
    1556     30938336 :         write_special_name_constructor (decl);
    1557    163547659 :       else if (DECL_DESTRUCTOR_P (decl))
    1558      7502484 :         write_special_name_destructor (decl);
    1559    156045175 :       else if (DECL_CONV_FN_P (decl))
    1560              :         {
    1561              :           /* Conversion operator. Handle it right here.
    1562              :              <operator> ::= cv <type>  */
    1563      2761544 :           tree type;
    1564      2761544 :           if (maybe_template_info (decl))
    1565              :             {
    1566          604 :               tree fn_type;
    1567          604 :               fn_type = get_mostly_instantiated_function_type (decl);
    1568          604 :               type = TREE_TYPE (fn_type);
    1569              :             }
    1570      2760940 :           else if (FNDECL_USED_AUTO (decl))
    1571           60 :             type = DECL_SAVED_AUTO_RETURN_TYPE (decl);
    1572              :           else
    1573      2760880 :             type = DECL_CONV_FN_TYPE (decl);
    1574      2761544 :           write_conversion_operator_name (type);
    1575              :         }
    1576    153283631 :       else if (DECL_OVERLOADED_OPERATOR_P (decl))
    1577              :         {
    1578     34997192 :           tree t;
    1579     34997192 :           if (!(t = DECL_RAMP_FN (decl)))
    1580     34996800 :             t = decl;
    1581     34997192 :           const char *mangled_name
    1582     34997192 :             = (ovl_op_info[DECL_ASSIGNMENT_OPERATOR_P (t)]
    1583     34997192 :                [DECL_OVERLOADED_OPERATOR_CODE_RAW (t)].mangled_name);
    1584     34997192 :           write_string (mangled_name);
    1585              :         }
    1586    118286439 :       else if (UDLIT_OPER_P (DECL_NAME (decl)))
    1587       309334 :         write_literal_operator_name (DECL_NAME (decl));
    1588              :       else
    1589              :         found = false;
    1590              :     }
    1591              : 
    1592     76520716 :   if (found)
    1593              :     /* OK */;
    1594    762167500 :   else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
    1595       125847 :            && DECL_NAMESPACE_SCOPE_P (decl)
    1596    762239469 :            && decl_linkage (decl) == lk_internal)
    1597              :     {
    1598        60564 :       MANGLE_TRACE_TREE ("local-source-name", decl);
    1599        60564 :       write_char ('L');
    1600        60564 :       write_source_name (DECL_NAME (decl));
    1601              :       /* The default discriminator is 1, and that's all we ever use,
    1602              :          so there's no code to output one here.  */
    1603              :     }
    1604              :   else
    1605              :     {
    1606    762106936 :       tree type = TREE_TYPE (decl);
    1607              : 
    1608    762106936 :       if (TREE_CODE (decl) == TYPE_DECL
    1609    762106936 :           && enum_with_enumerator_for_linkage_p (type))
    1610           20 :         write_unnamed_enum_name (type);
    1611   1131397557 :       else if (TREE_CODE (decl) == TYPE_DECL && TYPE_UNNAMED_P (type))
    1612         1538 :         write_unnamed_type_name (type);
    1613   1104489949 :       else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type))
    1614      2373144 :         write_closure_type_name (type);
    1615              :       else
    1616    759732234 :         write_source_name (DECL_NAME (decl));
    1617              :     }
    1618              : 
    1619              :   /* We use the ABI tags from the primary class template, ignoring tags on any
    1620              :      specializations.  This is necessary because C++ doesn't require a
    1621              :      specialization to be declared before it is used unless the use requires a
    1622              :      complete type, but we need to get the tags right on incomplete types as
    1623              :      well.  */
    1624    838688195 :   if (tree tmpl = most_general_template (decl))
    1625              :     {
    1626    493324751 :       tree res = DECL_TEMPLATE_RESULT (tmpl);
    1627    493324751 :       if (res == NULL_TREE)
    1628              :         /* UNBOUND_CLASS_TEMPLATE.  */;
    1629    493324748 :       else if (DECL_DECLARES_TYPE_P (decl))
    1630              :         decl = res;
    1631    170612822 :       else if (any_abi_below (11))
    1632              :         {
    1633              :           /* ABI v10 implicit tags on the template.  */
    1634        81578 :           tree mtags = missing_abi_tags (res);
    1635              :           /* Explicit tags on the template.  */
    1636        81578 :           tree ttags = get_abi_tags (res);
    1637              :           /* Tags on the instantiation.  */
    1638        81578 :           tree dtags = get_abi_tags (decl);
    1639              : 
    1640        81656 :           if (mtags && abi_warn_or_compat_version_crosses (10))
    1641            6 :             G.need_abi_warning = 1;
    1642              : 
    1643              :           /* Add the v10 tags to the explicit tags now.  */
    1644        81578 :           mtags = chainon (mtags, ttags);
    1645              : 
    1646        81578 :           if (!G.need_abi_warning
    1647       163058 :               && abi_warn_or_compat_version_crosses (11)
    1648       163062 :               && !equal_abi_tags (dtags, mtags, /*ignore_inherited_p=*/false))
    1649            6 :             G.need_abi_warning = 1;
    1650              : 
    1651        81578 :           if (!abi_version_at_least (10))
    1652              :             /* In abi <10, we only got the explicit tags.  */
    1653              :             decl = res;
    1654          911 :           else if (flag_abi_version == 10)
    1655              :             {
    1656              :               /* In ABI 10, we want explicit and implicit tags.  */
    1657           72 :               write_abi_tags (mtags);
    1658           72 :               return;
    1659              :             }
    1660              :         }
    1661              :     }
    1662              : 
    1663    838688123 :   tree tags = get_abi_tags (decl);
    1664    189496365 :   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CONV_FN_P (decl)
    1665    841449667 :       && any_abi_below (11))
    1666         2731 :     if (tree mtags = missing_abi_tags (decl))
    1667              :       {
    1668            9 :         if (!abi_check (11))
    1669            6 :           tags = chainon (mtags, tags);
    1670              :       }
    1671    838688123 :   write_abi_tags (tags);
    1672              : }
    1673              : 
    1674              : /* Write the unqualified-name for a conversion operator to TYPE.  */
    1675              : 
    1676              : static void
    1677      2761559 : write_conversion_operator_name (const tree type)
    1678              : {
    1679      2761559 :   write_string ("cv");
    1680      2761559 :   write_type (type);
    1681      2761559 : }
    1682              : 
    1683              : /* Non-terminal <source-name>.  IDENTIFIER is an IDENTIFIER_NODE.
    1684              : 
    1685              :      <source-name> ::= </length/ number> <identifier>  */
    1686              : 
    1687              : static void
    1688    764816499 : write_source_name (tree identifier)
    1689              : {
    1690    764816499 :   MANGLE_TRACE_TREE ("source-name", identifier);
    1691              : 
    1692    764816499 :   write_unsigned_number (IDENTIFIER_LENGTH (identifier));
    1693    764816499 :   write_identifier (IDENTIFIER_POINTER (identifier));
    1694    764816499 : }
    1695              : 
    1696              : /* Compare two TREE_STRINGs like strcmp.  */
    1697              : 
    1698              : static int
    1699          306 : tree_string_cmp (const void *p1, const void *p2)
    1700              : {
    1701          306 :   if (p1 == p2)
    1702              :     return 0;
    1703          306 :   tree s1 = *(const tree*)p1;
    1704          306 :   tree s2 = *(const tree*)p2;
    1705          306 :   return strcmp (TREE_STRING_POINTER (s1),
    1706          306 :                  TREE_STRING_POINTER (s2));
    1707              : }
    1708              : 
    1709              : /* Return the TREE_LIST of TAGS as a sorted VEC.  */
    1710              : 
    1711              : static vec<tree, va_gc> *
    1712       508358 : sorted_abi_tags (tree tags, bool ignore_inherited_p)
    1713              : {
    1714       508358 :   vec<tree, va_gc> * vec = make_tree_vector();
    1715              : 
    1716       853814 :   for (tree t = tags; t; t = TREE_CHAIN (t))
    1717              :     {
    1718       345456 :       if (ABI_TAG_NOT_MANGLED (t)
    1719       345456 :           || (ignore_inherited_p && ABI_TAG_INHERITED (t)))
    1720            6 :         continue;
    1721       345450 :       tree str = TREE_VALUE (t);
    1722       345450 :       vec_safe_push (vec, str);
    1723              :     }
    1724              : 
    1725       508358 :   vec->qsort (tree_string_cmp);
    1726              : 
    1727       508358 :   return vec;
    1728              : }
    1729              : 
    1730              : /* ID is the name of a function or type with abi_tags attribute TAGS.
    1731              :    Write out the name, suitably decorated.  */
    1732              : 
    1733              : static void
    1734    838688231 : write_abi_tags (tree tags)
    1735              : {
    1736    838688231 :   if (tags == NULL_TREE)
    1737    838688231 :     return;
    1738              : 
    1739       345324 :   vec<tree, va_gc> * vec = sorted_abi_tags (tags, /*ignore_inherited_p=*/false);
    1740              : 
    1741       345324 :   unsigned i; tree str;
    1742      1035999 :   FOR_EACH_VEC_ELT (*vec, i, str)
    1743              :     {
    1744       345351 :       write_string ("B");
    1745       345351 :       write_unsigned_number (TREE_STRING_LENGTH (str) - 1);
    1746       345351 :       write_identifier (TREE_STRING_POINTER (str));
    1747              :     }
    1748              : 
    1749       345324 :   release_tree_vector (vec);
    1750              : }
    1751              : 
    1752              : /* True iff the TREE_LISTS T1 and T2 of ABI tags are equivalent.  */
    1753              : 
    1754              : bool
    1755        81517 : equal_abi_tags (tree t1, tree t2, bool ignore_inherited_p)
    1756              : {
    1757        81517 :   releasing_vec v1 = sorted_abi_tags (t1, ignore_inherited_p);
    1758        81517 :   releasing_vec v2 = sorted_abi_tags (t2, ignore_inherited_p);
    1759              : 
    1760        81517 :   unsigned len1 = v1->length();
    1761        81517 :   if (len1 != v2->length())
    1762              :     return false;
    1763        81511 :   for (unsigned i = 0; i < len1; ++i)
    1764           21 :     if (strcmp (TREE_STRING_POINTER (v1[i]),
    1765           21 :                 TREE_STRING_POINTER (v2[i])) != 0)
    1766              :       return false;
    1767              :   return true;
    1768        81517 : }
    1769              : 
    1770              : /* Write a user-defined literal operator.
    1771              :           ::= li <source-name>    # "" <source-name>
    1772              :    IDENTIFIER is an LITERAL_IDENTIFIER_NODE.  */
    1773              : 
    1774              : static void
    1775       309334 : write_literal_operator_name (tree identifier)
    1776              : {
    1777       309334 :   const char* suffix = UDLIT_OP_SUFFIX (identifier);
    1778       309334 :   write_identifier (UDLIT_OP_MANGLED_PREFIX);
    1779       309334 :   write_unsigned_number (strlen (suffix));
    1780       309334 :   write_identifier (suffix);
    1781       309334 : }
    1782              : 
    1783              : /* Encode 0 as _, and 1+ as n-1_.  */
    1784              : 
    1785              : static void
    1786     32238144 : write_compact_number (int num)
    1787              : {
    1788     32238144 :   gcc_checking_assert (num >= 0);
    1789     32238144 :   if (num > 0)
    1790     12478528 :     write_unsigned_number (num - 1);
    1791     32238144 :   write_char ('_');
    1792     32238144 : }
    1793              : 
    1794              : /* Return how many unnamed types precede TYPE in its enclosing class.  */
    1795              : 
    1796              : static int
    1797          839 : nested_anon_class_index (tree type)
    1798              : {
    1799          839 :   int index = 0;
    1800          839 :   tree member = TYPE_FIELDS (TYPE_CONTEXT (type));
    1801        22181 :   for (; member; member = DECL_CHAIN (member))
    1802        22181 :     if (DECL_IMPLICIT_TYPEDEF_P (member))
    1803              :       {
    1804         1299 :         tree memtype = TREE_TYPE (member);
    1805         1299 :         if (memtype == type)
    1806              :           return index;
    1807         1124 :         else if (TYPE_UNNAMED_P (memtype))
    1808          204 :           ++index;
    1809              :       }
    1810              : 
    1811            0 :   if (seen_error ())
    1812              :     return -1;
    1813              : 
    1814            0 :   gcc_unreachable ();
    1815              : }
    1816              : 
    1817              : /* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
    1818              : 
    1819              : static void
    1820         1538 : write_unnamed_type_name (const tree type)
    1821              : {
    1822         1538 :   int discriminator;
    1823         1538 :   MANGLE_TRACE_TREE ("unnamed-type-name", type);
    1824              : 
    1825         1538 :   if (TYPE_FUNCTION_SCOPE_P (type))
    1826          358 :     discriminator = discriminator_for_local_entity (TYPE_NAME (type));
    1827         1180 :   else if (TYPE_CLASS_SCOPE_P (type))
    1828          839 :     discriminator = nested_anon_class_index (type);
    1829              :   else
    1830              :     {
    1831          341 :       gcc_assert (no_linkage_check (type, /*relaxed_p=*/true));
    1832              :       /* Just use the old mangling at namespace scope.  */
    1833          341 :       write_source_name (TYPE_IDENTIFIER (type));
    1834          341 :       return;
    1835              :     }
    1836              : 
    1837         1197 :   write_string ("Ut");
    1838         1197 :   write_compact_number (discriminator);
    1839              : }
    1840              : 
    1841              : /* <unnamed-enum-name> ::= Ue <underlying type> <enumerator source-name> */
    1842              : 
    1843              : static void
    1844           20 : write_unnamed_enum_name (const tree type)
    1845              : {
    1846           20 :   MANGLE_TRACE_TREE ("unnamed-enum-name", type);
    1847           20 :   write_string ("Ue");
    1848           20 :   write_type (ENUM_UNDERLYING_TYPE (type));
    1849           20 :   write_source_name (DECL_NAME (TREE_VALUE (TYPE_VALUES (type))));
    1850           20 : }
    1851              : 
    1852              : /* ABI issue #47: if a function template parameter is not "natural" for its
    1853              :    argument we must mangle the parameter.  */
    1854              : 
    1855              : static bool
    1856      8634140 : template_parm_natural_p (tree arg, tree parm)
    1857              : {
    1858      8634140 :   tree decl = TREE_VALUE (parm);
    1859              : 
    1860              :   /* A template parameter is "natural" if: */
    1861              : 
    1862      8634140 :   if (template_parameter_pack_p (decl))
    1863              :     {
    1864       843974 :       tree args = ARGUMENT_PACK_ARGS (arg);
    1865       843974 :       if (TREE_VEC_LENGTH (args) == 0)
    1866              :         {
    1867              : #if 0
    1868              :           /* the argument is an empty pack and the parameter is an
    1869              :              unconstrained template type parameter pack; */
    1870              :           if (TREE_CODE (decl) != TYPE_DECL)
    1871              :             return false;
    1872              : #else
    1873              :           /* Defer changing the mangling of C++11 code like
    1874              :              template <int i> int max();
    1875              :              template <int i, int j, int... rest> int max();  */
    1876              :           return true;
    1877              : #endif
    1878              :         }
    1879              :       else
    1880              :         /* the argument is a non-empty pack and a non-pack variant of the
    1881              :            parameter would be natural for the first element of the pack; */
    1882       661057 :         arg = TREE_VEC_ELT (args, 0);
    1883              :     }
    1884              : 
    1885              :   /* the argument is a template and the parameter has the exact
    1886              :      same template head; */
    1887      8451223 :   if (TREE_CODE (decl) == TEMPLATE_DECL)
    1888         9142 :     return template_heads_equivalent_p (arg, decl);
    1889              : 
    1890              :   /* the argument is a type and the parameter is unconstrained; or */
    1891      8442081 :   else if (TREE_CODE (decl) == TYPE_DECL)
    1892      7408604 :     return !TEMPLATE_PARM_CONSTRAINTS (parm);
    1893              : 
    1894              :   /* the argument is a non-type template argument and the declared parameter
    1895              :      type neither is instantiation dependent nor contains deduced types.  */
    1896      1033477 :   else if (TREE_CODE (decl) == PARM_DECL)
    1897              :     {
    1898              : #if 0
    1899              :       return !uses_template_parms (TREE_TYPE (decl));
    1900              : #else
    1901              :       /* Defer changing the mangling of C++98 code like
    1902              :          template <class T, T V> ....  */
    1903      1033477 :       return !type_uses_auto (TREE_TYPE (decl));
    1904              : #endif
    1905              :     }
    1906              : 
    1907            0 :   gcc_unreachable ();
    1908              : }
    1909              : 
    1910              : /* Used for lambda template head and non-natural function template parameters.
    1911              : 
    1912              :    <template-param-decl> ::= Ty               # template type parameter
    1913              :         ::= Tk <type-constraint>              # constrained type parameter
    1914              :         ::= Tn <type>                         # template non-type parameter
    1915              :         ::= Tt <template-param-decl>* [Q <constraint-expression] E  # ttp
    1916              :         ::= Tp <non-pack template-param-decl> # template parameter pack */
    1917              : 
    1918              : static void
    1919       115159 : write_template_param_decl (tree parm)
    1920              : {
    1921       115159 :   tree decl = TREE_VALUE (parm);
    1922              : 
    1923       115159 :   if (template_parameter_pack_p (decl))
    1924        41221 :     write_string ("Tp");
    1925              : 
    1926       115159 :   switch (TREE_CODE (decl))
    1927              :     {
    1928        48151 :     case PARM_DECL:
    1929        48151 :       {
    1930        48151 :         write_string ("Tn");
    1931              : 
    1932        48151 :         tree type = TREE_TYPE (decl);
    1933              :         /* TODO: We need to also mangle constrained auto*, auto&, etc, but
    1934              :            it's not clear how.  See finish_constrained_parameter.  */
    1935        48151 :         if (tree c = (is_auto (type)
    1936        52530 :                       ? TEMPLATE_PARM_CONSTRAINTS (parm)
    1937         4379 :                       : NULL_TREE))
    1938              :           {
    1939           22 :             if (TREE_CODE (c) == UNARY_LEFT_FOLD_EXPR)
    1940              :               {
    1941            3 :                 c = FOLD_EXPR_PACK (c);
    1942            3 :                 c = PACK_EXPANSION_PATTERN (c);
    1943              :               }
    1944           22 :             if (AUTO_IS_DECLTYPE (type))
    1945            0 :               write_string ("DK");
    1946              :             else
    1947           22 :               write_string ("Dk");
    1948           22 :             write_type_constraint (c);
    1949              :           }
    1950              :         else
    1951        48129 :           write_type (type);
    1952              :       }
    1953              :       break;
    1954              : 
    1955          351 :     case TEMPLATE_DECL:
    1956          351 :       {
    1957          351 :         write_string ("Tt");
    1958          351 :         tree parms = DECL_INNERMOST_TEMPLATE_PARMS (decl);
    1959          812 :         for (tree node : tree_vec_range (parms))
    1960          461 :           write_template_param_decl (node);
    1961          351 :         write_char ('E');
    1962              :       }
    1963          351 :       break;
    1964              : 
    1965        66657 :     case TYPE_DECL:
    1966        66657 :       if (tree c = TEMPLATE_PARM_CONSTRAINTS (parm))
    1967              :         {
    1968        36923 :           if (TREE_CODE (c) == UNARY_LEFT_FOLD_EXPR)
    1969              :             {
    1970           70 :               c = FOLD_EXPR_PACK (c);
    1971           70 :               c = PACK_EXPANSION_PATTERN (c);
    1972              :             }
    1973        36923 :           if (TREE_CODE (decl) == TYPE_DECL)
    1974              :             {
    1975        36923 :               write_string ("Tk");
    1976        36923 :               write_type_constraint (c);
    1977              :             }
    1978              :         }
    1979              :       else
    1980        29734 :         write_string ("Ty");
    1981              :       break;
    1982              : 
    1983            0 :     default:
    1984            0 :       gcc_unreachable ();
    1985              :     }
    1986       115159 : }
    1987              : 
    1988              : // A template head, for templated lambdas.
    1989              : // New in ABI=18. Returns true iff we emitted anything -- used for ABI
    1990              : // version warning.
    1991              : 
    1992              : static bool
    1993       517554 : write_closure_template_head (tree tmpl)
    1994              : {
    1995       517554 :   bool any = false;
    1996              : 
    1997              :   // We only need one level of template parms
    1998       517554 :   tree parms = DECL_TEMPLATE_PARMS (tmpl);
    1999       517554 :   tree inner = INNERMOST_TEMPLATE_PARMS (parms);
    2000              : 
    2001       591043 :   for (int ix = 0, len = TREE_VEC_LENGTH (inner); ix != len; ix++)
    2002              :     {
    2003       535942 :       tree parm = TREE_VEC_ELT (inner, ix);
    2004       535942 :       if (parm == error_mark_node)
    2005            0 :         continue;
    2006              : 
    2007       535942 :       if (DECL_IMPLICIT_TEMPLATE_PARM_P (TREE_VALUE (parm)))
    2008              :         // A synthetic parm, we're done.
    2009              :         break;
    2010              : 
    2011        73489 :       any = true;
    2012        73489 :       if (abi_version_at_least (18))
    2013        73249 :         write_template_param_decl (parm);
    2014              :     }
    2015              : 
    2016       517554 :   write_tparms_constraints (TEMPLATE_PARMS_CONSTRAINTS (parms));
    2017              : 
    2018       517554 :   return any;
    2019              : }
    2020              : 
    2021              : /* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
    2022              :    <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters */
    2023              : 
    2024              : static void
    2025      2373144 : write_closure_type_name (const tree type)
    2026              : {
    2027      2373144 :   tree fn = lambda_function (type);
    2028      2373144 :   tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
    2029      2373144 :   tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
    2030              : 
    2031      2373144 :   MANGLE_TRACE_TREE ("closure-type-name", type);
    2032              : 
    2033      2373144 :   write_string ("Ul");
    2034              : 
    2035      2373144 :   if (auto ti = maybe_template_info (fn))
    2036       517554 :     if (write_closure_template_head (TI_TEMPLATE (ti)))
    2037              :       // If there were any explicit template parms, we may need to
    2038              :       // issue a mangling diagnostic.
    2039       361005 :       if (abi_warn_or_compat_version_crosses (18))
    2040          198 :         G.need_abi_warning = true;
    2041              : 
    2042      2373144 :   write_method_parms (parms, TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE, fn);
    2043      2373144 :   write_char ('E');
    2044      2373144 :   if ((LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
    2045      2373144 :        != LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda))
    2046      3217560 :       && abi_warn_or_compat_version_crosses (18))
    2047          288 :     G.need_abi_warning = true;
    2048      4746288 :   write_compact_number (abi_version_at_least (18)
    2049      2372622 :                         ? LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
    2050          522 :                         : LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
    2051      2373144 : }
    2052              : 
    2053              : /* Convert NUMBER to ascii using base BASE and generating at least
    2054              :    MIN_DIGITS characters. BUFFER points to the _end_ of the buffer
    2055              :    into which to store the characters. Returns the number of
    2056              :    characters generated (these will be laid out in advance of where
    2057              :    BUFFER points).  */
    2058              : 
    2059              : static int
    2060   1034526586 : hwint_to_ascii (unsigned HOST_WIDE_INT number, const unsigned int base,
    2061              :                 char *buffer, const unsigned int min_digits)
    2062              : {
    2063   1034526586 :   static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    2064   1034526586 :   unsigned digits = 0;
    2065              : 
    2066   2573508741 :   while (number)
    2067              :     {
    2068   1538982155 :       unsigned HOST_WIDE_INT d = number / base;
    2069              : 
    2070   1538982155 :       *--buffer = base_digits[number - d * base];
    2071   1538982155 :       digits++;
    2072   1538982155 :       number = d;
    2073              :     }
    2074   1089476886 :   while (digits < min_digits)
    2075              :     {
    2076     54950300 :       *--buffer = base_digits[0];
    2077     54950300 :       digits++;
    2078              :     }
    2079   1034526586 :   return digits;
    2080              : }
    2081              : 
    2082              : /* Non-terminal <number>.
    2083              : 
    2084              :      <number> ::= [n] </decimal integer/>  */
    2085              : 
    2086              : static void
    2087   1034526286 : write_number (unsigned HOST_WIDE_INT number, const int unsigned_p,
    2088              :               const unsigned int base)
    2089              : {
    2090   1034526286 :   char buffer[sizeof (HOST_WIDE_INT) * 8];
    2091   1034526286 :   unsigned count = 0;
    2092              : 
    2093   1034526286 :   if (!unsigned_p && (HOST_WIDE_INT) number < 0)
    2094              :     {
    2095            0 :       write_char ('n');
    2096            0 :       number = -((HOST_WIDE_INT) number);
    2097              :     }
    2098   1034526286 :   count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1);
    2099   1034526286 :   write_chars (buffer + sizeof (buffer) - count, count);
    2100   1034526286 : }
    2101              : 
    2102              : /* Write out an integral CST in decimal. Most numbers are small, and
    2103              :    representable in a HOST_WIDE_INT. Occasionally we'll have numbers
    2104              :    bigger than that, which we must deal with.  */
    2105              : 
    2106              : static inline void
    2107     97063188 : write_integer_cst (const tree cst)
    2108              : {
    2109     97063188 :   int sign = tree_int_cst_sgn (cst);
    2110     97063188 :   widest_int abs_value = wi::abs (wi::to_widest (cst));
    2111     97063188 :   if (!wi::fits_uhwi_p (abs_value))
    2112              :     {
    2113              :       /* A bignum. We do this in chunks, each of which fits in a
    2114              :          HOST_WIDE_INT.  */
    2115          100 :       char buffer[sizeof (HOST_WIDE_INT) * 8 * 2];
    2116          100 :       unsigned HOST_WIDE_INT chunk;
    2117          100 :       unsigned chunk_digits;
    2118          100 :       char *ptr = buffer + sizeof (buffer);
    2119          100 :       unsigned count = 0;
    2120          100 :       tree n, base, type;
    2121          100 :       int done;
    2122              : 
    2123              :       /* HOST_WIDE_INT must be at least 32 bits, so 10^9 is
    2124              :          representable.  */
    2125          100 :       chunk = 1000000000;
    2126          100 :       chunk_digits = 9;
    2127              : 
    2128          100 :       if (sizeof (HOST_WIDE_INT) >= 8)
    2129              :         {
    2130              :           /* It is at least 64 bits, so 10^18 is representable.  */
    2131          100 :           chunk_digits = 18;
    2132          100 :           chunk *= chunk;
    2133              :         }
    2134              : 
    2135          100 :       type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst));
    2136          100 :       base = build_int_cstu (type, chunk);
    2137          100 :       n = wide_int_to_tree (type, wi::to_wide (cst));
    2138              : 
    2139          100 :       if (sign < 0)
    2140              :         {
    2141            0 :           write_char ('n');
    2142            0 :           n = fold_build1_loc (input_location, NEGATE_EXPR, type, n);
    2143              :         }
    2144          300 :       do
    2145              :         {
    2146          300 :           tree d = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, n, base);
    2147          300 :           tree tmp = fold_build2_loc (input_location, MULT_EXPR, type, d, base);
    2148          300 :           unsigned c;
    2149              : 
    2150          300 :           done = integer_zerop (d);
    2151          300 :           tmp = fold_build2_loc (input_location, MINUS_EXPR, type, n, tmp);
    2152          400 :           c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
    2153              :                               done ? 1 : chunk_digits);
    2154          300 :           ptr -= c;
    2155          300 :           count += c;
    2156          300 :           n = d;
    2157              :         }
    2158          300 :       while (!done);
    2159          100 :       write_chars (ptr, count);
    2160              :     }
    2161              :   else
    2162              :     {
    2163              :       /* A small num.  */
    2164     97063088 :       if (sign < 0)
    2165       498395 :         write_char ('n');
    2166     97063088 :       write_unsigned_number (abs_value.to_uhwi ());
    2167              :     }
    2168     97063188 : }
    2169              : 
    2170              : /* Write out a floating-point literal.
    2171              : 
    2172              :     "Floating-point literals are encoded using the bit pattern of the
    2173              :     target processor's internal representation of that number, as a
    2174              :     fixed-length lowercase hexadecimal string, high-order bytes first
    2175              :     (even if the target processor would store low-order bytes first).
    2176              :     The "n" prefix is not used for floating-point literals; the sign
    2177              :     bit is encoded with the rest of the number.
    2178              : 
    2179              :     Here are some examples, assuming the IEEE standard representation
    2180              :     for floating point numbers.  (Spaces are for readability, not
    2181              :     part of the encoding.)
    2182              : 
    2183              :         1.0f                    Lf 3f80 0000 E
    2184              :        -1.0f                    Lf bf80 0000 E
    2185              :         1.17549435e-38f         Lf 0080 0000 E
    2186              :         1.40129846e-45f         Lf 0000 0001 E
    2187              :         0.0f                    Lf 0000 0000 E"
    2188              : 
    2189              :    Caller is responsible for the Lx and the E.  */
    2190              : static void
    2191         2549 : write_real_cst (const tree value)
    2192              : {
    2193         2549 :   long target_real[4];  /* largest supported float */
    2194              :   /* Buffer for eight hex digits in a 32-bit number but big enough
    2195              :      even for 64-bit long to avoid warnings.  */
    2196         2549 :   char buffer[17];
    2197         2549 :   int i, limit, dir;
    2198              : 
    2199         2549 :   tree type = TREE_TYPE (value);
    2200         2549 :   int bits = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type));
    2201         2549 :   int words = bits / 32;
    2202              : 
    2203         2549 :   real_to_target (target_real, &TREE_REAL_CST (value),
    2204         2549 :                   TYPE_MODE (type));
    2205              : 
    2206         2549 :   if (words == 0)
    2207              :     {
    2208              :       /* _Float16 and std::bfloat16_t are the only supported types smaller than
    2209              :          32 bits.  */
    2210          382 :       gcc_assert (bits == 16);
    2211          382 :       sprintf (buffer, "%04lx", (unsigned long) target_real[0]);
    2212          382 :       write_chars (buffer, 4);
    2213          382 :       return;
    2214              :     }
    2215              : 
    2216         2167 :   gcc_assert (bits % 32 == 0);
    2217              : 
    2218              :   /* The value in target_real is in the target word order,
    2219              :      so we must write it out backward if that happens to be
    2220              :      little-endian.  write_number cannot be used, it will
    2221              :      produce uppercase.  */
    2222         2167 :   if (FLOAT_WORDS_BIG_ENDIAN)
    2223              :     i = 0, limit = words, dir = 1;
    2224              :   else
    2225         2167 :     i = words - 1, limit = -1, dir = -1;
    2226              : 
    2227         2195 :   if (GET_MODE_PRECISION (SCALAR_FLOAT_TYPE_MODE (type)) == 80
    2228         2167 :       && abi_check (21))
    2229              :     {
    2230              :       /* For -fabi-version=21 and above mangle
    2231              :          Intel/Motorola extended format 1.0L as
    2232              :          3fff8000000000000000
    2233              :          rather than the previous
    2234              :          0000000000003fff8000000000000000 (x86_64)
    2235              :          00003fff8000000000000000 (ia32)
    2236              :          3fff00008000000000000000 (m68k -mc68020)
    2237              :          i.e. without any embedded padding bits.  */
    2238           30 :       if (words == 4)
    2239              :         i += dir;
    2240              :       else
    2241            0 :         gcc_assert (words == 3);
    2242           30 :       unsigned long val = (unsigned long) target_real[i];
    2243           30 :       if (REAL_MODE_FORMAT (SCALAR_FLOAT_TYPE_MODE (type))->signbit_ro == 95)
    2244            0 :         val >>= 16;
    2245           30 :       sprintf (buffer, "%04lx", val);
    2246           30 :       write_chars (buffer, 4);
    2247           30 :       i += dir;
    2248              :     }
    2249              : 
    2250         6033 :   for (; i != limit; i += dir)
    2251              :     {
    2252         3866 :       sprintf (buffer, "%08lx", (unsigned long) target_real[i]);
    2253         3866 :       write_chars (buffer, 8);
    2254              :     }
    2255              : }
    2256              : 
    2257              : /* Non-terminal <identifier>.
    2258              : 
    2259              :      <identifier> ::= </unqualified source code identifier>  */
    2260              : 
    2261              : static void
    2262    766522770 : write_identifier (const char *identifier)
    2263              : {
    2264    766522770 :   MANGLE_TRACE ("identifier", identifier);
    2265    766522770 :   write_string (identifier);
    2266    766522770 : }
    2267              : 
    2268              : /* Handle constructor productions of non-terminal <special-name>.
    2269              :    CTOR is a constructor FUNCTION_DECL.
    2270              : 
    2271              :      <special-name> ::= C1   # complete object constructor
    2272              :                     ::= C2   # base object constructor
    2273              :                     ::= C3   # complete object allocating constructor
    2274              : 
    2275              :    Currently, allocating constructors are never used.  */
    2276              : 
    2277              : static void
    2278     30938336 : write_special_name_constructor (const tree ctor)
    2279              : {
    2280     30938336 :   write_char ('C');
    2281     30938336 :   bool new_inh = (flag_new_inheriting_ctors
    2282     61860945 :                   && DECL_INHERITED_CTOR (ctor));
    2283       163059 :   if (new_inh)
    2284       163059 :     write_char ('I');
    2285     30938336 :   if (DECL_BASE_CONSTRUCTOR_P (ctor))
    2286      6384045 :     write_char ('2');
    2287              :   /* This is the old-style "[unified]" constructor.
    2288              :      In some cases, we may emit this function and call
    2289              :      it from the clones in order to share code and save space.  */
    2290     24554291 :   else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor))
    2291     18173761 :     write_char ('4');
    2292              :   else
    2293              :     {
    2294      6380530 :       gcc_assert (DECL_COMPLETE_CONSTRUCTOR_P (ctor));
    2295      6380530 :       write_char ('1');
    2296              :     }
    2297     30938336 :   if (new_inh)
    2298       326118 :     write_type (DECL_INHERITED_CTOR_BASE (ctor));
    2299     30938336 : }
    2300              : 
    2301              : /* Handle destructor productions of non-terminal <special-name>.
    2302              :    DTOR is a destructor FUNCTION_DECL.
    2303              : 
    2304              :      <special-name> ::= D0 # deleting (in-charge) destructor
    2305              :                     ::= D1 # complete object (in-charge) destructor
    2306              :                     ::= D2 # base object (not-in-charge) destructor  */
    2307              : 
    2308              : static void
    2309      7502484 : write_special_name_destructor (const tree dtor)
    2310              : {
    2311      7502484 :   if (DECL_DELETING_DESTRUCTOR_P (dtor))
    2312       634013 :     write_string ("D0");
    2313      6868471 :   else if (DECL_BASE_DESTRUCTOR_P (dtor))
    2314      1639055 :     write_string ("D2");
    2315      5229416 :   else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor))
    2316              :     /* This is the old-style "[unified]" destructor.
    2317              :        In some cases, we may emit this function and call
    2318              :        it from the clones in order to share code and save space.  */
    2319      2982082 :     write_string ("D4");
    2320              :   else
    2321              :     {
    2322      2247334 :       gcc_assert (DECL_COMPLETE_DESTRUCTOR_P (dtor));
    2323      2247334 :       write_string ("D1");
    2324              :     }
    2325      7502484 : }
    2326              : 
    2327              : /* Return the discriminator for ENTITY appearing inside
    2328              :    FUNCTION.  The discriminator is the lexical ordinal of VAR or TYPE among
    2329              :    entities with the same name and kind in the same FUNCTION.  */
    2330              : 
    2331              : static int
    2332      2866318 : discriminator_for_local_entity (tree entity)
    2333              : {
    2334      2866318 :   if (!DECL_LANG_SPECIFIC (entity))
    2335              :     {
    2336              :       /* Some decls, like __FUNCTION__, don't need a discriminator.  */
    2337        32059 :       gcc_checking_assert (DECL_ARTIFICIAL (entity));
    2338              :       return 0;
    2339              :     }
    2340      5522243 :   else if (tree disc = DECL_DISCRIMINATOR (entity))
    2341          511 :     return TREE_INT_CST_LOW (disc);
    2342              :   else
    2343              :     /* The first entity with a particular name doesn't get
    2344              :        DECL_DISCRIMINATOR set up.  */
    2345              :     return 0;
    2346              : }
    2347              : 
    2348              : /* Return the discriminator for STRING, a string literal used inside
    2349              :    FUNCTION.  The discriminator is the lexical ordinal of STRING among
    2350              :    string literals used in FUNCTION.  */
    2351              : 
    2352              : static int
    2353            0 : discriminator_for_string_literal (tree /*function*/,
    2354              :                                   tree /*string*/)
    2355              : {
    2356              :   /* For now, we don't discriminate amongst string literals.  */
    2357            0 :   return 0;
    2358              : }
    2359              : 
    2360              : /*   <discriminator> := _ <number>    # when number < 10
    2361              :                      := __ <number> _ # when number >= 10
    2362              : 
    2363              :    The discriminator is used only for the second and later occurrences
    2364              :    of the same name within a single function. In this case <number> is
    2365              :    n - 2, if this is the nth occurrence, in lexical order.  */
    2366              : 
    2367              : static void
    2368      2865960 : write_discriminator (const int discriminator)
    2369              : {
    2370              :   /* If discriminator is zero, don't write anything.  Otherwise...  */
    2371      2865960 :   if (discriminator > 0)
    2372              :     {
    2373          478 :       write_char ('_');
    2374          478 :       if (discriminator - 1 >= 10)
    2375              :         {
    2376            6 :           if (abi_check (11))
    2377            6 :             write_char ('_');
    2378              :         }
    2379          478 :       write_unsigned_number (discriminator - 1);
    2380          478 :       if (abi_version_at_least (11) && discriminator - 1 >= 10)
    2381            6 :         write_char ('_');
    2382              :     }
    2383      2865960 : }
    2384              : 
    2385              : /* Mangle the name of a function-scope entity.  FUNCTION is the
    2386              :    FUNCTION_DECL for the enclosing function, or a PARM_DECL for lambdas in
    2387              :    default argument scope.  ENTITY is the decl for the entity itself.
    2388              :    LOCAL_ENTITY is the entity that's directly scoped in FUNCTION_DECL,
    2389              :    either ENTITY itself or an enclosing scope of ENTITY.
    2390              : 
    2391              :      <local-name> := Z <function encoding> E <entity name> [<discriminator>]
    2392              :                   := Z <function encoding> E s [<discriminator>]
    2393              :                   := Z <function encoding> Ed [ <parameter number> ] _ <entity name> */
    2394              : 
    2395              : static void
    2396      5167255 : write_local_name (tree function, const tree local_entity,
    2397              :                   const tree entity)
    2398              : {
    2399      5167255 :   tree parm = NULL_TREE;
    2400              : 
    2401      5167255 :   MANGLE_TRACE_TREE ("local-name", entity);
    2402              : 
    2403      5167255 :   if (TREE_CODE (function) == PARM_DECL)
    2404              :     {
    2405          366 :       parm = function;
    2406          366 :       function = DECL_CONTEXT (parm);
    2407              :     }
    2408              : 
    2409      5167255 :   write_char ('Z');
    2410      5167255 :   write_encoding (function);
    2411      5167255 :   write_char ('E');
    2412              : 
    2413              :   /* For this purpose, parameters are numbered from right-to-left.  */
    2414      5167255 :   if (parm)
    2415              :     {
    2416          366 :       int i = list_length (parm);
    2417          366 :       write_char ('d');
    2418          366 :       write_compact_number (i - 1);
    2419              :     }
    2420              : 
    2421      5167255 :   if (TREE_CODE (entity) == STRING_CST)
    2422              :     {
    2423            0 :       write_char ('s');
    2424            0 :       write_discriminator (discriminator_for_string_literal (function,
    2425              :                                                              entity));
    2426              :     }
    2427              :   else
    2428              :     {
    2429              :       /* Now the <entity name>.  Let write_name know its being called
    2430              :          from <local-name>, so it doesn't try to process the enclosing
    2431              :          function scope again.  */
    2432      5167255 :       write_name (entity, /*ignore_local_scope=*/true);
    2433      5167255 :       if (DECL_DISCRIMINATOR_P (local_entity)
    2434     15322758 :           && !(TREE_CODE (local_entity) == TYPE_DECL
    2435     14966157 :                && TYPE_ANON_P (TREE_TYPE (local_entity))))
    2436      2865691 :         write_discriminator (discriminator_for_local_entity (local_entity));
    2437              :     }
    2438      5167255 : }
    2439              : 
    2440              : /* Non-terminals <type> and <CV-qualifier>.
    2441              : 
    2442              :      <type> ::= <builtin-type>
    2443              :             ::= <function-type>
    2444              :             ::= <class-enum-type>
    2445              :             ::= <array-type>
    2446              :             ::= <pointer-to-member-type>
    2447              :             ::= <template-param>
    2448              :             ::= <substitution>
    2449              :             ::= <CV-qualifier>
    2450              :             ::= P <type>    # pointer-to
    2451              :             ::= R <type>    # reference-to
    2452              :             ::= C <type>    # complex pair (C 2000)
    2453              :             ::= G <type>    # imaginary (C 2000)     [not supported]
    2454              :             ::= U <source-name> <type>   # vendor extended type qualifier
    2455              : 
    2456              :    C++11 extensions
    2457              : 
    2458              :      <type> ::= RR <type>   # rvalue reference-to
    2459              :      <type> ::= Dt <expression> # decltype of an id-expression or
    2460              :                                 # class member access
    2461              :      <type> ::= DT <expression> # decltype of an expression
    2462              :      <type> ::= Dn              # decltype of nullptr
    2463              :      <type> ::= Dm                # decltype of ^^int
    2464              :      <type> ::= <splice>    # C++26 dependent splice [proposed]
    2465              : 
    2466              :    TYPE is a type node.  */
    2467              : 
    2468              : static void
    2469   1309831010 : write_type (tree type)
    2470              : {
    2471              :   /* This gets set to nonzero if TYPE turns out to be a (possibly
    2472              :      CV-qualified) builtin type.  */
    2473   1309831019 :   int is_builtin_type = 0;
    2474              : 
    2475   1309831019 :   MANGLE_TRACE_TREE ("type", type);
    2476              : 
    2477   1309831019 :   if (type == error_mark_node)
    2478              :     return;
    2479              : 
    2480   1309831004 :   type = canonicalize_for_substitution (type);
    2481   1309831004 :   if (find_substitution (type))
    2482              :     return;
    2483              : 
    2484              : 
    2485   1195144941 :   if (write_CV_qualifiers_for_type (type) > 0)
    2486              :     /* If TYPE was CV-qualified, we just wrote the qualifiers; now
    2487              :        mangle the unqualified type.  The recursive call is needed here
    2488              :        since both the qualified and unqualified types are substitution
    2489              :        candidates.  */
    2490              :     {
    2491     84416601 :       tree t = TYPE_MAIN_VARIANT (type);
    2492     84416601 :       if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t))
    2493              :         {
    2494           99 :           tree attrs = NULL_TREE;
    2495           99 :           if (tx_safe_fn_type_p (type))
    2496            3 :             attrs = tree_cons (get_identifier ("transaction_safe"),
    2497              :                                NULL_TREE, attrs);
    2498           99 :           t = cp_build_type_attribute_variant (t, attrs);
    2499              :         }
    2500     84416601 :       gcc_assert (t != type);
    2501     84416601 :       if (FUNC_OR_METHOD_TYPE_P (t))
    2502              :         {
    2503         6725 :           t = build_ref_qualified_type (t, type_memfn_rqual (type));
    2504         6725 :           if (flag_noexcept_type)
    2505              :             {
    2506         6704 :               tree r = TYPE_RAISES_EXCEPTIONS (type);
    2507         6704 :               t = build_exception_variant (t, r);
    2508              :             }
    2509         6725 :           if (abi_version_at_least (8)
    2510         6749 :               || type == TYPE_MAIN_VARIANT (type))
    2511              :             /* Avoid adding the unqualified function type as a substitution.  */
    2512         6701 :             write_function_type (t);
    2513              :           else
    2514           24 :             write_type (t);
    2515        33508 :           if (abi_warn_or_compat_version_crosses (8))
    2516           39 :             G.need_abi_warning = 1;
    2517              :         }
    2518              :       else
    2519     84409876 :         write_type (t);
    2520              :     }
    2521   1110728340 :   else if (TREE_CODE (type) == ARRAY_TYPE)
    2522              :     /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
    2523              :        so that the cv-qualification of the element type is available
    2524              :        in write_array_type.  */
    2525      1581634 :     write_array_type (type);
    2526              :   else
    2527              :     {
    2528   1109146706 :       tree type_orig = type;
    2529              : 
    2530              :       /* See through any typedefs.  */
    2531   1109146706 :       type = TYPE_MAIN_VARIANT (type);
    2532   1109146706 :       if (FUNC_OR_METHOD_TYPE_P (type))
    2533      3319968 :         type = cxx_copy_lang_qualifiers (type, type_orig);
    2534              : 
    2535              :       /* According to the C++ ABI, some library classes are passed the
    2536              :          same as the scalar type of their single member and use the same
    2537              :          mangling.  */
    2538   1109146706 :       if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
    2539        16206 :         type = TREE_TYPE (first_field (type));
    2540              : 
    2541   1109146706 :       if (TYPE_PTRDATAMEM_P (type))
    2542        17088 :         write_pointer_to_member_type (type);
    2543              :       else
    2544              :         {
    2545              :           /* Handle any target-specific fundamental types.  */
    2546   1109129618 :           const char *target_mangling
    2547   1109129618 :             = targetm.mangle_type (type_orig);
    2548              : 
    2549   1109129618 :           if (target_mangling)
    2550              :             {
    2551      9889186 :               write_string (target_mangling);
    2552              :               /* Add substitutions for types other than fundamental
    2553              :                  types.  */
    2554      9889186 :               if (!VOID_TYPE_P (type)
    2555              :                   && TREE_CODE (type) != INTEGER_TYPE
    2556              :                   && TREE_CODE (type) != REAL_TYPE
    2557              :                   && TREE_CODE (type) != BOOLEAN_TYPE)
    2558            0 :                 add_substitution (type);
    2559              :               return;
    2560              :             }
    2561              : 
    2562   1099240432 :           switch (TREE_CODE (type))
    2563              :             {
    2564    591513893 :             case VOID_TYPE:
    2565    591513893 :             case BOOLEAN_TYPE:
    2566    591513893 :             case INTEGER_TYPE:  /* Includes wchar_t.  */
    2567    591513893 :             case REAL_TYPE:
    2568    591513893 :             case FIXED_POINT_TYPE:
    2569    591513893 :               {
    2570              :                 /* If this is a typedef, TYPE may not be one of
    2571              :                    the standard builtin type nodes, but an alias of one.  Use
    2572              :                    TYPE_MAIN_VARIANT to get to the underlying builtin type.  */
    2573    591513893 :                 write_builtin_type (TYPE_MAIN_VARIANT (type));
    2574    591513893 :                 ++is_builtin_type;
    2575              :               }
    2576    591513893 :               break;
    2577              : 
    2578       692163 :             case COMPLEX_TYPE:
    2579       692163 :               write_char ('C');
    2580       692163 :               write_type (TREE_TYPE (type));
    2581       692163 :               break;
    2582              : 
    2583      3319968 :             case FUNCTION_TYPE:
    2584      3319968 :             case METHOD_TYPE:
    2585      3319968 :               write_function_type (type);
    2586      3319968 :               break;
    2587              : 
    2588    330208229 :             case UNION_TYPE:
    2589    330208229 :             case RECORD_TYPE:
    2590    330208229 :             case ENUMERAL_TYPE:
    2591              :               /* A pointer-to-member function is represented as a special
    2592              :                  RECORD_TYPE, so check for this first.  */
    2593    330208229 :               if (TYPE_PTRMEMFUNC_P (type))
    2594       269280 :                 write_pointer_to_member_type (type);
    2595              :               else
    2596    329938949 :                 write_class_enum_type (type);
    2597              :               break;
    2598              : 
    2599      2729981 :             case TYPENAME_TYPE:
    2600      2729981 :             case UNBOUND_CLASS_TEMPLATE:
    2601              :               /* We handle TYPENAME_TYPEs and UNBOUND_CLASS_TEMPLATEs like
    2602              :                  ordinary nested names.  */
    2603      2729981 :               write_nested_name (TYPE_STUB_DECL (type));
    2604      2729981 :               break;
    2605              : 
    2606    136360481 :             case POINTER_TYPE:
    2607    136360481 :             case REFERENCE_TYPE:
    2608    136360481 :               if (TYPE_PTR_P (type))
    2609     58759569 :                 write_char ('P');
    2610     77600912 :               else if (TYPE_REF_IS_RVALUE (type))
    2611     13018547 :                 write_char ('O');
    2612              :               else
    2613     64582365 :                 write_char ('R');
    2614    136360481 :               {
    2615    136360481 :                 tree target = TREE_TYPE (type);
    2616              :                 /* Attribute const/noreturn are not reflected in mangling.
    2617              :                    We strip them here rather than at a lower level because
    2618              :                    a typedef or template argument can have function type
    2619              :                    with function-cv-quals (that use the same representation),
    2620              :                    but you can't have a pointer/reference to such a type.  */
    2621    136360481 :                 if (TREE_CODE (target) == FUNCTION_TYPE)
    2622              :                   {
    2623     11409695 :                     if (abi_warn_or_compat_version_crosses (5)
    2624      2282293 :                         && TYPE_QUALS (target) != TYPE_UNQUALIFIED)
    2625            3 :                       G.need_abi_warning = 1;
    2626      2282287 :                     if (abi_version_at_least (5))
    2627      2281858 :                       target = build_qualified_type (target, TYPE_UNQUALIFIED);
    2628              :                   }
    2629    136360481 :                 write_type (target);
    2630              :               }
    2631    136360481 :               break;
    2632              : 
    2633     29410149 :             case TEMPLATE_TYPE_PARM:
    2634     29410149 :               if (is_auto (type))
    2635              :                 {
    2636       742285 :                   if (template_placeholder_p (type)
    2637       742285 :                       && abi_check (19))
    2638              :                     {
    2639              :                       /* ABI #109: placeholder is mangled as its template.  */
    2640           33 :                       type = CLASS_PLACEHOLDER_TEMPLATE (type);
    2641           33 :                       if (find_substitution (type))
    2642              :                         return;
    2643           33 :                       write_name (type);
    2644           33 :                       break;
    2645              :                     }
    2646       742252 :                   if (AUTO_IS_DECLTYPE (type))
    2647        22848 :                     write_identifier ("Dc");
    2648              :                   else
    2649       719404 :                     write_identifier ("Da");
    2650              :                   ++is_builtin_type;
    2651              :                   break;
    2652              :                 }
    2653              :               /* fall through.  */
    2654     28667864 :             case TEMPLATE_PARM_INDEX:
    2655     28667864 :               write_template_param (type);
    2656     28667864 :               break;
    2657              : 
    2658           93 :             case TEMPLATE_TEMPLATE_PARM:
    2659           93 :               write_template_template_param (type);
    2660           93 :               break;
    2661              : 
    2662          536 :             case BOUND_TEMPLATE_TEMPLATE_PARM:
    2663          536 :               write_template_template_param (type);
    2664          536 :               write_template_args
    2665          536 :                 (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
    2666          536 :               break;
    2667              : 
    2668        35201 :             case VECTOR_TYPE:
    2669        35201 :               if (abi_version_at_least (4))
    2670              :                 {
    2671        35186 :                   write_string ("Dv");
    2672              :                   /* Non-constant vector size would be encoded with
    2673              :                      _ expression, but we don't support that yet.  */
    2674        35186 :                   write_unsigned_number (TYPE_VECTOR_SUBPARTS (type)
    2675              :                                          .to_constant ());
    2676        35186 :                   write_char ('_');
    2677        35186 :                 }
    2678              :               else
    2679           15 :                 write_string ("U8__vector");
    2680       175960 :               if (abi_warn_or_compat_version_crosses (4))
    2681           15 :                 G.need_abi_warning = 1;
    2682        35201 :               write_type (TREE_TYPE (type));
    2683        35201 :               break;
    2684              : 
    2685      3485381 :             case TYPE_PACK_EXPANSION:
    2686      3485381 :               write_string ("Dp");
    2687      3485381 :               write_type (PACK_EXPANSION_PATTERN (type));
    2688      3485381 :               break;
    2689              : 
    2690       451698 :             case DECLTYPE_TYPE:
    2691              :               /* These shouldn't make it into mangling.  */
    2692       451698 :               gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type)
    2693              :                           && !DECLTYPE_FOR_LAMBDA_PROXY (type));
    2694              : 
    2695              :               /* In ABI <5, we stripped decltype of a plain decl.  */
    2696       451698 :               if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
    2697              :                 {
    2698          559 :                   tree expr = DECLTYPE_TYPE_EXPR (type);
    2699          559 :                   tree etype = NULL_TREE;
    2700          559 :                   switch (TREE_CODE (expr))
    2701              :                     {
    2702          119 :                     case VAR_DECL:
    2703          119 :                     case PARM_DECL:
    2704          119 :                     case RESULT_DECL:
    2705          119 :                     case FUNCTION_DECL:
    2706          119 :                     case CONST_DECL:
    2707          119 :                     case TEMPLATE_PARM_INDEX:
    2708          119 :                       etype = TREE_TYPE (expr);
    2709          119 :                       break;
    2710              : 
    2711              :                     default:
    2712              :                       break;
    2713              :                     }
    2714              : 
    2715          119 :                   if (etype && !type_uses_auto (etype))
    2716              :                     {
    2717          117 :                       if (!abi_check (5))
    2718              :                         {
    2719              :                           write_type (etype);
    2720              :                           return;
    2721              :                         }
    2722              :                     }
    2723              :                 }
    2724              : 
    2725       451689 :               write_char ('D');
    2726       451689 :               if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
    2727          550 :                 write_char ('t');
    2728              :               else
    2729       451139 :                 write_char ('T');
    2730       451689 :               ++cp_unevaluated_operand;
    2731       451689 :               write_expression (DECLTYPE_TYPE_EXPR (type));
    2732       451689 :               --cp_unevaluated_operand;
    2733       451689 :               write_char ('E');
    2734       451689 :               break;
    2735              : 
    2736       806342 :             case NULLPTR_TYPE:
    2737       806342 :               write_string ("Dn");
    2738       806342 :               if (abi_check (7))
    2739              :                 ++is_builtin_type;
    2740              :               break;
    2741              : 
    2742           48 :             case SPLICE_SCOPE:
    2743           48 :               write_splice (type);
    2744           48 :               break;
    2745              : 
    2746            3 :             case TYPEOF_TYPE:
    2747            3 :               sorry ("mangling %<typeof%>, use %<decltype%> instead");
    2748            3 :               break;
    2749              : 
    2750           21 :             case TRAIT_TYPE:
    2751           21 :               error ("use of built-in trait %qT in function signature; "
    2752              :                      "use library traits instead", type);
    2753           21 :               break;
    2754              : 
    2755           29 :             case PACK_INDEX_TYPE:
    2756              :               /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
    2757           29 :               write_string ("Dy");
    2758           29 :               if (TREE_CODE (PACK_INDEX_PACK (type)) == TREE_VEC)
    2759              :                 {
    2760            6 :                   write_char ('J');
    2761           40 :                   for (int i = 0; i < TREE_VEC_LENGTH (PACK_INDEX_PACK (type));
    2762              :                        ++i)
    2763           14 :                     write_template_arg (TREE_VEC_ELT (PACK_INDEX_PACK (type),
    2764              :                                                       i));
    2765            6 :                   write_char ('E');
    2766              :                 }
    2767              :               else
    2768              :                 /* Dy rather than DyDp.  */
    2769           23 :                 write_type (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (type)));
    2770           29 :               write_expression (PACK_INDEX_INDEX (type));
    2771           29 :               break;
    2772              : 
    2773       226216 :             case OPAQUE_TYPE:
    2774       226216 :               if (REFLECTION_TYPE_P (type))
    2775              :                 {
    2776       226216 :                   write_string ("Dm");
    2777       226216 :                   ++is_builtin_type;
    2778       226216 :                   break;
    2779              :                 }
    2780              :               /* fall through.  */
    2781              : 
    2782            0 :             default:
    2783            0 :               gcc_unreachable ();
    2784              :             }
    2785              :         }
    2786              :     }
    2787              : 
    2788              :   /* Types other than builtin types are substitution candidates.  */
    2789   1184442718 :   if (!is_builtin_type)
    2790    591967045 :     add_substitution (type);
    2791              : }
    2792              : 
    2793              : /* qsort callback for sorting a vector of attribute entries.  */
    2794              : 
    2795              : static int
    2796            0 : attr_strcmp (const void *p1, const void *p2)
    2797              : {
    2798            0 :   tree a1 = *(const tree*)p1;
    2799            0 :   tree a2 = *(const tree*)p2;
    2800              : 
    2801            0 :   const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1));
    2802            0 :   const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2));
    2803              : 
    2804            0 :   return strcmp (as1->name, as2->name);
    2805              : }
    2806              : 
    2807              : /* Return true if we should mangle a type attribute with name NAME.  */
    2808              : 
    2809              : static bool
    2810        12551 : mangle_type_attribute_p (tree name)
    2811              : {
    2812        12551 :   const attribute_spec *as = lookup_attribute_spec (name);
    2813        12551 :   if (!as || !as->affects_type_identity)
    2814              :     return false;
    2815              : 
    2816              :   /* Skip internal-only attributes, which are distinguished from others
    2817              :      by having a space.  At present, all internal-only attributes that
    2818              :      affect type identity are target-specific and are handled by
    2819              :      targetm.mangle_type instead.
    2820              : 
    2821              :      Another reason to do this is that a space isn't a valid identifier
    2822              :      character for most file formats.  */
    2823           57 :   if (strchr (IDENTIFIER_POINTER (name), ' '))
    2824              :     return false;
    2825              : 
    2826              :   /* The following attributes are mangled specially.  */
    2827           57 :   if (is_attribute_p ("transaction_safe", name))
    2828              :     return false;
    2829           33 :   if (is_attribute_p ("abi_tag", name))
    2830            0 :     return false;
    2831              : 
    2832              :   return true;
    2833              : }
    2834              : 
    2835              : /* Non-terminal <CV-qualifiers> for type nodes.  Returns the number of
    2836              :    CV-qualifiers written for TYPE.
    2837              : 
    2838              :      <CV-qualifiers> ::= [r] [V] [K]  */
    2839              : 
    2840              : static int
    2841   1195414221 : write_CV_qualifiers_for_type (const tree type)
    2842              : {
    2843   1195414221 :   int num_qualifiers = 0;
    2844              : 
    2845              :   /* The order is specified by:
    2846              : 
    2847              :        "In cases where multiple order-insensitive qualifiers are
    2848              :        present, they should be ordered 'K' (closest to the base type),
    2849              :        'V', 'r', and 'U' (farthest from the base type) ..."  */
    2850              : 
    2851              :   /* Mangle attributes that affect type identity as extended qualifiers.
    2852              : 
    2853              :      We don't do this with classes and enums because their attributes
    2854              :      are part of their definitions, not something added on.  */
    2855              : 
    2856   1195414221 :   if (!OVERLOAD_TYPE_P (type))
    2857              :     {
    2858    829462184 :       auto_vec<tree> vec;
    2859    829474735 :       for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
    2860        12551 :         if (mangle_type_attribute_p (get_attribute_name (a)))
    2861           33 :           vec.safe_push (a);
    2862   4146550697 :       if (abi_warn_or_compat_version_crosses (10) && !vec.is_empty ())
    2863            0 :         G.need_abi_warning = true;
    2864    829462184 :       if (abi_version_at_least (10))
    2865              :         {
    2866    829213527 :           vec.qsort (attr_strcmp);
    2867    829462250 :           while (!vec.is_empty())
    2868              :             {
    2869           33 :               tree a = vec.pop();
    2870           33 :               const attribute_spec *as
    2871           33 :                 = lookup_attribute_spec (get_attribute_name (a));
    2872              : 
    2873           33 :               write_char ('U');
    2874           33 :               write_unsigned_number (strlen (as->name));
    2875           33 :               write_string (as->name);
    2876           33 :               if (TREE_VALUE (a))
    2877              :                 {
    2878            3 :                   write_char ('I');
    2879            6 :                   for (tree args = TREE_VALUE (a); args;
    2880            3 :                        args = TREE_CHAIN (args))
    2881              :                     {
    2882            3 :                       tree arg = TREE_VALUE (args);
    2883            3 :                       write_template_arg (arg);
    2884              :                     }
    2885            3 :                   write_char ('E');
    2886              :                 }
    2887              : 
    2888           33 :               ++num_qualifiers;
    2889              :             }
    2890              :         }
    2891    829462184 :     }
    2892              : 
    2893              :   /* Note that we do not use cp_type_quals below; given "const
    2894              :      int[3]", the "const" is emitted with the "int", not with the
    2895              :      array.  */
    2896   1195414221 :   cp_cv_quals quals = TYPE_QUALS (type);
    2897              : 
    2898   1195414221 :   if (quals & TYPE_QUAL_RESTRICT)
    2899              :     {
    2900           43 :       write_char ('r');
    2901           43 :       ++num_qualifiers;
    2902              :     }
    2903   1195414221 :   if (quals & TYPE_QUAL_VOLATILE)
    2904              :     {
    2905       552232 :       write_char ('V');
    2906       552232 :       ++num_qualifiers;
    2907              :     }
    2908   1195414221 :   if (quals & TYPE_QUAL_CONST)
    2909              :     {
    2910     84345966 :       write_char ('K');
    2911     84345966 :       ++num_qualifiers;
    2912              :     }
    2913              : 
    2914   1195414221 :   return num_qualifiers;
    2915              : }
    2916              : 
    2917              : /* Non-terminal <builtin-type>.
    2918              : 
    2919              :      <builtin-type> ::= v   # void
    2920              :                     ::= b   # bool
    2921              :                     ::= w   # wchar_t
    2922              :                     ::= c   # char
    2923              :                     ::= a   # signed char
    2924              :                     ::= h   # unsigned char
    2925              :                     ::= s   # short
    2926              :                     ::= t   # unsigned short
    2927              :                     ::= i   # int
    2928              :                     ::= j   # unsigned int
    2929              :                     ::= l   # long
    2930              :                     ::= m   # unsigned long
    2931              :                     ::= x   # long long, __int64
    2932              :                     ::= y   # unsigned long long, __int64
    2933              :                     ::= n   # __int128
    2934              :                     ::= o   # unsigned __int128
    2935              :                     ::= f   # float
    2936              :                     ::= d   # double
    2937              :                     ::= e   # long double, __float80
    2938              :                     ::= g   # __float128          [not supported]
    2939              :                     ::= u <source-name>  # vendor extended type */
    2940              : 
    2941              : static void
    2942    591513893 : write_builtin_type (tree type)
    2943              : {
    2944    591513893 :   if (TYPE_CANONICAL (type))
    2945    591513893 :     type = TYPE_CANONICAL (type);
    2946              : 
    2947    591513893 :   switch (TREE_CODE (type))
    2948              :     {
    2949     79700848 :     case VOID_TYPE:
    2950     79700848 :       write_char ('v');
    2951     79700848 :       break;
    2952              : 
    2953     50748257 :     case BOOLEAN_TYPE:
    2954     50748257 :       write_char ('b');
    2955     50748257 :       break;
    2956              : 
    2957    442448344 :     case INTEGER_TYPE:
    2958              :       /* TYPE may still be wchar_t, char8_t, char16_t, or char32_t, since that
    2959              :          isn't in integer_type_nodes.  */
    2960    442448344 :       if (type == wchar_type_node)
    2961     44457753 :         write_char ('w');
    2962    397990591 :       else if (type == char8_type_node)
    2963     23440496 :         write_string ("Du");
    2964    374550095 :       else if (type == char16_type_node)
    2965     23187742 :         write_string ("Ds");
    2966    351362353 :       else if (type == char32_type_node)
    2967     25872384 :         write_string ("Di");
    2968              :       else
    2969              :         {
    2970    325489983 :           size_t itk;
    2971              :           /* Assume TYPE is one of the shared integer type nodes.  Find
    2972              :              it in the array of these nodes.  */
    2973    325489969 :         iagain:
    2974   2065693036 :           for (itk = 0; itk < itk_none; ++itk)
    2975   2064112683 :             if (integer_types[itk] != NULL_TREE
    2976   2054630565 :                 && integer_type_codes[itk] != '\0'
    2977   2051469859 :                 && type == integer_types[itk])
    2978              :               {
    2979              :                 /* Print the corresponding single-letter code.  */
    2980    323909630 :                 write_char (integer_type_codes[itk]);
    2981    323909630 :                 break;
    2982              :               }
    2983              : 
    2984    325489983 :           if (itk == itk_none)
    2985              :             {
    2986      1580353 :               tree t = c_common_type_for_mode (TYPE_MODE (type),
    2987      1580353 :                                                TYPE_UNSIGNED (type));
    2988      1580353 :               if (type != t)
    2989              :                 {
    2990           14 :                   type = t;
    2991           14 :                   goto iagain;
    2992              :                 }
    2993              : 
    2994      1580339 :               if (TYPE_PRECISION (type) == 128)
    2995      2213047 :                 write_char (TYPE_UNSIGNED (type) ? 'o' : 'n');
    2996              :               else
    2997              :                 {
    2998              :                   /* Allow for cases where TYPE is not one of the shared
    2999              :                      integer type nodes and write a "vendor extended builtin
    3000              :                      type" with a name the form intN or uintN, respectively.
    3001              :                      Situations like this can happen if you have an
    3002              :                      __attribute__((__mode__(__SI__))) type and use exotic
    3003              :                      switches like '-mint8' on AVR.  Of course, this is
    3004              :                      undefined by the C++ ABI (and '-mint8' is not even
    3005              :                      Standard C conforming), but when using such special
    3006              :                      options you're pretty much in nowhere land anyway.  */
    3007            0 :                   const char *prefix;
    3008            0 :                   char prec[11];        /* up to ten digits for an unsigned */
    3009              : 
    3010            0 :                   prefix = TYPE_UNSIGNED (type) ? "uint" : "int";
    3011            0 :                   sprintf (prec, "%u", (unsigned) TYPE_PRECISION (type));
    3012            0 :                   write_char ('u');     /* "vendor extended builtin type" */
    3013            0 :                   write_unsigned_number (strlen (prefix) + strlen (prec));
    3014            0 :                   write_string (prefix);
    3015            0 :                   write_string (prec);
    3016              :                 }
    3017              :             }
    3018              :         }
    3019              :       break;
    3020              : 
    3021     18616444 :     case REAL_TYPE:
    3022     18616444 :       if (type == float_type_node)
    3023      6046819 :         write_char ('f');
    3024     12569625 :       else if (type == double_type_node)
    3025     10076810 :         write_char ('d');
    3026      2492815 :       else if (type == long_double_type_node)
    3027            0 :         write_char ('e');
    3028      2492815 :       else if (type == dfloat32_type_node)
    3029         6152 :         write_string ("Df");
    3030      2486663 :       else if (type == dfloat64_type_node)
    3031         6041 :         write_string ("Dd");
    3032      2480622 :       else if (type == dfloat128_type_node)
    3033         6008 :         write_string ("De");
    3034      2474614 :       else if (type == float16_type_node)
    3035            0 :         write_string ("DF16_");
    3036      2474614 :       else if (type == float32_type_node)
    3037       817704 :         write_string ("DF32_");
    3038      1656910 :       else if (type == float64_type_node)
    3039       819448 :         write_string ("DF64_");
    3040       837462 :       else if (type == float128_type_node)
    3041       777724 :         write_string ("DF128_");
    3042        59738 :       else if (type == float32x_type_node)
    3043        29869 :         write_string ("DF32x");
    3044        29869 :       else if (type == float64x_type_node)
    3045        29869 :         write_string ("DF64x");
    3046            0 :       else if (type == float128x_type_node)
    3047            0 :         write_string ("DF128x");
    3048            0 :       else if (type == bfloat16_type_node)
    3049            0 :         write_string ("DF16b");
    3050              :       else
    3051            0 :         gcc_unreachable ();
    3052              :       break;
    3053              : 
    3054            0 :     default:
    3055            0 :       gcc_unreachable ();
    3056              :     }
    3057    591513893 : }
    3058              : 
    3059              : /* Non-terminal <function-type>.  NODE is a FUNCTION_TYPE or
    3060              :    METHOD_TYPE.  The return type is mangled before the parameter
    3061              :    types.
    3062              : 
    3063              :      <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E   */
    3064              : 
    3065              : static void
    3066      3326669 : write_function_type (const tree type)
    3067              : {
    3068      3326669 :   MANGLE_TRACE_TREE ("function-type", type);
    3069              : 
    3070              :   /* For a pointer to member function, the function type may have
    3071              :      cv-qualifiers, indicating the quals for the artificial 'this'
    3072              :      parameter.  */
    3073      3326669 :   if (TREE_CODE (type) == METHOD_TYPE)
    3074              :     {
    3075              :       /* The first parameter must be a POINTER_TYPE pointing to the
    3076              :          `this' parameter.  */
    3077       269280 :       tree this_type = class_of_this_parm (type);
    3078       269280 :       write_CV_qualifiers_for_type (this_type);
    3079              :     }
    3080              : 
    3081      3326669 :   write_exception_spec (TYPE_RAISES_EXCEPTIONS (type));
    3082              : 
    3083      3326669 :   if (tx_safe_fn_type_p (type))
    3084           24 :     write_string ("Dx");
    3085              : 
    3086      3326669 :   write_char ('F');
    3087              :   /* We don't track whether or not a type is `extern "C"'.  Note that
    3088              :      you can have an `extern "C"' function that does not have
    3089              :      `extern "C"' type, and vice versa:
    3090              : 
    3091              :        extern "C" typedef void function_t();
    3092              :        function_t f; // f has C++ linkage, but its type is
    3093              :                      // `extern "C"'
    3094              : 
    3095              :        typedef void function_t();
    3096              :        extern "C" function_t f; // Vice versa.
    3097              : 
    3098              :      See [dcl.link].  */
    3099      3326669 :   write_bare_function_type (type, /*include_return_type_p=*/1,
    3100              :                             /*decl=*/NULL);
    3101      3326669 :   if (FUNCTION_REF_QUALIFIED (type))
    3102              :     {
    3103         2156 :       if (FUNCTION_RVALUE_QUALIFIED (type))
    3104          865 :         write_char ('O');
    3105              :       else
    3106         1291 :         write_char ('R');
    3107              :     }
    3108      3326669 :   write_char ('E');
    3109      3326669 : }
    3110              : 
    3111              : /* Non-terminal <bare-function-type>.  TYPE is a FUNCTION_TYPE or
    3112              :    METHOD_TYPE.  If INCLUDE_RETURN_TYPE is nonzero, the return value
    3113              :    is mangled before the parameter types.  If non-NULL, DECL is
    3114              :    FUNCTION_DECL for the function whose type is being emitted.  */
    3115              : 
    3116              : static void
    3117    197813204 : write_bare_function_type (const tree type, const int include_return_type_p,
    3118              :                           const tree decl)
    3119              : {
    3120    197813204 :   MANGLE_TRACE_TREE ("bare-function-type", type);
    3121              : 
    3122              :   /* Mangle the return type, if requested.  */
    3123    197813204 :   if (include_return_type_p)
    3124     17786568 :     write_type (TREE_TYPE (type));
    3125              : 
    3126              :   /* Now mangle the types of the arguments.  */
    3127    197813204 :   ++G.parm_depth;
    3128    197813204 :   write_method_parms (TYPE_ARG_TYPES (type),
    3129    197813204 :                       TREE_CODE (type) == METHOD_TYPE,
    3130              :                       decl);
    3131    197813204 :   --G.parm_depth;
    3132    197813204 : }
    3133              : 
    3134              : /* Write the mangled representation of a method parameter list of
    3135              :    types given in PARM_TYPES.  If METHOD_P is nonzero, the function is
    3136              :    considered a non-static method, and the this parameter is omitted.
    3137              :    If non-NULL, DECL is the FUNCTION_DECL for the function whose
    3138              :    parameters are being emitted.  */
    3139              : 
    3140              : static void
    3141    200186348 : write_method_parms (tree parm_types, const int method_p, const tree decl)
    3142              : {
    3143    200186348 :   tree first_parm_type;
    3144    379589401 :   tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;
    3145              : 
    3146              :   /* Assume this parameter type list is variable-length.  If it ends
    3147              :      with a void type, then it's not.  */
    3148    200186348 :   int varargs_p = 1;
    3149              : 
    3150              :   /* If this is a member function, skip the first arg, which is the
    3151              :      this pointer.
    3152              :        "Member functions do not encode the type of their implicit this
    3153              :        parameter."
    3154              : 
    3155              :      Similarly, there's no need to mangle artificial parameters, like
    3156              :      the VTT parameters for constructors and destructors.  */
    3157    200186348 :   if (method_p)
    3158              :     {
    3159    156142951 :       parm_types = TREE_CHAIN (parm_types);
    3160    156142951 :       parm_decl = parm_decl ? DECL_CHAIN (parm_decl) : NULL_TREE;
    3161              : 
    3162    156186059 :       while (parm_decl && DECL_ARTIFICIAL (parm_decl))
    3163              :         {
    3164        43108 :           parm_types = TREE_CHAIN (parm_types);
    3165        43108 :           parm_decl = DECL_CHAIN (parm_decl);
    3166              :         }
    3167              : 
    3168    156142951 :       if (decl && ctor_omit_inherited_parms (decl))
    3169              :         /* Bring back parameters omitted from an inherited ctor.  */
    3170           54 :         parm_types = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (decl));
    3171              :     }
    3172              : 
    3173    200186348 :   for (first_parm_type = parm_types;
    3174    626410042 :        parm_types;
    3175    426223694 :        parm_types = TREE_CHAIN (parm_types))
    3176              :     {
    3177    426223694 :       tree parm = TREE_VALUE (parm_types);
    3178    426223694 :       if (parm == void_type_node)
    3179              :         {
    3180              :           /* "Empty parameter lists, whether declared as () or
    3181              :              conventionally as (void), are encoded with a void parameter
    3182              :              (v)."  */
    3183    200140931 :           if (parm_types == first_parm_type)
    3184     66939585 :             write_type (parm);
    3185              :           /* If the parm list is terminated with a void type, it's
    3186              :              fixed-length.  */
    3187    200140931 :           varargs_p = 0;
    3188              :           /* A void type better be the last one.  */
    3189    200140931 :           gcc_assert (TREE_CHAIN (parm_types) == NULL);
    3190              :         }
    3191              :       else
    3192    226082763 :         write_type (parm);
    3193              :     }
    3194              : 
    3195    200186348 :   if (varargs_p)
    3196              :     /* <builtin-type> ::= z  # ellipsis  */
    3197        45417 :     write_char ('z');
    3198    200186348 : }
    3199              : 
    3200              : /* <class-enum-type> ::= <name>  */
    3201              : 
    3202              : static void
    3203    329938949 : write_class_enum_type (const tree type)
    3204              : {
    3205    329938949 :   write_name (TYPE_NAME (type));
    3206    329938949 : }
    3207              : 
    3208              : /* Mangle a requirement REQ in a requires-expression.  */
    3209              : 
    3210              : static void
    3211       563654 : write_requirement (tree req)
    3212              : {
    3213       563654 :   tree op = TREE_OPERAND (req, 0);
    3214              : 
    3215       563654 :   switch (tree_code code = TREE_CODE (req))
    3216              :     {
    3217              :       /* # simple-requirement or compound-requirement
    3218              :          <requirement> ::= X <expression> [ N ] [ R <type-constraint> ]
    3219              :                            X <expression> C <expression>
    3220              :                              [ R <type-constraint> ]  */
    3221       563221 :     case SIMPLE_REQ:
    3222       563221 :     case COMPOUND_REQ:
    3223       563221 :       write_char ('X');
    3224       563221 :       write_expression (op);
    3225       563221 :       if (code == SIMPLE_REQ)
    3226              :         break;
    3227       108830 :       if (operand_equal_p (TREE_OPERAND (req, 2), boolean_true_node))
    3228           15 :         write_char ('N');
    3229       108815 :       else if (TREE_OPERAND (req, 2) != error_mark_node
    3230       108815 :                && !operand_equal_p (TREE_OPERAND (req, 2), boolean_false_node))
    3231              :         {
    3232            6 :           write_char ('C');
    3233            6 :           write_expression (TREE_OPERAND (req, 2));
    3234              :         }
    3235       108830 :       if (tree constr = TREE_OPERAND (req, 1))
    3236              :         {
    3237       108815 :           write_char ('R');
    3238       108815 :           write_type_constraint (PLACEHOLDER_TYPE_CONSTRAINTS (constr));
    3239              :         }
    3240              :       break;
    3241              : 
    3242              :       /* <requirement> ::= T <type> # type-requirement */
    3243          427 :     case TYPE_REQ:
    3244          427 :       write_char ('T');
    3245          427 :       write_type (op);
    3246          427 :       break;
    3247              : 
    3248              :       /* <requirement> ::= Q <constraint-expression> # nested-requirement */
    3249            6 :     case NESTED_REQ:
    3250            6 :       write_char ('Q');
    3251            6 :       write_constraint_expression (op);
    3252            6 :       break;
    3253              : 
    3254            0 :     default:
    3255            0 :       gcc_unreachable ();
    3256              :     }
    3257       563654 : }
    3258              : 
    3259              : /* # requires { ... }
    3260              :    <expression> ::= rq <requirement>+ E
    3261              :    # requires (...) { ... }
    3262              :    <expression> ::= rQ <bare-function-type> _ <requirement>+ E */
    3263              : 
    3264              : static void
    3265       535654 : write_requires_expr (tree expr)
    3266              : {
    3267       535654 :   tree parms = REQUIRES_EXPR_PARMS (expr);
    3268       535654 :   if (parms)
    3269              :     {
    3270        91872 :       write_string ("rQ");
    3271        91872 :       ++G.parm_depth;
    3272       184193 :       for (; parms; parms = DECL_CHAIN (parms))
    3273        92321 :         write_type (cv_unqualified (TREE_TYPE (parms)));
    3274        91872 :       --G.parm_depth;
    3275        91872 :       write_char ('_');
    3276              :     }
    3277              :   else
    3278       443782 :     write_string ("rq");
    3279              : 
    3280      1099308 :   for (tree reqs = REQUIRES_EXPR_REQS (expr); reqs;
    3281       563654 :        reqs = TREE_CHAIN (reqs))
    3282       563654 :     write_requirement (TREE_VALUE (reqs));
    3283              : 
    3284       535654 :   write_char ('E');
    3285       535654 : }
    3286              : 
    3287              : /* Non-terminal <template-args>.  ARGS is a TREE_VEC of template
    3288              :    arguments.
    3289              : 
    3290              :      <template-args> ::= I <template-arg>* [Q <constraint-expr>] E  */
    3291              : 
    3292              : static void
    3293    425655441 : write_template_args (tree args, tree parms /*= NULL_TREE*/)
    3294              : {
    3295    425655441 :   int i;
    3296    425655441 :   int length = 0;
    3297              : 
    3298    425655441 :   MANGLE_TRACE_TREE ("template-args", args);
    3299              : 
    3300    425655441 :   write_char ('I');
    3301              : 
    3302    425655441 :   if (args)
    3303    425655441 :     length = TREE_VEC_LENGTH (args);
    3304              : 
    3305    425655441 :   tree constraints = NULL_TREE;
    3306    425655441 :   if (parms)
    3307              :     {
    3308      4989872 :       constraints = TEMPLATE_PARMS_CONSTRAINTS (parms);
    3309      4989872 :       parms = INNERMOST_TEMPLATE_PARMS (parms);
    3310              :     }
    3311              : 
    3312    425655441 :   if (args && length && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
    3313              :     {
    3314              :       /* We have nested template args.  We want the innermost template
    3315              :          argument list.  */
    3316      6258495 :       args = TREE_VEC_ELT (args, length - 1);
    3317      6258495 :       length = TREE_VEC_LENGTH (args);
    3318              :     }
    3319    425655441 :   if (TEMPLATE_ARGS_TYPE_CONSTRAINT_P (args))
    3320              :     /* Skip the constrained type.  */
    3321              :     i = 1;
    3322              :   else
    3323    425602401 :     i = 0;
    3324    425655441 :   bool implicit_parm_scope = false;
    3325   1183253360 :   for (; i < length; ++i)
    3326              :     {
    3327    757597919 :       tree arg = TREE_VEC_ELT (args, i);
    3328    757597919 :       if (parms)
    3329              :         {
    3330      8634140 :           tree parm = TREE_VEC_ELT (parms, i);
    3331      8634140 :           tree decl = TREE_VALUE (parm);
    3332      8634140 :           if (DECL_IMPLICIT_TEMPLATE_PARM_P (decl)
    3333      8634140 :               && !implicit_parm_scope)
    3334              :             {
    3335              :               /* The rest of the template parameters are based on generic
    3336              :                  function parameters, so any expressions in their
    3337              :                  type-constraints are in parameter scope.  */
    3338         9653 :               implicit_parm_scope = true;
    3339         9653 :               ++G.parm_depth;
    3340              :             }
    3341      8634140 :           if (!template_parm_natural_p (arg, parm)
    3342      8634140 :               && abi_check (19))
    3343        41449 :             write_template_param_decl (parm);
    3344              :         }
    3345    757597919 :       write_template_arg (arg);
    3346              :     }
    3347    425655441 :   if (implicit_parm_scope)
    3348         9653 :     --G.parm_depth;
    3349              : 
    3350    425655441 :   write_tparms_constraints (constraints);
    3351              : 
    3352    425655441 :   write_char ('E');
    3353    425655441 : }
    3354              : 
    3355              : /* Write out the
    3356              :    <unqualified-name>
    3357              :    <unqualified-name> <template-args>
    3358              :    part of SCOPE_REF or COMPONENT_REF mangling.  */
    3359              : 
    3360              : static void
    3361       514486 : write_member_name (tree member)
    3362              : {
    3363       514486 :   if (identifier_p (member))
    3364              :     {
    3365       375121 :       if (IDENTIFIER_ANY_OP_P (member))
    3366              :         {
    3367        54199 :           if (abi_check (11))
    3368        54175 :             write_string ("on");
    3369              :         }
    3370       375121 :       write_unqualified_id (member);
    3371              :     }
    3372       139365 :   else if (DECL_P (member))
    3373              :     {
    3374         1296 :       if (ANON_AGGR_TYPE_P (TREE_TYPE (member)))
    3375              :         ;
    3376         1290 :       else if (DECL_OVERLOADED_OPERATOR_P (member))
    3377              :         {
    3378           15 :           if (abi_check (16))
    3379            9 :             write_string ("on");
    3380              :         }
    3381         1296 :       write_unqualified_name (member);
    3382              :     }
    3383       138069 :   else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
    3384              :     {
    3385          271 :       tree name = TREE_OPERAND (member, 0);
    3386          271 :       name = OVL_FIRST (name);
    3387          271 :       write_member_name (name);
    3388          271 :       write_template_args (TREE_OPERAND (member, 1));
    3389              :     }
    3390              :   else
    3391       137798 :     write_expression (member);
    3392       514486 : }
    3393              : 
    3394              : /* EXPR is a base COMPONENT_REF; write the minimized base conversion path for
    3395              :    converting to BASE, or just the conversion of EXPR if BASE is null.
    3396              : 
    3397              :    "Given a fully explicit base path P := C_n -> ... -> C_0, the minimized base
    3398              :    path Min(P) is defined as follows: let C_i be the last element for which the
    3399              :    conversion to C_0 is unambiguous; if that element is C_n, the minimized path
    3400              :    is C_n -> C_0; otherwise, the minimized path is Min(C_n -> ... -> C_i) ->
    3401              :    C_0."
    3402              : 
    3403              :    We mangle the conversion to C_i if it's different from C_n.  */
    3404              : 
    3405              : static bool
    3406       200642 : write_base_ref (tree expr, tree base = NULL_TREE)
    3407              : {
    3408       200642 :   if (TREE_CODE (expr) != COMPONENT_REF)
    3409              :     return false;
    3410              : 
    3411       200636 :   tree field = TREE_OPERAND (expr, 1);
    3412              : 
    3413       200636 :   if (TREE_CODE (field) != FIELD_DECL || !DECL_FIELD_IS_BASE (field))
    3414              :     return false;
    3415              : 
    3416           18 :   tree object = TREE_OPERAND (expr, 0);
    3417              : 
    3418           18 :   tree binfo = NULL_TREE;
    3419           18 :   if (base)
    3420              :     {
    3421            9 :       tree cur = TREE_TYPE (object);
    3422            9 :       binfo = lookup_base (cur, base, ba_unique, NULL, tf_none);
    3423              :     }
    3424              :   else
    3425              :     /* We're at the end of the base conversion chain, so it can't be
    3426              :        ambiguous.  */
    3427            9 :     base = TREE_TYPE (field);
    3428              : 
    3429           18 :   if (binfo == error_mark_node)
    3430              :     {
    3431              :       /* cur->base is ambiguous, so make the conversion to
    3432              :          last explicit, expressed as a cast (last&)object.  */
    3433            3 :       tree last = TREE_TYPE (expr);
    3434            3 :       write_string (OVL_OP_INFO (false, CAST_EXPR)->mangled_name);
    3435            3 :       write_type (build_reference_type (last));
    3436            3 :       write_expression (object);
    3437              :     }
    3438           15 :   else if (write_base_ref (object, base))
    3439              :     /* cur->base is unambiguous, but we had another base conversion
    3440              :        underneath and wrote it out.  */;
    3441              :   else
    3442              :     /* No more base conversions, just write out the object.  */
    3443            6 :     write_expression (object);
    3444              : 
    3445              :   return true;
    3446              : }
    3447              : 
    3448              : /* The number of elements spanned by a RANGE_EXPR.  */
    3449              : 
    3450              : unsigned HOST_WIDE_INT
    3451           24 : range_expr_nelts (tree expr)
    3452              : {
    3453           24 :   tree lo = TREE_OPERAND (expr, 0);
    3454           24 :   tree hi = TREE_OPERAND (expr, 1);
    3455           24 :   return tree_to_uhwi (hi) - tree_to_uhwi (lo) + 1;
    3456              : }
    3457              : 
    3458              : /* <expression> ::= <unary operator-name> <expression>
    3459              :                 ::= <binary operator-name> <expression> <expression>
    3460              :                 ::= <expr-primary>
    3461              : 
    3462              :    <expr-primary> ::= <template-param>
    3463              :                   ::= L <type> <value number> E             # literal
    3464              :                   ::= L <mangled-name> E          # external name
    3465              :                   ::= st <type>                           # sizeof
    3466              :                   ::= sr <type> <unqualified-name>  # dependent name
    3467              :                   ::= sr <type> <unqualified-name> <template-args>
    3468              :                   ::= L Dm <value reflection> E           # C++26 reflection
    3469              :                                                         # value [proposed]
    3470              :                   ::= <splice>            # C++26 dependent splice [proposed]  */
    3471              : 
    3472              : static void
    3473     12678297 : write_expression (tree expr)
    3474              : {
    3475     13116327 :   enum tree_code code = TREE_CODE (expr);
    3476              : 
    3477     13116327 :   if (TREE_CODE (expr) == TARGET_EXPR)
    3478              :     {
    3479            0 :       expr = TARGET_EXPR_INITIAL (expr);
    3480            0 :       code = TREE_CODE (expr);
    3481              :     }
    3482              : 
    3483              :   /* Skip NOP_EXPR and CONVERT_EXPR.  They can occur when (say) a pointer
    3484              :      argument is converted (via qualification conversions) to another type.  */
    3485     13687030 :   while (CONVERT_EXPR_CODE_P (code)
    3486     13563789 :          || code == IMPLICIT_CONV_EXPR
    3487     13563657 :          || location_wrapper_p (expr)
    3488              :          /* Parentheses aren't mangled.  */
    3489     13116693 :          || code == PAREN_EXPR
    3490     13116693 :          || code == NON_LVALUE_EXPR
    3491     26803723 :          || (code == VIEW_CONVERT_EXPR
    3492          366 :              && TREE_CODE (TREE_OPERAND (expr, 0)) == TEMPLATE_PARM_INDEX))
    3493              :     {
    3494       570703 :       expr = TREE_OPERAND (expr, 0);
    3495       570703 :       code = TREE_CODE (expr);
    3496              :     }
    3497              : 
    3498     13116327 :   if (code == BASELINK
    3499     13116327 :       && (!type_unknown_p (expr)
    3500       773335 :           || !BASELINK_QUALIFIED_P (expr)))
    3501              :     {
    3502       790680 :       expr = BASELINK_FUNCTIONS (expr);
    3503       790680 :       code = TREE_CODE (expr);
    3504              :     }
    3505              : 
    3506              :   /* Handle pointers-to-members by making them look like expression
    3507              :      nodes.  */
    3508     13116327 :   if (code == PTRMEM_CST)
    3509              :     {
    3510         7790 :       expr = build_nt (ADDR_EXPR,
    3511              :                        build_qualified_name (/*type=*/NULL_TREE,
    3512         3895 :                                              PTRMEM_CST_CLASS (expr),
    3513         3895 :                                              PTRMEM_CST_MEMBER (expr),
    3514              :                                              /*template_p=*/false));
    3515         3895 :       code = TREE_CODE (expr);
    3516              :     }
    3517              : 
    3518              :   /* Handle template parameters.  */
    3519     13116327 :   if (code == TEMPLATE_TYPE_PARM
    3520     13116327 :       || code == TEMPLATE_TEMPLATE_PARM
    3521     13116327 :       || code == BOUND_TEMPLATE_TEMPLATE_PARM
    3522     13112313 :       || code == TEMPLATE_PARM_INDEX)
    3523       789355 :     write_template_param (expr);
    3524              :   /* Handle literals.  */
    3525     12326972 :   else if (TREE_CODE_CLASS (code) == tcc_constant
    3526     11942489 :            || code == CONST_DECL
    3527     11942489 :            || code == REFLECT_EXPR)
    3528       409143 :     write_template_arg_literal (expr);
    3529     11917829 :   else if (code == EXCESS_PRECISION_EXPR
    3530     11917829 :            && TREE_CODE (TREE_OPERAND (expr, 0)) == REAL_CST)
    3531            0 :     write_template_arg_literal (fold_convert (TREE_TYPE (expr),
    3532              :                                               TREE_OPERAND (expr, 0)));
    3533     11917829 :   else if (code == PARM_DECL && DECL_ARTIFICIAL (expr))
    3534              :     {
    3535       121875 :       gcc_assert (id_equal (DECL_NAME (expr), "this"));
    3536       121875 :       write_string ("fpT");
    3537              :     }
    3538     11795954 :   else if (code == PARM_DECL)
    3539              :     {
    3540              :       /* A function parameter used in a late-specified return type.  */
    3541       362535 :       int index = DECL_PARM_INDEX (expr);
    3542       362535 :       int level = DECL_PARM_LEVEL (expr);
    3543       362535 :       int delta = G.parm_depth - level + 1;
    3544       362535 :       gcc_assert (index >= 1);
    3545       362535 :       write_char ('f');
    3546       362535 :       if (delta != 0)
    3547              :         {
    3548       173710 :           gcc_checking_assert (delta > 0);
    3549       173710 :           if (abi_check (5))
    3550              :             {
    3551              :               /* Let L be the number of function prototype scopes from the
    3552              :                  innermost one (in which the parameter reference occurs) up
    3553              :                  to (and including) the one containing the declaration of
    3554              :                  the referenced parameter.  If the parameter declaration
    3555              :                  clause of the innermost function prototype scope has been
    3556              :                  completely seen, it is not counted (in that case -- which
    3557              :                  is perhaps the most common -- L can be zero).  */
    3558       173707 :               write_char ('L');
    3559       173707 :               write_unsigned_number (delta - 1);
    3560              :             }
    3561              :         }
    3562       362535 :       write_char ('p');
    3563       362535 :       write_compact_number (index - 1);
    3564              :     }
    3565     11433419 :   else if (DECL_P (expr))
    3566              :     {
    3567       379642 :       write_char ('L');
    3568       379642 :       write_mangled_name (expr, false);
    3569       379642 :       write_char ('E');
    3570              :     }
    3571     11053777 :   else if (TREE_CODE (expr) == SIZEOF_EXPR)
    3572              :     {
    3573         6973 :       tree op = TREE_OPERAND (expr, 0);
    3574              : 
    3575         6973 :       if (PACK_EXPANSION_P (op))
    3576              :         {
    3577         5462 :     sizeof_pack:
    3578         5465 :           if (abi_check (11))
    3579              :             {
    3580              :               /* sZ rather than szDp.  */
    3581         5456 :               write_string ("sZ");
    3582         5456 :               write_expression (PACK_EXPANSION_PATTERN (op));
    3583              :               return;
    3584              :             }
    3585              :         }
    3586              : 
    3587         1520 :       if (SIZEOF_EXPR_TYPE_P (expr))
    3588              :         {
    3589            0 :           write_string ("st");
    3590            0 :           write_type (TREE_TYPE (op));
    3591              :         }
    3592         1520 :       else if (ARGUMENT_PACK_P (op))
    3593              :         {
    3594           15 :           tree args = ARGUMENT_PACK_ARGS (op);
    3595           15 :           int length = TREE_VEC_LENGTH (args);
    3596           15 :           if (abi_check (10))
    3597              :             {
    3598              :               /* Before v19 we wrongly mangled all single pack expansions with
    3599              :                  sZ, but now only for expressions, as types ICEd (95298).  */
    3600           12 :               if (length == 1)
    3601              :                 {
    3602            9 :                   tree arg = TREE_VEC_ELT (args, 0);
    3603            9 :                   if (TREE_CODE (arg) == EXPR_PACK_EXPANSION
    3604            9 :                       && !abi_check (19))
    3605              :                     {
    3606            3 :                       op = arg;
    3607            3 :                       goto sizeof_pack;
    3608              :                     }
    3609              :                 }
    3610              : 
    3611              :               /* sP <template-arg>* E # sizeof...(T), size of a captured
    3612              :                  template parameter pack from an alias template */
    3613            9 :               write_string ("sP");
    3614           24 :               for (int i = 0; i < length; ++i)
    3615           15 :                 write_template_arg (TREE_VEC_ELT (args, i));
    3616            9 :               write_char ('E');
    3617              :             }
    3618              :           else
    3619              :             {
    3620              :               /* In GCC 5 we represented this sizeof wrong, with the effect
    3621              :                  that we mangled it as the last element of the pack.  */
    3622            3 :               tree arg = TREE_VEC_ELT (args, length-1);
    3623            3 :               if (TYPE_P (op))
    3624              :                 {
    3625            3 :                   write_string ("st");
    3626            3 :                   write_type (arg);
    3627              :                 }
    3628              :               else
    3629              :                 {
    3630            0 :                   write_string ("sz");
    3631            0 :                   write_expression (arg);
    3632              :                 }
    3633              :             }
    3634              :         }
    3635         1505 :       else if (TYPE_P (TREE_OPERAND (expr, 0)))
    3636              :         {
    3637         1381 :           write_string ("st");
    3638         1381 :           write_type (TREE_OPERAND (expr, 0));
    3639              :         }
    3640              :       else
    3641          124 :         goto normal_expr;
    3642              :     }
    3643     11046804 :   else if (code == PACK_INDEX_EXPR)
    3644              :     {
    3645              :       /* https://github.com/itanium-cxx-abi/cxx-abi/issues/175.  */
    3646           37 :       write_string ("sy");
    3647           37 :       if (TREE_CODE (PACK_INDEX_PACK (expr)) == TREE_VEC)
    3648              :         {
    3649            2 :           write_char ('J');
    3650           20 :           for (int i = 0; i < TREE_VEC_LENGTH (PACK_INDEX_PACK (expr));
    3651              :                ++i)
    3652            8 :             write_template_arg (TREE_VEC_ELT (PACK_INDEX_PACK (expr), i));
    3653            2 :           write_char ('E');
    3654              :         }
    3655              :       else
    3656              :         /* sy rather than sysp.  */
    3657           35 :         write_expression (PACK_EXPANSION_PATTERN (PACK_INDEX_PACK (expr)));
    3658           37 :       write_expression (PACK_INDEX_INDEX (expr));
    3659              :     }
    3660     11046767 :   else if (TREE_CODE (expr) == ALIGNOF_EXPR)
    3661              :     {
    3662           36 :       if (!ALIGNOF_EXPR_STD_P (expr))
    3663              :         {
    3664           24 :           if (abi_check (16))
    3665              :             {
    3666              :               /* We used to mangle __alignof__ like alignof.  */
    3667           18 :               write_string ("u11__alignof__");
    3668           18 :               write_template_arg (TREE_OPERAND (expr, 0));
    3669           18 :               write_char ('E');
    3670           18 :               return;
    3671              :             }
    3672              :         }
    3673           18 :       if (TYPE_P (TREE_OPERAND (expr, 0)))
    3674              :         {
    3675            9 :           write_string ("at");
    3676            9 :           write_type (TREE_OPERAND (expr, 0));
    3677              :         }
    3678              :       else
    3679            9 :         goto normal_expr;
    3680              :     }
    3681     11046731 :   else if (code == SCOPE_REF
    3682     11046731 :            || code == BASELINK)
    3683              :     {
    3684       317508 :       tree scope, member;
    3685       317508 :       if (code == SCOPE_REF)
    3686              :         {
    3687       317475 :           scope = TREE_OPERAND (expr, 0);
    3688       317475 :           member = TREE_OPERAND (expr, 1);
    3689       317475 :           if (BASELINK_P (member))
    3690           21 :             member = BASELINK_FUNCTIONS (member);
    3691              :         }
    3692              :       else
    3693              :         {
    3694           33 :           scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (expr));
    3695           33 :           member = BASELINK_FUNCTIONS (expr);
    3696              :         }
    3697              : 
    3698              :       /* If the MEMBER is a real declaration, then the qualifying
    3699              :          scope was not dependent.  Ideally, we would not have a
    3700              :          SCOPE_REF in those cases, but sometimes we do.  If the second
    3701              :          argument is a DECL, then the name must not have been
    3702              :          dependent.  */
    3703       317508 :       if (DECL_P (member))
    3704              :         write_expression (member);
    3705              :       else
    3706              :         {
    3707       313310 :           gcc_assert (code != BASELINK || BASELINK_QUALIFIED_P (expr));
    3708       313277 :           write_string ("sr");
    3709       313277 :           write_type (scope);
    3710       313277 :           write_member_name (member);
    3711              :         }
    3712              :     }
    3713     10729223 :   else if (INDIRECT_REF_P (expr)
    3714       472080 :            && TREE_TYPE (TREE_OPERAND (expr, 0))
    3715     11117861 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
    3716              :     {
    3717       265651 :       write_expression (TREE_OPERAND (expr, 0));
    3718              :     }
    3719     10463572 :   else if (identifier_p (expr))
    3720              :     {
    3721              :       /* An operator name appearing as a dependent name needs to be
    3722              :          specially marked to disambiguate between a use of the operator
    3723              :          name and a use of the operator in an expression.  */
    3724       255065 :       if (IDENTIFIER_ANY_OP_P (expr))
    3725            7 :         write_string ("on");
    3726       255065 :       write_unqualified_id (expr);
    3727              :     }
    3728     10208507 :   else if (dependent_splice_p (expr))
    3729           50 :     write_splice (expr);
    3730     10208457 :   else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
    3731              :     {
    3732      4294648 :       tree fn = TREE_OPERAND (expr, 0);
    3733      5676430 :       if (!identifier_p (fn))
    3734      4294645 :         fn = OVL_NAME (fn);
    3735      4294648 :       if (IDENTIFIER_ANY_OP_P (fn))
    3736            3 :         write_string ("on");
    3737      4294648 :       write_unqualified_id (fn);
    3738      4294648 :       write_template_args (TREE_OPERAND (expr, 1));
    3739              :     }
    3740      5913809 :   else if (TREE_CODE (expr) == MODOP_EXPR)
    3741              :     {
    3742           87 :       enum tree_code subop = TREE_CODE (TREE_OPERAND (expr, 1));
    3743           87 :       const char *name = OVL_OP_INFO (true, subop)->mangled_name;
    3744              : 
    3745           87 :       write_string (name);
    3746           87 :       write_expression (TREE_OPERAND (expr, 0));
    3747           87 :       write_expression (TREE_OPERAND (expr, 2));
    3748              :     }
    3749      5913722 :   else if (code == NEW_EXPR || code == VEC_NEW_EXPR)
    3750              :     {
    3751              :       /* ::= [gs] nw <expression>* _ <type> E
    3752              :          ::= [gs] nw <expression>* _ <type> <initializer>
    3753              :          ::= [gs] na <expression>* _ <type> E
    3754              :          ::= [gs] na <expression>* _ <type> <initializer>
    3755              :          <initializer> ::= pi <expression>* E  */
    3756       160590 :       tree placement = TREE_OPERAND (expr, 0);
    3757       160590 :       tree type = TREE_OPERAND (expr, 1);
    3758       160590 :       tree nelts = TREE_OPERAND (expr, 2);
    3759       160590 :       tree init = TREE_OPERAND (expr, 3);
    3760       160590 :       tree t;
    3761              : 
    3762       160590 :       gcc_assert (code == NEW_EXPR);
    3763       160590 :       if (TREE_OPERAND (expr, 2))
    3764           12 :         code = VEC_NEW_EXPR;
    3765              : 
    3766       160590 :       if (NEW_EXPR_USE_GLOBAL (expr))
    3767       160565 :         write_string ("gs");
    3768              : 
    3769       160590 :       write_string (OVL_OP_INFO (false, code)->mangled_name);
    3770              : 
    3771       321155 :       for (t = placement; t; t = TREE_CHAIN (t))
    3772       160565 :         write_expression (TREE_VALUE (t));
    3773              : 
    3774       160590 :       write_char ('_');
    3775              : 
    3776       160590 :       if (nelts)
    3777              :         {
    3778           12 :           ++processing_template_decl;
    3779              :           /* Avoid compute_array_index_type complaints about
    3780              :              non-constant nelts.  */
    3781           12 :           tree max = cp_build_binary_op (input_location, MINUS_EXPR,
    3782              :                                          fold_convert (sizetype, nelts),
    3783              :                                          size_one_node,
    3784              :                                          tf_warning_or_error);
    3785           12 :           max = maybe_constant_value (max);
    3786           12 :           tree domain = build_index_type (max);
    3787           12 :           type = build_cplus_array_type (type, domain);
    3788           12 :           --processing_template_decl;
    3789              :         }
    3790       160590 :       write_type (type);
    3791              : 
    3792       160578 :       if (init && TREE_CODE (init) == TREE_LIST
    3793       321162 :           && DIRECT_LIST_INIT_P (TREE_VALUE (init)))
    3794              :         write_expression (TREE_VALUE (init));
    3795              :       else
    3796              :         {
    3797       160587 :           if (init)
    3798       160575 :             write_string ("pi");
    3799       160575 :           if (init && init != void_node)
    3800       321138 :             for (t = init; t; t = TREE_CHAIN (t))
    3801       160569 :               write_expression (TREE_VALUE (t));
    3802       160587 :           write_char ('E');
    3803              :         }
    3804              :     }
    3805              :   else if (code == DELETE_EXPR || code == VEC_DELETE_EXPR)
    3806              :     {
    3807           12 :       gcc_assert (code == DELETE_EXPR);
    3808           12 :       if (DELETE_EXPR_USE_VEC (expr))
    3809            6 :         code = VEC_DELETE_EXPR;
    3810              : 
    3811           12 :       if (DELETE_EXPR_USE_GLOBAL (expr))
    3812            6 :         write_string ("gs");
    3813              : 
    3814           12 :       write_string (OVL_OP_INFO (false, code)->mangled_name);
    3815              : 
    3816           12 :       write_expression (TREE_OPERAND (expr, 0));
    3817              :     }
    3818              :   else if (code == THROW_EXPR)
    3819              :     {
    3820            8 :       tree op = TREE_OPERAND (expr, 0);
    3821            8 :       if (op)
    3822              :         {
    3823            5 :           write_string ("tw");
    3824            5 :           write_expression (op);
    3825              :         }
    3826              :       else
    3827            3 :         write_string ("tr");
    3828              :     }
    3829              :   else if (code == NOEXCEPT_EXPR)
    3830              :     {
    3831            6 :       write_string ("nx");
    3832            6 :       write_expression (TREE_OPERAND (expr, 0));
    3833              :     }
    3834              :   else if (code == CONSTRUCTOR)
    3835              :     {
    3836       177048 :       bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr);
    3837       177048 :       tree etype = TREE_TYPE (expr);
    3838              : 
    3839       177048 :       if (braced_init)
    3840           97 :         write_string ("il");
    3841              :       else
    3842              :         {
    3843       176951 :           write_string ("tl");
    3844       176951 :           write_type (etype);
    3845              :         }
    3846              : 
    3847              :       /* If this is an undigested initializer, mangle it as written.
    3848              :          COMPOUND_LITERAL_P doesn't actually distinguish between digested and
    3849              :          undigested braced casts, but it should work to use it to distinguish
    3850              :          between braced casts in a template signature (undigested) and template
    3851              :          parm object values (digested), and all CONSTRUCTORS that get here
    3852              :          should be one of those two cases.  */
    3853       177048 :       bool undigested = braced_init || COMPOUND_LITERAL_P (expr);
    3854       176647 :       if (undigested || !zero_init_expr_p (expr))
    3855              :         {
    3856              :           /* Convert braced initializer lists to STRING_CSTs so that
    3857              :              A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while
    3858              :              still using the latter mangling for strings that
    3859              :              originated as braced initializer lists.  */
    3860       156201 :           expr = braced_lists_to_strings (etype, expr);
    3861              : 
    3862       156201 :           if (TREE_CODE (expr) == CONSTRUCTOR)
    3863              :             {
    3864       156193 :               vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr);
    3865       156193 :               unsigned last_nonzero = UINT_MAX;
    3866       156193 :               constructor_elt *ce;
    3867              : 
    3868       156193 :               if (!undigested)
    3869       376035 :                 for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
    3870       220243 :                   if ((TREE_CODE (etype) == UNION_TYPE
    3871           37 :                        && ce->index != first_field (etype))
    3872       220269 :                       || !zero_init_expr_p (ce->value))
    3873              :                     last_nonzero = i;
    3874              : 
    3875       156193 :               tree prev_field = NULL_TREE;
    3876       156193 :               if (undigested || last_nonzero != UINT_MAX)
    3877       374090 :                 for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
    3878              :                   {
    3879       220213 :                     if (i > last_nonzero)
    3880              :                       break;
    3881       217733 :                     if (!undigested && !CONSTRUCTOR_NO_CLEARING (expr)
    3882       217897 :                         && (TREE_CODE (etype) == RECORD_TYPE
    3883       215861 :                             || TREE_CODE (etype) == ARRAY_TYPE))
    3884              :                       {
    3885              :                         /* Write out any implicit non-trailing zeros
    3886              :                            (which we neglected to do before v21).  */
    3887       215824 :                         if (TREE_CODE (etype) == RECORD_TYPE)
    3888              :                           {
    3889       133486 :                             tree field;
    3890       133486 :                             if (i == 0)
    3891       120193 :                               field = first_field (etype);
    3892              :                             else
    3893        13293 :                               field = DECL_CHAIN (prev_field);
    3894       133898 :                             for (;;)
    3895              :                               {
    3896       133692 :                                 field = next_subobject_field (field);
    3897       133692 :                                 if (field == ce->index)
    3898              :                                   break;
    3899          206 :                                 if (abi_check (21))
    3900              :                                   {
    3901          196 :                                     tree type = TREE_TYPE (field), expr;
    3902          196 :                                     if (REFLECTION_TYPE_P (type))
    3903            0 :                                       expr = get_null_reflection ();
    3904              :                                     else
    3905          196 :                                       expr = build_zero_cst (type);
    3906          196 :                                     write_expression (expr);
    3907              :                                   }
    3908          206 :                                 field = DECL_CHAIN (field);
    3909          206 :                               }
    3910              :                           }
    3911        82338 :                         else if (TREE_CODE (etype) == ARRAY_TYPE)
    3912              :                           {
    3913        82338 :                             unsigned HOST_WIDE_INT j;
    3914        82338 :                             if (i == 0)
    3915              :                               j = 0;
    3916              :                             else
    3917        47400 :                               j = 1 + tree_to_uhwi (prev_field);
    3918        82338 :                             unsigned HOST_WIDE_INT k;
    3919        82338 :                             if (TREE_CODE (ce->index) == RANGE_EXPR)
    3920           12 :                               k = tree_to_uhwi (TREE_OPERAND (ce->index, 0));
    3921              :                             else
    3922        82326 :                               k = tree_to_uhwi (ce->index);
    3923        82338 :                             tree zero = NULL_TREE;
    3924        84108 :                             for (; j < k; ++j)
    3925         1770 :                               if (abi_check (21))
    3926              :                                 {
    3927         1188 :                                   if (!zero)
    3928           30 :                                     zero = build_zero_cst (TREE_TYPE (etype));
    3929         1188 :                                   write_expression (zero);
    3930              :                                 }
    3931              :                           }
    3932              :                       }
    3933              : 
    3934       217897 :                     if (!undigested && TREE_CODE (etype) == UNION_TYPE)
    3935              :                       {
    3936              :                         /* Express the active member as a designator.  */
    3937           37 :                         write_string ("di");
    3938           37 :                         write_unqualified_name (ce->index);
    3939              :                       }
    3940       217897 :                     unsigned reps = 1;
    3941       217897 :                     if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
    3942           12 :                       reps = range_expr_nelts (ce->index);
    3943       217897 :                     if (TREE_CODE (ce->value) == RAW_DATA_CST)
    3944              :                       {
    3945           30 :                         gcc_assert (reps == 1);
    3946           30 :                         unsigned int len = RAW_DATA_LENGTH (ce->value);
    3947              :                         /* If this is the last non-zero element, skip
    3948              :                            zeros at the end.  */
    3949           30 :                         if (i == last_nonzero)
    3950          282 :                           while (len)
    3951              :                             {
    3952          282 :                               if (RAW_DATA_POINTER (ce->value)[len - 1])
    3953              :                                 break;
    3954              :                               --len;
    3955              :                             }
    3956           30 :                         tree valtype = TREE_TYPE (ce->value);
    3957         3906 :                         for (unsigned int i = 0; i < len; ++i)
    3958              :                           {
    3959         3876 :                             write_char ('L');
    3960         3876 :                             write_type (valtype);
    3961         3876 :                             unsigned HOST_WIDE_INT v;
    3962         3876 :                             if (!TYPE_UNSIGNED (valtype)
    3963          780 :                                 && TYPE_PRECISION (valtype) == BITS_PER_UNIT
    3964         4656 :                                 && RAW_DATA_SCHAR_ELT (ce->value, i) < 0)
    3965              :                               {
    3966            0 :                                 write_char ('n');
    3967            0 :                                 v = -RAW_DATA_SCHAR_ELT (ce->value, i);
    3968              :                               }
    3969              :                             else
    3970         3876 :                               v = RAW_DATA_UCHAR_ELT (ce->value, i);
    3971         3876 :                             write_unsigned_number (v);
    3972         3876 :                             write_char ('E');
    3973              :                           }
    3974              :                       }
    3975              :                     else
    3976       435752 :                       for (unsigned j = 0; j < reps; ++j)
    3977       217885 :                         write_expression (ce->value);
    3978       217897 :                     prev_field = ce->index;
    3979       217897 :                     if (prev_field && TREE_CODE (prev_field) == RANGE_EXPR)
    3980           12 :                       prev_field = TREE_OPERAND (prev_field, 1);
    3981              :                   }
    3982              :             }
    3983              :           else
    3984              :             {
    3985            8 :               gcc_assert (TREE_CODE (expr) == STRING_CST);
    3986            8 :               write_expression (expr);
    3987              :             }
    3988              :         }
    3989       177048 :       write_char ('E');
    3990              :     }
    3991              :   else if (code == LAMBDA_EXPR)
    3992              :     {
    3993              :       /* [temp.over.link] Two lambda-expressions are never considered
    3994              :          equivalent.
    3995              : 
    3996              :          So just use the closure type mangling.  */
    3997         1408 :       write_char ('L');
    3998         1408 :       write_type (LAMBDA_EXPR_CLOSURE (expr));
    3999         1408 :       write_char ('E');
    4000              :     }
    4001              :   else if (code == REQUIRES_EXPR)
    4002       535654 :     write_requires_expr (expr);
    4003      5038996 :   else if (dependent_name (expr))
    4004              :     {
    4005       120761 :       tree name = dependent_name (expr);
    4006       120761 :       if (IDENTIFIER_ANY_OP_P (name))
    4007              :         {
    4008            9 :           if (abi_check (16))
    4009            6 :             write_string ("on");
    4010              :         }
    4011       120761 :       write_unqualified_id (name);
    4012              :     }
    4013              :   else
    4014              :     {
    4015      4918235 :     normal_expr:
    4016      4918368 :       int i, len;
    4017      4918368 :       const char *name;
    4018              : 
    4019              :       /* When we bind a variable or function to a non-type template
    4020              :          argument with reference type, we create an ADDR_EXPR to show
    4021              :          the fact that the entity's address has been taken.  But, we
    4022              :          don't actually want to output a mangling code for the `&'.  */
    4023      4918368 :       if (TREE_CODE (expr) == ADDR_EXPR
    4024         7361 :           && TREE_TYPE (expr)
    4025      4921834 :           && TYPE_REF_P (TREE_TYPE (expr)))
    4026              :         {
    4027            0 :           expr = TREE_OPERAND (expr, 0);
    4028            0 :           if (DECL_P (expr))
    4029              :             {
    4030              :               write_expression (expr);
    4031              :               return;
    4032              :             }
    4033              : 
    4034            0 :           code = TREE_CODE (expr);
    4035              :         }
    4036              : 
    4037      4918368 :       if (code == COMPONENT_REF)
    4038              :         {
    4039       200947 :           tree ob = TREE_OPERAND (expr, 0);
    4040              : 
    4041       200947 :           if (TREE_CODE (ob) == ARROW_EXPR)
    4042              :             {
    4043          320 :               write_string (OVL_OP_INFO (false, code)->mangled_name);
    4044          320 :               ob = TREE_OPERAND (ob, 0);
    4045          320 :               write_expression (ob);
    4046              :             }
    4047       200627 :           else if (write_base_ref (expr))
    4048              :             return;
    4049       200618 :           else if (!is_dummy_object (ob))
    4050              :             {
    4051       200612 :               write_string ("dt");
    4052       200612 :               write_expression (ob);
    4053              :             }
    4054              :           /* else, for a non-static data member with no associated object (in
    4055              :              unevaluated context), use the unresolved-name mangling.  */
    4056              : 
    4057       200938 :           write_member_name (TREE_OPERAND (expr, 1));
    4058       200938 :           return;
    4059              :         }
    4060              : 
    4061              :       /* If it wasn't any of those, recursively expand the expression.  */
    4062      4717421 :       name = OVL_OP_INFO (false, code)->mangled_name;
    4063              : 
    4064              :       /* We used to mangle const_cast and static_cast like a C cast.  */
    4065      4717421 :       if (code == CONST_CAST_EXPR
    4066      4717421 :           || code == STATIC_CAST_EXPR)
    4067              :         {
    4068          265 :           if (!abi_check (6))
    4069           15 :             name = OVL_OP_INFO (false, CAST_EXPR)->mangled_name;
    4070              :         }
    4071              : 
    4072      4717421 :       if (name == NULL)
    4073              :         {
    4074            3 :           switch (code)
    4075              :             {
    4076            3 :             case TRAIT_EXPR:
    4077            3 :               error ("use of built-in trait %qE in function signature; "
    4078              :                      "use library traits instead", expr);
    4079            3 :               break;
    4080              : 
    4081            0 :             case ERROR_MARK:
    4082            0 :               if (seen_error ())
    4083              :                 break;
    4084              :               /* FALLTHROUGH */
    4085            0 :             default:
    4086            0 :               sorry ("mangling %C", code);
    4087            0 :               break;
    4088              :             }
    4089              :           return;
    4090              :         }
    4091              :       else
    4092      4717418 :         write_string (name);
    4093              : 
    4094      4717418 :       switch (code)
    4095              :         {
    4096      2129635 :         case CALL_EXPR:
    4097      2129635 :           if (tree fn = CALL_EXPR_FN (expr))
    4098              :             {
    4099      2129629 :               if (TREE_CODE (fn) == ADDR_EXPR)
    4100            0 :                 fn = TREE_OPERAND (fn, 0);
    4101              : 
    4102              :               /* Mangle a dependent name as the name, not whatever happens to
    4103              :                  be the first function in the overload set.  */
    4104      2128906 :               if (OVL_P (fn)
    4105      2384487 :                   && type_dependent_expression_p_push (expr))
    4106       254962 :                 fn = OVL_NAME (fn);
    4107              : 
    4108      2129629 :               write_expression (fn);
    4109              :             }
    4110              :           else
    4111            6 :             switch (CALL_EXPR_IFN (expr))
    4112              :               {
    4113              :               /* Calls to __builtin_bswapg/__builtin_bitreverseg are parsed
    4114              :                  as IFN_BSWAP/IFN_BITREVERSE calls because we don't have
    4115              :                  those builtins but instead keywords.  Pretend they are
    4116              :                  builtin function template.  */
    4117            3 :               case IFN_BSWAP:
    4118            3 :                 write_source_name (get_identifier ("__builtin_bswapg"));
    4119            3 :                 break;
    4120            3 :               case IFN_BITREVERSE:
    4121            3 :                 write_source_name (get_identifier ("__builtin_bitreverseg"));
    4122            3 :                 break;
    4123            0 :               default:
    4124            0 :                 gcc_unreachable ();
    4125              :               }
    4126              : 
    4127      2779691 :           for (i = 0; i < call_expr_nargs (expr); ++i)
    4128       650056 :             write_expression (CALL_EXPR_ARG (expr, i));
    4129      2129635 :           write_char ('E');
    4130      2129635 :           break;
    4131              : 
    4132       162449 :         case CAST_EXPR:
    4133       162449 :           write_type (TREE_TYPE (expr));
    4134       162449 :           if (list_length (TREE_OPERAND (expr, 0)) == 1)
    4135       162271 :             write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
    4136              :           else
    4137              :             {
    4138          178 :               tree args = TREE_OPERAND (expr, 0);
    4139          178 :               write_char ('_');
    4140          190 :               for (; args; args = TREE_CHAIN (args))
    4141           12 :                 write_expression (TREE_VALUE (args));
    4142          178 :               write_char ('E');
    4143              :             }
    4144              :           break;
    4145              : 
    4146          271 :         case DYNAMIC_CAST_EXPR:
    4147          271 :         case REINTERPRET_CAST_EXPR:
    4148          271 :         case STATIC_CAST_EXPR:
    4149          271 :         case CONST_CAST_EXPR:
    4150          271 :           write_type (TREE_TYPE (expr));
    4151          271 :           write_expression (TREE_OPERAND (expr, 0));
    4152          271 :           break;
    4153              : 
    4154         7551 :         case PREINCREMENT_EXPR:
    4155         7551 :         case PREDECREMENT_EXPR:
    4156         7551 :           if (abi_check (6))
    4157         7542 :             write_char ('_');
    4158              :           /* Fall through.  */
    4159              : 
    4160      2425063 :         default:
    4161              :           /* In the middle-end, some expressions have more operands than
    4162              :              they do in templates (and mangling).  */
    4163      2425063 :           len = cp_tree_operand_length (expr);
    4164              : 
    4165      8761940 :           for (i = 0; i < len; ++i)
    4166              :             {
    4167      3911814 :               tree operand = TREE_OPERAND (expr, i);
    4168              :               /* As a GNU extension, the middle operand of a
    4169              :                  conditional may be omitted.  Since expression
    4170              :                  manglings are supposed to represent the input token
    4171              :                  stream, there's no good way to mangle such an
    4172              :                  expression without extending the C++ ABI.  */
    4173      3911814 :               if (code == COND_EXPR && i == 1 && !operand)
    4174              :                 {
    4175            3 :                   error ("omitted middle operand to %<?:%> operand "
    4176              :                          "cannot be mangled");
    4177            3 :                   continue;
    4178              :                 }
    4179      3911811 :               else if (FOLD_EXPR_P (expr))
    4180              :                 {
    4181              :                   /* The first 'operand' of a fold-expression is the operator
    4182              :                      that it folds over.  */
    4183       514960 :                   if (i == 0)
    4184              :                     {
    4185       257343 :                       int fcode = TREE_INT_CST_LOW (operand);
    4186       257343 :                       write_string (OVL_OP_INFO (false, fcode)->mangled_name);
    4187       257343 :                       continue;
    4188       257343 :                     }
    4189       257617 :                   else if (code == BINARY_LEFT_FOLD_EXPR)
    4190              :                     {
    4191              :                       /* The order of operands of the binary left and right
    4192              :                          folds is the same, but we want to mangle them in
    4193              :                          lexical order, i.e. non-pack first.  */
    4194          542 :                       if (i == 1)
    4195          271 :                         operand = FOLD_EXPR_INIT (expr);
    4196              :                       else
    4197          271 :                         operand = FOLD_EXPR_PACK (expr);
    4198              :                     }
    4199       257617 :                   if (PACK_EXPANSION_P (operand))
    4200       257343 :                     operand = PACK_EXPANSION_PATTERN (operand);
    4201              :                 }
    4202      3654468 :               write_expression (operand);
    4203              :             }
    4204              :         }
    4205              :     }
    4206              : }
    4207              : 
    4208              : /* Non-terminal <reflection>.
    4209              : 
    4210              :      <reflection> ::= nu                          # null reflection
    4211              :                   ::= vl <expression>                     # value
    4212              :                   ::= ob <expression>                     # object
    4213              :                   ::= vr <variable name>          # variable
    4214              :                   ::= sb <sb name>                        # structured binding
    4215              :                   ::= fn <function encoding>              # function
    4216              :                   ::= pa [ <nonnegative number> ] _ <encoding>      # fn param
    4217              :                   ::= en <prefix> <unqualified-name>        # enumerator
    4218              :                   ::= an [ <nonnegative number> ] _       # annotation
    4219              :                   ::= ta <alias prefix> <alias unqualified-name>
    4220              :                       [ <alias template-args> ] _ <type> # type alias
    4221              :                   ::= ty <type>                           # type
    4222              :                   ::= dm <prefix> <unqualified-name>        # ns data member
    4223              :                   ::= da <prefix> [ <nonnegative number> ] _ # empty anon union
    4224              :                                                              # data member
    4225              :                   ::= un <prefix> [ <nonnegative number> ] _ # unnamed bitfld
    4226              :                   ::= ct [ <prefix> ] <unqualified-name> # class template
    4227              :                   ::= ft [ <prefix> ] <unqualified-name> # function template
    4228              :                   ::= vt [ <prefix> ] <unqualified-name> # variable template
    4229              :                   ::= at [ <prefix> ] <unqualified-name> # alias template
    4230              :                   ::= co [ <prefix> ] <unqualified-name> # concept
    4231              :                   ::= na [ <prefix> ] <unqualified-name> # namespace alias
    4232              :                   ::= ns [ <prefix> ] <unqualified-name> # namespace
    4233              :                   ::= gs                                 # ^^::
    4234              :                   ::= tt <template-template-param>         # templ templ param
    4235              :                   ::= de <expression>                      # dependent expr
    4236              :                   ::= ba [ <nonnegative number> ] _ <type> # dir. base cls rel
    4237              :                   ::= ds <type> _ [ <unqualified-name> ] _
    4238              :                       [ <alignment number> ] _ [ <bit-width number> ] _
    4239              :                       [ n ] [ <template-arg>* ]           # data member spec  */
    4240              : 
    4241              : static void
    4242         1708 : write_reflection (tree refl)
    4243              : {
    4244         1708 :   char prefix[3];
    4245         1708 :   tree arg = reflection_mangle_prefix (refl, prefix);
    4246         1708 :   if (strcmp (prefix, "dm") == 0
    4247          234 :       && DECL_NAME (arg) == NULL_TREE
    4248           12 :       && ANON_AGGR_TYPE_P (TREE_TYPE (arg))
    4249         1720 :       && anon_aggr_naming_decl (TREE_TYPE (arg)) == NULL_TREE)
    4250           12 :     strcpy (prefix, "da");
    4251         1708 :   write_string (prefix);
    4252              :   /* If there is no argument, nothing further needs to be mangled.  */
    4253         1708 :   if (arg == NULL_TREE)
    4254           62 :     return;
    4255         1646 :   if (strcmp (prefix, "vl") == 0 || strcmp (prefix, "ob") == 0)
    4256           22 :     write_expression (arg);
    4257         1624 :   else if (strcmp (prefix, "vr") == 0 || strcmp (prefix, "sb") == 0)
    4258          234 :     write_name (arg);
    4259         1390 :   else if (strcmp (prefix, "fn") == 0)
    4260          196 :     write_encoding (arg);
    4261         1194 :   else if (strcmp (prefix, "pa") == 0)
    4262              :     {
    4263           82 :       tree fn = DECL_CONTEXT (arg);
    4264              :       /* DECL_PARM_INDEX is 1-based but here we want a 0-based index.  */
    4265           82 :       const int idx = DECL_PARM_INDEX (arg) - 1;
    4266           82 :       write_compact_number (idx);
    4267           82 :       write_encoding (fn);
    4268              :     }
    4269         1112 :   else if (strcmp (prefix, "en") == 0)
    4270              :     {
    4271           26 :       write_prefix (decl_mangling_context (arg));
    4272           26 :       write_unqualified_name (arg);
    4273              :     }
    4274         1086 :   else if (strcmp (prefix, "an") == 0)
    4275           10 :     write_compact_number (tree_to_uhwi (arg));
    4276         1076 :   else if (strcmp (prefix, "ta") == 0)
    4277              :     {
    4278           28 :       arg = TYPE_NAME (arg);
    4279              :       /* Can't use write_prefix (arg) here instead of
    4280              :          write_prefix + write_unqualified_name + optional
    4281              :          write_template_args, it shouldn't be
    4282              :          remembered among substitutions.  */
    4283           28 :       write_prefix (decl_mangling_context (arg));
    4284           28 :       if (modules_p ())
    4285            0 :         maybe_write_module (arg);
    4286           28 :       write_source_name (DECL_NAME (arg));
    4287           28 :       tree template_info = maybe_template_info (arg);
    4288           28 :       if (template_info)
    4289            4 :         write_template_args (TI_ARGS (template_info));
    4290           28 :       write_char ('_');
    4291           28 :       write_type (DECL_ORIGINAL_TYPE (arg));
    4292              :     }
    4293         1048 :   else if (strcmp (prefix, "ty") == 0)
    4294          314 :     write_type (arg);
    4295          734 :   else if (strcmp (prefix, "dm") == 0)
    4296              :     {
    4297          222 :       tree ctx = decl_mangling_context (arg);
    4298          452 :       while (ctx && ANON_UNION_TYPE_P (ctx))
    4299            8 :         ctx = decl_mangling_context (TYPE_NAME (ctx));
    4300          222 :       write_prefix (ctx);
    4301          222 :       write_unqualified_name (arg);
    4302              :     }
    4303          512 :   else if (strcmp (prefix, "da") == 0)
    4304              :     {
    4305           12 :       int idx = 0;
    4306           12 :       tree ctx = decl_mangling_context (arg);
    4307          198 :       for (tree f = TYPE_FIELDS (ctx); f; f = DECL_CHAIN (f))
    4308          198 :         if (f == arg)
    4309              :           break;
    4310          186 :         else if (TREE_CODE (f) == FIELD_DECL
    4311           18 :                  && DECL_NAME (f) == NULL_TREE
    4312           18 :                  && ANON_AGGR_TYPE_P (TREE_TYPE (f))
    4313          204 :                  && anon_aggr_naming_decl (TREE_TYPE (f)) == NULL_TREE)
    4314           18 :           ++idx;
    4315           12 :       write_prefix (ctx);
    4316           12 :       write_compact_number (idx);
    4317              :     }
    4318          500 :   else if (strcmp (prefix, "un") == 0)
    4319              :     {
    4320            8 :       tree ctx = DECL_CONTEXT (arg);
    4321            8 :       int idx = 0;
    4322          142 :       for (tree f = TYPE_FIELDS (ctx); f; f = DECL_CHAIN (f))
    4323          142 :         if (f == arg)
    4324              :           break;
    4325          134 :         else if (TREE_CODE (f) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (f))
    4326            6 :           ++idx;
    4327            8 :       write_prefix (decl_mangling_context (arg));
    4328            8 :       write_compact_number (idx);
    4329              :     }
    4330          492 :   else if (strcmp (prefix, "ct") == 0
    4331          454 :            || strcmp (prefix, "ft") == 0
    4332          408 :            || strcmp (prefix, "vt") == 0
    4333          390 :            || strcmp (prefix, "at") == 0
    4334          372 :            || strcmp (prefix, "co") == 0
    4335          358 :            || strcmp (prefix, "na") == 0
    4336          320 :            || strcmp (prefix, "ns") == 0)
    4337              :     {
    4338          376 :       write_prefix (decl_mangling_context (arg));
    4339          376 :       write_unqualified_name (STRIP_TEMPLATE (arg));
    4340              :     }
    4341          116 :   else if (strcmp (prefix, "ba") == 0)
    4342              :     {
    4343           26 :       gcc_assert (TREE_CODE (arg) == TREE_BINFO);
    4344              :       tree c = arg, base_binfo;
    4345           52 :       while (BINFO_INHERITANCE_CHAIN (c))
    4346              :         c = BINFO_INHERITANCE_CHAIN (c);
    4347              : 
    4348              :       unsigned idx;
    4349           30 :       for (idx = 0; BINFO_BASE_ITERATE (c, idx, base_binfo); idx++)
    4350           30 :         if (base_binfo == arg)
    4351              :           break;
    4352           26 :       write_compact_number (idx);
    4353           26 :       write_type (BINFO_TYPE (c));
    4354              :     }
    4355           90 :   else if (strcmp (prefix, "ds") == 0)
    4356              :     {
    4357           84 :       gcc_assert (TREE_CODE (arg) == TREE_VEC);
    4358           84 :       write_type (TREE_VEC_ELT (arg, 0));
    4359           84 :       write_char ('_');
    4360           84 :       if (TREE_VEC_ELT (arg, 1))
    4361           80 :         write_unqualified_id (TREE_VEC_ELT (arg, 1));
    4362           84 :       write_char ('_');
    4363           84 :       if (TREE_VEC_ELT (arg, 2))
    4364            2 :         write_number (tree_to_shwi (TREE_VEC_ELT (arg, 2)), 0, 10);
    4365           84 :       write_char ('_');
    4366           84 :       if (TREE_VEC_ELT (arg, 3))
    4367            6 :         write_number (tree_to_shwi (TREE_VEC_ELT (arg, 3)), 0, 10);
    4368           84 :       write_char ('_');
    4369           84 :       if (integer_nonzerop (TREE_VEC_ELT (arg, 4)))
    4370            2 :         write_char ('n');
    4371           90 :       for (int i = 5; i < TREE_VEC_LENGTH (arg); ++i)
    4372            6 :         write_template_arg (REFLECT_EXPR_HANDLE (TREE_VEC_ELT (arg, i)));
    4373              :     }
    4374            6 :   else if (strcmp (prefix, "tt") == 0)
    4375              :     {
    4376            2 :       gcc_assert (DECL_TEMPLATE_TEMPLATE_PARM_P (arg));
    4377            2 :       write_template_template_param (TREE_TYPE (arg));
    4378              :     }
    4379            4 :   else if (strcmp (prefix, "de") == 0)
    4380            4 :     write_expression (arg);
    4381              :   else
    4382            0 :     gcc_unreachable ();
    4383              : }
    4384              : 
    4385              : /* Mangle a dependent splice.
    4386              : 
    4387              :      <splice> ::= DS <expression> [ <template-args> ] E
    4388              : 
    4389              :    TODO: This is only a proposed mangling.
    4390              :    See <https://github.com/itanium-cxx-abi/cxx-abi/issues/208>.  */
    4391              : 
    4392              : static void
    4393          108 : write_splice (tree sp)
    4394              : {
    4395          108 :   write_string ("DS");
    4396              : 
    4397          108 :   if (TREE_CODE (sp) == SPLICE_SCOPE)
    4398           58 :     sp = SPLICE_SCOPE_EXPR (sp);
    4399          108 :   gcc_assert (dependent_splice_p (sp));
    4400          108 :   if (TREE_CODE (sp) == TEMPLATE_ID_EXPR)
    4401              :     {
    4402            4 :       write_expression (TREE_OPERAND (TREE_OPERAND (sp, 0), 0));
    4403            4 :       write_template_args (TREE_OPERAND (sp, 1));
    4404              :     }
    4405              :   else
    4406          104 :     write_expression (TREE_OPERAND (sp, 0));
    4407              : 
    4408          108 :   write_char ('E');
    4409          108 : }
    4410              : 
    4411              : /* Literal subcase of non-terminal <template-arg>.
    4412              : 
    4413              :      "Literal arguments, e.g. "A<42L>", are encoded with their type
    4414              :      and value. Negative integer values are preceded with "n"; for
    4415              :      example, "A<-42L>" becomes "1AILln42EE". The bool value false is
    4416              :      encoded as 0, true as 1."  */
    4417              : 
    4418              : static void
    4419     95949529 : write_template_arg_literal (const tree value)
    4420              : {
    4421     95949529 :   if (TREE_CODE (value) == STRING_CST)
    4422              :     /* Temporarily mangle strings as braced initializer lists.  */
    4423         1667 :     write_string ("tl");
    4424              :   else
    4425     95947862 :     write_char ('L');
    4426              : 
    4427     95949529 :   tree valtype = TREE_TYPE (value);
    4428     95949529 :   write_type (valtype);
    4429              : 
    4430              :   /* Write a null member pointer value as (type)0, regardless of its
    4431              :      real representation.  */
    4432     95949529 :   if (null_member_pointer_value_p (value))
    4433          264 :     write_integer_cst (integer_zero_node);
    4434              :   else
    4435     95949265 :     switch (TREE_CODE (value))
    4436              :       {
    4437        24400 :       case CONST_DECL:
    4438        24400 :         write_integer_cst (DECL_INITIAL (value));
    4439        24400 :         break;
    4440              : 
    4441     95918941 :       case INTEGER_CST:
    4442     95918941 :         gcc_assert (!same_type_p (TREE_TYPE (value), boolean_type_node)
    4443              :                     || integer_zerop (value) || integer_onep (value));
    4444     95918941 :         if (!(abi_version_at_least (14)
    4445     95912071 :               && NULLPTR_TYPE_P (TREE_TYPE (value))))
    4446     95918885 :           write_integer_cst (value);
    4447              :         break;
    4448              : 
    4449         2543 :       case REAL_CST:
    4450         2543 :         write_real_cst (value);
    4451         2543 :         break;
    4452              : 
    4453            6 :       case COMPLEX_CST:
    4454            6 :         if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST
    4455            6 :             && TREE_CODE (TREE_IMAGPART (value)) == INTEGER_CST)
    4456              :           {
    4457            3 :             write_integer_cst (TREE_REALPART (value));
    4458            3 :             write_char ('_');
    4459            3 :             write_integer_cst (TREE_IMAGPART (value));
    4460              :           }
    4461            3 :         else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST
    4462            3 :                  && TREE_CODE (TREE_IMAGPART (value)) == REAL_CST)
    4463              :           {
    4464            3 :             write_real_cst (TREE_REALPART (value));
    4465            3 :             write_char ('_');
    4466            3 :             write_real_cst (TREE_IMAGPART (value));
    4467              :           }
    4468              :         else
    4469            0 :           gcc_unreachable ();
    4470              :         break;
    4471              : 
    4472         1667 :       case STRING_CST:
    4473         1667 :         {
    4474              :           /* Mangle strings the same as braced initializer lists.  */
    4475         1667 :           unsigned n = TREE_STRING_LENGTH (value);
    4476         1667 :           const char *str = TREE_STRING_POINTER (value);
    4477              : 
    4478              :           /* Count the number of trailing nuls and subtract them from
    4479              :              STRSIZE because they don't need to be mangled.  */
    4480         4638 :           for (const char *p = str + n - 1; ; --p)
    4481              :             {
    4482         4638 :               if (*p || p == str)
    4483              :                 {
    4484         1667 :                   n -= str + n - !!*p - p;
    4485         1667 :                   break;
    4486              :                 }
    4487              :             }
    4488         1667 :           tree eltype = TREE_TYPE (valtype);
    4489        11784 :           for (const char *p = str; n--; ++p)
    4490              :             {
    4491        10117 :               write_char ('L');
    4492        10117 :               write_type (eltype);
    4493        10117 :               write_unsigned_number (*(const unsigned char*)p);
    4494        10117 :               write_string ("E");
    4495              :             }
    4496              :           break;
    4497              :         }
    4498              : 
    4499         1708 :       case REFLECT_EXPR:
    4500         1708 :         write_reflection (value);
    4501         1708 :         break;
    4502              : 
    4503            0 :       default:
    4504            0 :         gcc_unreachable ();
    4505              :       }
    4506              : 
    4507     95949529 :   write_char ('E');
    4508     95949529 : }
    4509              : 
    4510              : /* Non-terminal <template-arg>.
    4511              : 
    4512              :      <template-arg> ::= <type>                              # type
    4513              :                     ::= L <type> </value/ number> E # literal
    4514              :                     ::= LZ <name> E                       # external name
    4515              :                     ::= X <expression> E          # expression  */
    4516              : 
    4517              : static void
    4518    772148422 : write_template_arg (tree node)
    4519              : {
    4520    772148422 :   enum tree_code code = TREE_CODE (node);
    4521              : 
    4522    772148422 :   MANGLE_TRACE_TREE ("template-arg", node);
    4523              : 
    4524              :   /* A template template parameter's argument list contains TREE_LIST
    4525              :      nodes of which the value field is the actual argument.  */
    4526    772148422 :   if (code == TREE_LIST)
    4527              :     {
    4528            0 :       node = TREE_VALUE (node);
    4529              :       /* If it's a decl, deal with its type instead.  */
    4530            0 :       if (DECL_P (node))
    4531              :         {
    4532            0 :           node = TREE_TYPE (node);
    4533            0 :           code = TREE_CODE (node);
    4534              :         }
    4535              :     }
    4536              : 
    4537    772148422 :   if (VAR_P (node) && DECL_NTTP_OBJECT_P (node))
    4538              :     /* We want to mangle the argument, not the var we stored it in.  */
    4539        51639 :     node = tparm_object_argument (node);
    4540              : 
    4541              :   /* Strip a conversion added by convert_nontype_argument.  */
    4542    772148422 :   if (TREE_CODE (node) == IMPLICIT_CONV_EXPR)
    4543           78 :     node = TREE_OPERAND (node, 0);
    4544    772148422 :   if (REFERENCE_REF_P (node))
    4545          282 :     node = TREE_OPERAND (node, 0);
    4546    772148422 :   if (TREE_CODE (node) == NOP_EXPR
    4547    772148422 :       && TYPE_REF_P (TREE_TYPE (node)))
    4548              :     {
    4549              :       /* Template parameters can be of reference type. To maintain
    4550              :          internal consistency, such arguments use a conversion from
    4551              :          address of object to reference type.  */
    4552          276 :       gcc_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR);
    4553          276 :       node = TREE_OPERAND (TREE_OPERAND (node, 0), 0);
    4554              :     }
    4555              : 
    4556    772148422 :   if (TREE_CODE (node) == BASELINK
    4557    772148422 :       && !type_unknown_p (node))
    4558              :     {
    4559              :       /* Before v6 we wrongly wrapped a class-scope function in X/E.  */
    4560           18 :       if (abi_check (6))
    4561           12 :         node = BASELINK_FUNCTIONS (node);
    4562              :     }
    4563              : 
    4564    772148422 :   if (ARGUMENT_PACK_P (node))
    4565              :     {
    4566              :       /* Expand the template argument pack. */
    4567     10118962 :       tree args = ARGUMENT_PACK_ARGS (node);
    4568     10118962 :       int i, length = TREE_VEC_LENGTH (args);
    4569     10118962 :       if (abi_check (6))
    4570     10118944 :         write_char ('J');
    4571              :       else
    4572           18 :         write_char ('I');
    4573     24669401 :       for (i = 0; i < length; ++i)
    4574     14550439 :         write_template_arg (TREE_VEC_ELT (args, i));
    4575     10118962 :       write_char ('E');
    4576              :     }
    4577    762029460 :   else if (TYPE_P (node))
    4578    664870782 :     write_type (node);
    4579     97158678 :   else if (code == TEMPLATE_DECL)
    4580              :     /* A template appearing as a template arg is a template template arg.  */
    4581       807550 :     write_template_template_arg (node);
    4582     95542524 :   else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST)
    4583       808604 :            || code == CONST_DECL
    4584       812338 :            || null_member_pointer_value_p (node)
    4585     97163318 :            || code == REFLECT_EXPR)
    4586     95540386 :     write_template_arg_literal (node);
    4587       810742 :   else if (code == EXCESS_PRECISION_EXPR
    4588       810742 :            && TREE_CODE (TREE_OPERAND (node, 0)) == REAL_CST)
    4589            0 :     write_template_arg_literal (fold_convert (TREE_TYPE (node),
    4590              :                                               TREE_OPERAND (node, 0)));
    4591       810742 :   else if (DECL_P (node))
    4592              :     {
    4593          295 :       write_char ('L');
    4594              :       /* Until ABI version 3, the underscore before the mangled name
    4595              :          was incorrectly omitted.  */
    4596          295 :       if (!abi_check (3))
    4597           21 :         write_char ('Z');
    4598              :       else
    4599          274 :         write_string ("_Z");
    4600          295 :       write_encoding (node);
    4601          295 :       write_char ('E');
    4602              :     }
    4603              :   else
    4604              :     {
    4605              :       /* Template arguments may be expressions.  */
    4606       810447 :       write_char ('X');
    4607       810447 :       write_expression (node);
    4608       810447 :       write_char ('E');
    4609              :     }
    4610    772148422 : }
    4611              : 
    4612              : /*  <template-template-arg>
    4613              :                         ::= <name>
    4614              :                         ::= <substitution>  */
    4615              : 
    4616              : static void
    4617       807550 : write_template_template_arg (const tree decl)
    4618              : {
    4619       807550 :   MANGLE_TRACE_TREE ("template-template-arg", decl);
    4620              : 
    4621       807550 :   if (find_substitution (decl))
    4622              :     return;
    4623       724257 :   write_name (decl);
    4624       724257 :   add_substitution (decl);
    4625              : }
    4626              : 
    4627              : 
    4628              : /* Non-terminal <array-type>.  TYPE is an ARRAY_TYPE.
    4629              : 
    4630              :      <array-type> ::= A [</dimension/ number>] _ </element/ type>
    4631              :                   ::= A <expression> _ </element/ type>
    4632              : 
    4633              :      "Array types encode the dimension (number of elements) and the
    4634              :      element type.  For variable length arrays, the dimension (but not
    4635              :      the '_' separator) is omitted."
    4636              :      Note that for flexible array members, like for other arrays of
    4637              :      unspecified size, the dimension is also omitted.  */
    4638              : 
    4639              : static void
    4640      1581634 : write_array_type (const tree type)
    4641              : {
    4642      1581634 :   write_char ('A');
    4643      1581634 :   if (TYPE_DOMAIN (type))
    4644              :     {
    4645       401271 :       tree index_type;
    4646              : 
    4647       401271 :       index_type = TYPE_DOMAIN (type);
    4648              :       /* The INDEX_TYPE gives the upper and lower bounds of the array.
    4649              :          It's null for flexible array members which have no upper bound
    4650              :          (this is a change from GCC 5 and prior where such members were
    4651              :          incorrectly mangled as zero-length arrays).  */
    4652       401271 :       if (tree max = TYPE_MAX_VALUE (index_type))
    4653              :         {
    4654       401271 :           if (TREE_CODE (max) == INTEGER_CST)
    4655              :             {
    4656              :               /* The ABI specifies that we should mangle the number of
    4657              :                  elements in the array, not the largest allowed index.  */
    4658       237777 :               offset_int wmax = wi::to_offset (max) + 1;
    4659              :               /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
    4660              :                  number of elements as zero.  */
    4661       237777 :               wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
    4662       237777 :               gcc_assert (wi::fits_uhwi_p (wmax));
    4663       237777 :               write_unsigned_number (wmax.to_uhwi ());
    4664              :             }
    4665              :           else
    4666              :             {
    4667       163494 :               gcc_checking_assert (TREE_CODE (max) == MINUS_EXPR
    4668              :                                    && integer_onep (TREE_OPERAND (max, 1)));
    4669       163494 :               max = TREE_OPERAND (max, 0);
    4670       163494 :               write_expression (max);
    4671              :             }
    4672              :         }
    4673              :     }
    4674      1581634 :   write_char ('_');
    4675      1581634 :   write_type (TREE_TYPE (type));
    4676      1581634 : }
    4677              : 
    4678              : /* Non-terminal <pointer-to-member-type> for pointer-to-member
    4679              :    variables.  TYPE is a pointer-to-member POINTER_TYPE.
    4680              : 
    4681              :      <pointer-to-member-type> ::= M </class/ type> </member/ type>  */
    4682              : 
    4683              : static void
    4684       286368 : write_pointer_to_member_type (const tree type)
    4685              : {
    4686       286368 :   write_char ('M');
    4687       286368 :   write_type (TYPE_PTRMEM_CLASS_TYPE (type));
    4688       286368 :   write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type));
    4689       286368 : }
    4690              : 
    4691              : /* Non-terminal <template-param>.  PARM is a TEMPLATE_TYPE_PARM,
    4692              :    TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
    4693              :    TEMPLATE_PARM_INDEX.
    4694              : 
    4695              :      <template-param> ::= T </parameter/ number> _  */
    4696              : 
    4697              : static void
    4698     29471274 : write_template_param (const tree parm)
    4699              : {
    4700     29471274 :   int parm_index;
    4701     29471274 :   int level;
    4702              : 
    4703     29471274 :   MANGLE_TRACE_TREE ("template-parm", parm);
    4704              : 
    4705     29471274 :   switch (TREE_CODE (parm))
    4706              :     {
    4707     28685933 :     case TEMPLATE_TYPE_PARM:
    4708     28685933 :     case TEMPLATE_TEMPLATE_PARM:
    4709     28685933 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    4710     28685933 :       parm_index = TEMPLATE_TYPE_IDX (parm);
    4711     28685933 :       level = TEMPLATE_TYPE_LEVEL (parm);
    4712     28685933 :       break;
    4713              : 
    4714       785341 :     case TEMPLATE_PARM_INDEX:
    4715       785341 :       parm_index = TEMPLATE_PARM_IDX (parm);
    4716       785341 :       level = TEMPLATE_PARM_LEVEL (parm);
    4717       785341 :       break;
    4718              : 
    4719            0 :     default:
    4720            0 :       gcc_unreachable ();
    4721              :     }
    4722              : 
    4723     29471274 :   write_char ('T');
    4724     29471274 :   if (level > 1)
    4725              :     {
    4726        28673 :       if (abi_check (19))
    4727              :         {
    4728        28661 :           write_char ('L');
    4729        28661 :           write_compact_number (level - 1);
    4730              :         }
    4731              :     }
    4732              :   /* NUMBER as it appears in the mangling is (-1)-indexed, with the
    4733              :      earliest template param denoted by `_'.  */
    4734     29471274 :   write_compact_number (parm_index);
    4735     29471274 : }
    4736              : 
    4737              : /*  <template-template-param>
    4738              :                         ::= <template-param>
    4739              :                         ::= <substitution>  */
    4740              : 
    4741              : static void
    4742          631 : write_template_template_param (const tree parm)
    4743              : {
    4744          631 :   tree templ = NULL_TREE;
    4745              : 
    4746              :   /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
    4747              :      template template parameter.  The substitution candidate here is
    4748              :      only the template.  */
    4749          631 :   if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
    4750              :     {
    4751          536 :       templ
    4752          536 :         = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
    4753          536 :       if (find_substitution (templ))
    4754              :         return;
    4755              :     }
    4756              : 
    4757              :   /* <template-param> encodes only the template parameter position,
    4758              :      not its template arguments, which is fine here.  */
    4759          631 :   write_template_param (parm);
    4760          631 :   if (templ)
    4761          536 :     add_substitution (templ);
    4762              : }
    4763              : 
    4764              : /* Non-terminal <substitution>.
    4765              : 
    4766              :       <substitution> ::= S <seq-id> _
    4767              :                      ::= S_  */
    4768              : 
    4769              : static void
    4770    182634045 : write_substitution (const int seq_id)
    4771              : {
    4772    182634045 :   MANGLE_TRACE ("substitution", "");
    4773              : 
    4774    182634045 :   write_char ('S');
    4775    182634045 :   if (seq_id > 0)
    4776    159052304 :     write_number (seq_id - 1, /*unsigned=*/1, 36);
    4777    182634045 :   write_char ('_');
    4778    182634045 : }
    4779              : 
    4780              : /* Start mangling ENTITY.  */
    4781              : 
    4782              : static inline void
    4783    232550662 : start_mangling (const tree entity)
    4784              : {
    4785    232550662 :   G = {};
    4786    232550662 :   G.entity = entity;
    4787    232550662 :   obstack_free (&name_obstack, name_base);
    4788    232550662 :   mangle_obstack = &name_obstack;
    4789    232550662 :   name_base = obstack_alloc (&name_obstack, 0);
    4790    232550662 : }
    4791              : 
    4792              : /* Done with mangling.  Release the data.  */
    4793              : 
    4794              : static void
    4795    232550662 : finish_mangling_internal (void)
    4796              : {
    4797              :   /* Clear all the substitutions.  */
    4798    232550662 :   vec_safe_truncate (G.substitutions, 0);
    4799              : 
    4800    232550662 :   if (G.mod)
    4801         7873 :     mangle_module_fini ();
    4802              : 
    4803              :   /* Null-terminate the string.  */
    4804    232550662 :   write_char ('\0');
    4805    232550662 : }
    4806              : 
    4807              : 
    4808              : /* Like finish_mangling_internal, but return the mangled string.  */
    4809              : 
    4810              : static inline const char *
    4811       457708 : finish_mangling (void)
    4812              : {
    4813       457708 :   finish_mangling_internal ();
    4814       457708 :   return (const char *) obstack_finish (mangle_obstack);
    4815              : }
    4816              : 
    4817              : /* Like finish_mangling_internal, but return an identifier.  */
    4818              : 
    4819              : static tree
    4820    232092954 : finish_mangling_get_identifier (void)
    4821              : {
    4822    232092954 :   finish_mangling_internal ();
    4823              :   /* Don't obstack_finish here, and the next start_mangling will
    4824              :      remove the identifier.  */
    4825    232092954 :   return get_identifier ((const char *) obstack_base (mangle_obstack));
    4826              : }
    4827              : 
    4828              : /* Initialize data structures for mangling.  */
    4829              : 
    4830              : void
    4831       101489 : init_mangle (void)
    4832              : {
    4833       101489 :   gcc_obstack_init (&name_obstack);
    4834       101489 :   name_base = obstack_alloc (&name_obstack, 0);
    4835       101489 :   vec_alloc (G.substitutions, 0);
    4836              : 
    4837              :   /* Cache these identifiers for quick comparison when checking for
    4838              :      standard substitutions.  */
    4839       101489 :   subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator");
    4840       101489 :   subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string");
    4841       101489 :   subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits");
    4842       101489 :   subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream");
    4843       101489 :   subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream");
    4844       101489 :   subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
    4845       101489 : }
    4846              : 
    4847              : /* Generate a mangling for MODULE's global initializer fn.  */
    4848              : 
    4849              : tree
    4850         2102 : mangle_module_global_init (int module)
    4851              : {
    4852         2102 :   start_mangling (NULL_TREE);
    4853              : 
    4854         2102 :   write_string ("_ZGI");
    4855         2102 :   write_module (module, true);
    4856              : 
    4857         2102 :   return finish_mangling_get_identifier ();
    4858              : }
    4859              : 
    4860              : /* Generate the mangled name of DECL.  */
    4861              : 
    4862              : static tree
    4863    225410123 : mangle_decl_string (const tree decl)
    4864              : {
    4865    225410123 :   tree result;
    4866    225410123 :   tree saved_fn = current_function_decl;
    4867              : 
    4868              :   /* We shouldn't be trying to mangle an uninstantiated template.  */
    4869    225410123 :   gcc_assert (!type_dependent_expression_p (decl));
    4870              : 
    4871    225410123 :   current_function_decl = NULL_TREE;
    4872    225410123 :   iloc_sentinel ils (DECL_SOURCE_LOCATION (decl));
    4873              : 
    4874    225410123 :   start_mangling (decl);
    4875              : 
    4876    225410123 :   if (TREE_CODE (decl) == TYPE_DECL)
    4877       340550 :     write_type (TREE_TYPE (decl));
    4878              :   else
    4879    225069573 :     write_mangled_name (decl, true);
    4880              : 
    4881    225410123 :   result = finish_mangling_get_identifier ();
    4882    225410123 :   if (DEBUG_MANGLE)
    4883              :     fprintf (stderr, "mangle_decl_string = '%s'\n\n",
    4884              :              IDENTIFIER_POINTER (result));
    4885              : 
    4886    225410123 :   current_function_decl = saved_fn;
    4887    225410123 :   return result;
    4888    225410123 : }
    4889              : 
    4890              : /* Return an identifier for the external mangled name of DECL.  */
    4891              : 
    4892              : static tree
    4893    168585554 : get_mangled_id (tree decl)
    4894              : {
    4895    168585554 :   tree id = mangle_decl_string (decl);
    4896    168585554 :   return targetm.mangle_decl_assembler_name (decl, id);
    4897              : }
    4898              : 
    4899              : /* Create an identifier for the external mangled name of DECL.  */
    4900              : 
    4901              : void
    4902    168594301 : mangle_decl (const tree decl)
    4903              : {
    4904    168594301 :   tree id;
    4905    168594301 :   bool dep;
    4906              : 
    4907              :   /* Don't bother mangling uninstantiated templates.  */
    4908    168594301 :   ++processing_template_decl;
    4909    168594301 :   if (TREE_CODE (decl) == TYPE_DECL)
    4910       341037 :     dep = dependent_type_p (TREE_TYPE (decl));
    4911              :   else
    4912    335180152 :     dep = (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
    4913    280413837 :            && any_dependent_template_arguments_p (DECL_TI_ARGS (decl)));
    4914    168594301 :   --processing_template_decl;
    4915    168594301 :   if (dep)
    4916              :     return;
    4917              : 
    4918              :   /* During LTO we keep mangled names of TYPE_DECLs for ODR type merging.
    4919              :      It is not needed to assign names to anonymous namespace, but we use the
    4920              :      "<anon>" marker to be able to tell if type is C++ ODR type or type
    4921              :      produced by other language.  */
    4922    168586041 :   if (TREE_CODE (decl) == TYPE_DECL
    4923       341037 :       && TYPE_STUB_DECL (TREE_TYPE (decl))
    4924    168916397 :       && !TREE_PUBLIC (TYPE_STUB_DECL (TREE_TYPE (decl))))
    4925          487 :     id = get_identifier ("<anon>");
    4926              :   else
    4927              :     {
    4928    168585554 :       gcc_assert (TREE_CODE (decl) != TYPE_DECL
    4929              :                   || !no_linkage_check (TREE_TYPE (decl), true));
    4930    168585554 :       if (abi_version_at_least (10))
    4931    168467516 :         if (tree fn = decl_function_context (decl))
    4932      3686417 :           maybe_check_abi_tags (fn, decl);
    4933    168585554 :       id = get_mangled_id (decl);
    4934              :     }
    4935    168586041 :   SET_DECL_ASSEMBLER_NAME (decl, id);
    4936              : 
    4937    168586041 :   if (G.need_cxx17_warning
    4938    168586041 :       && (TREE_PUBLIC (decl) || DECL_REALLY_EXTERN (decl)))
    4939           10 :     warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wnoexcept_type,
    4940              :                 "mangled name for %qD will change in C++17 because the "
    4941              :                 "exception specification is part of a function type",
    4942              :                 decl);
    4943              : 
    4944    168586041 :   if (id != DECL_NAME (decl)
    4945              :       /* Don't do this for a fake symbol we aren't going to emit anyway.  */
    4946    165959466 :       && TREE_CODE (decl) != TYPE_DECL
    4947    334204470 :       && !DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
    4948              :     {
    4949    144699630 :       int save_ver = flag_abi_version;
    4950    144699630 :       tree id2 = NULL_TREE;
    4951              : 
    4952    144699630 :       if (!DECL_REALLY_EXTERN (decl))
    4953              :         {
    4954     87134606 :           record_mangling (decl, G.need_abi_warning);
    4955              : 
    4956     87134606 :           if (!G.need_abi_warning)
    4957              :             return;
    4958              : 
    4959        38193 :           flag_abi_version = flag_abi_compat_version;
    4960        38193 :           id2 = mangle_decl_string (decl);
    4961        38193 :           id2 = targetm.mangle_decl_assembler_name (decl, id2);
    4962        38193 :           flag_abi_version = save_ver;
    4963              : 
    4964        38193 :           if (id2 != id)
    4965        38077 :             note_mangling_alias (decl, id2);
    4966              :         }
    4967              : 
    4968     57603217 :       if (warn_abi)
    4969              :         {
    4970     56786571 :           const char fabi_version[] = "-fabi-version";
    4971              : 
    4972     56786571 :           if (flag_abi_compat_version != warn_abi_version
    4973     56785844 :               || id2 == NULL_TREE)
    4974              :             {
    4975     56786376 :               flag_abi_version = warn_abi_version;
    4976     56786376 :               id2 = mangle_decl_string (decl);
    4977     56786376 :               id2 = targetm.mangle_decl_assembler_name (decl, id2);
    4978              :             }
    4979     56786571 :           flag_abi_version = save_ver;
    4980              : 
    4981     56786571 :           if (id2 == id)
    4982              :             /* OK.  */;
    4983          266 :           else if (warn_abi_version != 0
    4984          266 :                    && abi_version_at_least (warn_abi_version))
    4985          222 :             warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
    4986              :                         "the mangled name of %qD changed between "
    4987              :                         "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
    4988              :                         G.entity, fabi_version, warn_abi_version, id2,
    4989              :                         fabi_version, save_ver, id);
    4990              :           else
    4991           44 :             warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
    4992              :                         "the mangled name of %qD changes between "
    4993              :                         "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
    4994              :                         G.entity, fabi_version, save_ver, id,
    4995              :                         fabi_version, warn_abi_version, id2);
    4996              :         }
    4997              : 
    4998     57603217 :       flag_abi_version = save_ver;
    4999              :     }
    5000              : }
    5001              : 
    5002              : /* Generate the mangled representation of TYPE.  */
    5003              : 
    5004              : const char *
    5005       457708 : mangle_type_string (const tree type)
    5006              : {
    5007       457708 :   const char *result;
    5008              : 
    5009       457708 :   start_mangling (type);
    5010       457708 :   write_type (type);
    5011       457708 :   result = finish_mangling ();
    5012       457708 :   if (DEBUG_MANGLE)
    5013              :     fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
    5014       457708 :   return result;
    5015              : }
    5016              : 
    5017              : /* Create an identifier for the mangled name of a special component
    5018              :    for belonging to TYPE.  CODE is the ABI-specified code for this
    5019              :    component.  */
    5020              : 
    5021              : static tree
    5022      5853995 : mangle_special_for_type (const tree type, const char *code)
    5023              : {
    5024      5853995 :   tree result;
    5025              : 
    5026              :   /* We don't have an actual decl here for the special component, so
    5027              :      we can't just process the <encoded-name>.  Instead, fake it.  */
    5028      5853995 :   start_mangling (type);
    5029              : 
    5030              :   /* Start the mangling.  */
    5031      5853995 :   write_string ("_Z");
    5032      5853995 :   write_string (code);
    5033              : 
    5034              :   /* Add the type.  */
    5035      5853995 :   write_type (type);
    5036      5853995 :   result = finish_mangling_get_identifier ();
    5037              : 
    5038      5853995 :   if (DEBUG_MANGLE)
    5039              :     fprintf (stderr, "mangle_special_for_type = %s\n\n",
    5040              :              IDENTIFIER_POINTER (result));
    5041              : 
    5042      5853995 :   return result;
    5043              : }
    5044              : 
    5045              : /* Create an identifier for the mangled representation of the typeinfo
    5046              :    structure for TYPE.  */
    5047              : 
    5048              : tree
    5049      3348986 : mangle_typeinfo_for_type (const tree type)
    5050              : {
    5051      3348986 :   return mangle_special_for_type (type, "TI");
    5052              : }
    5053              : 
    5054              : /* Create an identifier for the mangled name of the NTBS containing
    5055              :    the mangled name of TYPE.  */
    5056              : 
    5057              : tree
    5058       449302 : mangle_typeinfo_string_for_type (const tree type)
    5059              : {
    5060       449302 :   return mangle_special_for_type (type, "TS");
    5061              : }
    5062              : 
    5063              : /* Create an identifier for the mangled name of the vtable for TYPE.  */
    5064              : 
    5065              : tree
    5066      1867417 : mangle_vtbl_for_type (const tree type)
    5067              : {
    5068      1867417 :   return mangle_special_for_type (type, "TV");
    5069              : }
    5070              : 
    5071              : /* Returns an identifier for the mangled name of the VTT for TYPE.  */
    5072              : 
    5073              : tree
    5074       188290 : mangle_vtt_for_type (const tree type)
    5075              : {
    5076       188290 :   return mangle_special_for_type (type, "TT");
    5077              : }
    5078              : 
    5079              : /* Returns an identifier for the mangled name of the decomposition
    5080              :    artificial variable DECL.  DECLS is the vector of the VAR_DECLs
    5081              :    for the identifier-list.  */
    5082              : 
    5083              : tree
    5084          897 : mangle_decomp (const tree decl, vec<tree> &decls)
    5085              : {
    5086          897 :   gcc_assert (!type_dependent_expression_p (decl));
    5087              : 
    5088          897 :   location_t saved_loc = input_location;
    5089          897 :   input_location = DECL_SOURCE_LOCATION (decl);
    5090              : 
    5091          897 :   check_abi_tags (decl);
    5092          897 :   start_mangling (decl);
    5093          897 :   write_string ("_Z");
    5094              : 
    5095          897 :   tree context = decl_mangling_context (decl);
    5096          897 :   gcc_assert (context != NULL_TREE);
    5097              : 
    5098          897 :   bool nested = false;
    5099          897 :   bool local = false;
    5100          897 :   if (DECL_NAMESPACE_STD_P (context))
    5101            9 :     write_string ("St");
    5102          888 :   else if (TREE_CODE (context) == FUNCTION_DECL)
    5103              :     {
    5104          269 :       local = true;
    5105          269 :       write_char ('Z');
    5106          269 :       write_encoding (context);
    5107          269 :       write_char ('E');
    5108              :     }
    5109          619 :   else if (context != global_namespace)
    5110              :     {
    5111          100 :       nested = true;
    5112          100 :       write_char ('N');
    5113          100 :       write_prefix (context);
    5114              :     }
    5115              : 
    5116          897 :   write_string ("DC");
    5117          897 :   unsigned int i;
    5118          897 :   tree d;
    5119         2966 :   FOR_EACH_VEC_ELT (decls, i, d)
    5120         2069 :     write_unqualified_name (d);
    5121          897 :   write_char ('E');
    5122              : 
    5123          897 :   if (tree tags = get_abi_tags (decl))
    5124              :     {
    5125              :       /* We didn't emit ABI tags for structured bindings before ABI 19.  */
    5126           30 :       if (!G.need_abi_warning
    5127           30 :           && TREE_PUBLIC (decl)
    5128          120 :           && abi_warn_or_compat_version_crosses (19))
    5129           30 :         G.need_abi_warning = 1;
    5130              : 
    5131           30 :       if (abi_version_at_least (19))
    5132           30 :         write_abi_tags (tags);
    5133              :     }
    5134              : 
    5135          897 :   if (nested)
    5136          100 :     write_char ('E');
    5137          797 :   else if (local && DECL_DISCRIMINATOR_P (decl))
    5138          269 :     write_discriminator (discriminator_for_local_entity (decl));
    5139              : 
    5140          897 :   tree id = finish_mangling_get_identifier ();
    5141          897 :   if (DEBUG_MANGLE)
    5142              :     fprintf (stderr, "mangle_decomp = '%s'\n\n",
    5143              :              IDENTIFIER_POINTER (id));
    5144              : 
    5145          897 :   input_location = saved_loc;
    5146              : 
    5147          897 :   if (warn_abi && G.need_abi_warning)
    5148              :     {
    5149            0 :       const char fabi_version[] = "-fabi-version";
    5150            0 :       tree id2 = id;
    5151            0 :       int save_ver = flag_abi_version;
    5152              : 
    5153            0 :       if (flag_abi_version != warn_abi_version)
    5154              :         {
    5155            0 :           flag_abi_version = warn_abi_version;
    5156            0 :           id2 = mangle_decomp (decl, decls);
    5157            0 :           flag_abi_version = save_ver;
    5158              :         }
    5159              : 
    5160            0 :       if (id2 == id)
    5161              :         /* OK.  */;
    5162            0 :       else if (warn_abi_version != 0
    5163            0 :                && abi_version_at_least (warn_abi_version))
    5164            0 :         warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
    5165              :                     "the mangled name of %qD changed between "
    5166              :                     "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
    5167              :                     G.entity, fabi_version, warn_abi_version, id2,
    5168              :                     fabi_version, save_ver, id);
    5169              :       else
    5170            0 :         warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi,
    5171              :                     "the mangled name of %qD changes between "
    5172              :                     "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)",
    5173              :                     G.entity, fabi_version, save_ver, id,
    5174              :                     fabi_version, warn_abi_version, id2);
    5175              :     }
    5176              : 
    5177          897 :   return id;
    5178              : }
    5179              : 
    5180              : /* Return an identifier for a construction vtable group.  TYPE is
    5181              :    the most derived class in the hierarchy; BINFO is the base
    5182              :    subobject for which this construction vtable group will be used.
    5183              : 
    5184              :    This mangling isn't part of the ABI specification; in the ABI
    5185              :    specification, the vtable group is dumped in the same COMDAT as the
    5186              :    main vtable, and is referenced only from that vtable, so it doesn't
    5187              :    need an external name.  For binary formats without COMDAT sections,
    5188              :    though, we need external names for the vtable groups.
    5189              : 
    5190              :    We use the production
    5191              : 
    5192              :     <special-name> ::= TC <type> <offset number> _ <base type>  */
    5193              : 
    5194              : tree
    5195       257799 : mangle_ctor_vtbl_for_type (const tree type, const tree binfo)
    5196              : {
    5197       257799 :   tree result;
    5198              : 
    5199       257799 :   start_mangling (type);
    5200              : 
    5201       257799 :   write_string ("_Z");
    5202       257799 :   write_string ("TC");
    5203       257799 :   write_type (type);
    5204       257799 :   write_integer_cst (BINFO_OFFSET (binfo));
    5205       257799 :   write_char ('_');
    5206       257799 :   write_type (BINFO_TYPE (binfo));
    5207              : 
    5208       257799 :   result = finish_mangling_get_identifier ();
    5209       257799 :   if (DEBUG_MANGLE)
    5210              :     fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n",
    5211              :              IDENTIFIER_POINTER (result));
    5212       257799 :   return result;
    5213              : }
    5214              : 
    5215              : /* Mangle a this pointer or result pointer adjustment.
    5216              : 
    5217              :    <call-offset> ::= h <fixed offset number> _
    5218              :                  ::= v <fixed offset number> _ <virtual offset number> _ */
    5219              : 
    5220              : static void
    5221       492834 : mangle_call_offset (const tree fixed_offset, const tree virtual_offset)
    5222              : {
    5223       492834 :   write_char (virtual_offset ? 'v' : 'h');
    5224              : 
    5225              :   /* For either flavor, write the fixed offset.  */
    5226       492834 :   write_integer_cst (fixed_offset);
    5227       492834 :   write_char ('_');
    5228              : 
    5229              :   /* For a virtual thunk, add the virtual offset.  */
    5230       492834 :   if (virtual_offset)
    5231              :     {
    5232       369000 :       write_integer_cst (virtual_offset);
    5233       369000 :       write_char ('_');
    5234              :     }
    5235       492834 : }
    5236              : 
    5237              : /* Return an identifier for the mangled name of a this-adjusting or
    5238              :    covariant thunk to FN_DECL.  FIXED_OFFSET is the initial adjustment
    5239              :    to this used to find the vptr.  If VIRTUAL_OFFSET is non-NULL, this
    5240              :    is a virtual thunk, and it is the vtbl offset in
    5241              :    bytes. THIS_ADJUSTING is nonzero for a this adjusting thunk and
    5242              :    zero for a covariant thunk. Note, that FN_DECL might be a covariant
    5243              :    thunk itself. A covariant thunk name always includes the adjustment
    5244              :    for the this pointer, even if there is none.
    5245              : 
    5246              :    <special-name> ::= T <call-offset> <base encoding>
    5247              :                   ::= Tc <this_adjust call-offset> <result_adjust call-offset>
    5248              :                                         <base encoding>  */
    5249              : 
    5250              : tree
    5251       492447 : mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
    5252              :               tree virtual_offset, tree thunk)
    5253              : {
    5254       492447 :   tree result;
    5255              : 
    5256       492447 :   if (abi_version_at_least (11))
    5257       492444 :     maybe_check_abi_tags (fn_decl, thunk, 11);
    5258              : 
    5259       492447 :   start_mangling (fn_decl);
    5260              : 
    5261       492447 :   write_string ("_Z");
    5262       492447 :   write_char ('T');
    5263              : 
    5264       492447 :   if (!this_adjusting)
    5265              :     {
    5266              :       /* Covariant thunk with no this adjustment */
    5267          217 :       write_char ('c');
    5268          217 :       mangle_call_offset (integer_zero_node, NULL_TREE);
    5269          217 :       mangle_call_offset (fixed_offset, virtual_offset);
    5270              :     }
    5271       492230 :   else if (!DECL_THUNK_P (fn_decl))
    5272              :     /* Plain this adjusting thunk.  */
    5273       492060 :     mangle_call_offset (fixed_offset, virtual_offset);
    5274              :   else
    5275              :     {
    5276              :       /* This adjusting thunk to covariant thunk.  */
    5277          170 :       write_char ('c');
    5278          170 :       mangle_call_offset (fixed_offset, virtual_offset);
    5279          170 :       fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl));
    5280          170 :       virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl);
    5281          170 :       if (virtual_offset)
    5282          124 :         virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
    5283          170 :       mangle_call_offset (fixed_offset, virtual_offset);
    5284          170 :       fn_decl = THUNK_TARGET (fn_decl);
    5285              :     }
    5286              : 
    5287              :   /* Scoped name.  */
    5288       492447 :   write_encoding (fn_decl);
    5289              : 
    5290       492447 :   result = finish_mangling_get_identifier ();
    5291       492447 :   if (DEBUG_MANGLE)
    5292              :     fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result));
    5293       492447 :   return result;
    5294              : }
    5295              : 
    5296              : /* Handle ABI backwards compatibility for past bugs where we didn't call
    5297              :    check_abi_tags in places where it's needed: call check_abi_tags and warn if
    5298              :    it makes a difference.  If FOR_DECL is non-null, it's the declaration
    5299              :    that we're actually trying to mangle; if it's null, we're mangling the
    5300              :    guard variable for T.  */
    5301              : 
    5302              : static void
    5303      4183863 : maybe_check_abi_tags (tree t, tree for_decl, int ver)
    5304              : {
    5305      4183863 :   if (DECL_ASSEMBLER_NAME_SET_P (t))
    5306              :     return;
    5307              : 
    5308       828490 :   tree oldtags = get_abi_tags (t);
    5309              : 
    5310       828490 :   mangle_decl (t);
    5311              : 
    5312       828490 :   tree newtags = get_abi_tags (t);
    5313       828490 :   if (newtags && newtags != oldtags
    5314           48 :       && abi_version_crosses (ver))
    5315              :     {
    5316           12 :       if (for_decl && DECL_THUNK_P (for_decl))
    5317            3 :         warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
    5318              :                     "the mangled name of a thunk for %qD changes between "
    5319              :                     "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
    5320              :                     t, flag_abi_version, warn_abi_version);
    5321            9 :       else if (for_decl)
    5322            6 :         warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi,
    5323              :                     "the mangled name of %qD changes between "
    5324              :                     "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
    5325              :                     for_decl, flag_abi_version, warn_abi_version);
    5326              :       else
    5327            3 :         warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
    5328              :                     "the mangled name of the initialization guard variable "
    5329              :                     "for %qD changes between %<-fabi-version=%d%> and "
    5330              :                     "%<-fabi-version=%d%>",
    5331              :                     t, flag_abi_version, warn_abi_version);
    5332              :     }
    5333              : }
    5334              : 
    5335              : /* Write out the appropriate string for this variable when generating
    5336              :    another mangled name based on this one.  */
    5337              : 
    5338              : static void
    5339         7776 : write_guarded_var_name (const tree variable)
    5340              : {
    5341         7776 :   if (DECL_NAME (variable)
    5342         7776 :       && startswith (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR"))
    5343              :     /* The name of a guard variable for a reference temporary should refer
    5344              :        to the reference, not the temporary.  */
    5345            6 :     write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
    5346         7770 :   else if (DECL_DECOMPOSITION_P (variable)
    5347          751 :            && DECL_NAME (variable) == NULL_TREE
    5348         8042 :            && startswith (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)),
    5349              :                           "_Z"))
    5350              :     /* The name of a guard variable for a structured binding needs special
    5351              :        casing.  */
    5352          272 :     write_string (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)) + 2);
    5353              :   else
    5354         7498 :     write_name (variable);
    5355         7776 : }
    5356              : 
    5357              : /* Return an identifier for the name of an initialization guard
    5358              :    variable for indicated VARIABLE.  */
    5359              : 
    5360              : tree
    5361         5008 : mangle_guard_variable (const tree variable)
    5362              : {
    5363         5008 :   if (abi_version_at_least (10))
    5364         5002 :     maybe_check_abi_tags (variable);
    5365         5008 :   start_mangling (variable);
    5366         5008 :   write_string ("_ZGV");
    5367         5008 :   write_guarded_var_name (variable);
    5368         5008 :   return finish_mangling_get_identifier ();
    5369              : }
    5370              : 
    5371              : /* Return an identifier for the name of a thread_local initialization
    5372              :    function for VARIABLE.  */
    5373              : 
    5374              : tree
    5375         1190 : mangle_tls_init_fn (const tree variable)
    5376              : {
    5377         1190 :   check_abi_tags (variable);
    5378         1190 :   start_mangling (variable);
    5379         1190 :   write_string ("_ZTH");
    5380         1190 :   write_guarded_var_name (variable);
    5381         1190 :   return finish_mangling_get_identifier ();
    5382              : }
    5383              : 
    5384              : /* Return an identifier for the name of a thread_local wrapper
    5385              :    function for VARIABLE.  */
    5386              : 
    5387              : #define TLS_WRAPPER_PREFIX "_ZTW"
    5388              : 
    5389              : tree
    5390          749 : mangle_tls_wrapper_fn (const tree variable)
    5391              : {
    5392          749 :   check_abi_tags (variable);
    5393          749 :   start_mangling (variable);
    5394          749 :   write_string (TLS_WRAPPER_PREFIX);
    5395          749 :   write_guarded_var_name (variable);
    5396          749 :   return finish_mangling_get_identifier ();
    5397              : }
    5398              : 
    5399              : /* Return true iff FN is a thread_local wrapper function.  */
    5400              : 
    5401              : bool
    5402      2517444 : decl_tls_wrapper_p (const tree fn)
    5403              : {
    5404      2517444 :   if (TREE_CODE (fn) != FUNCTION_DECL)
    5405              :     return false;
    5406      2142949 :   tree name = DECL_NAME (fn);
    5407      2142949 :   return startswith (IDENTIFIER_POINTER (name), TLS_WRAPPER_PREFIX);
    5408              : }
    5409              : 
    5410              : /* Return an identifier for the name of a temporary variable used to
    5411              :    initialize a static reference.  This is now part of the ABI.  */
    5412              : 
    5413              : tree
    5414          829 : mangle_ref_init_variable (const tree variable)
    5415              : {
    5416          829 :   start_mangling (variable);
    5417          829 :   write_string ("_ZGR");
    5418          829 :   check_abi_tags (variable);
    5419          829 :   write_guarded_var_name (variable);
    5420              :   /* Avoid name clashes with aggregate initialization of multiple
    5421              :      references at once.  */
    5422          829 :   write_compact_number (current_ref_temp_count++);
    5423          829 :   return finish_mangling_get_identifier ();
    5424              : }
    5425              : 
    5426              : /* Return an identifier for the mangled name of a C++20 template parameter
    5427              :    object for template argument EXPR.  */
    5428              : 
    5429              : tree
    5430        67815 : mangle_template_parm_object (tree expr)
    5431              : {
    5432        67815 :   start_mangling (expr);
    5433        67815 :   write_string ("_ZTAX");
    5434        67815 :   write_expression (expr);
    5435        67815 :   write_char ('E');
    5436        67815 :   return finish_mangling_get_identifier ();
    5437              : }
    5438              : 
    5439              : /* Given a CLASS_TYPE, such as a record for std::bad_exception this
    5440              :    function generates a mangled name for the vtable map variable of
    5441              :    the class type.  For example, if the class type is
    5442              :    "std::bad_exception", the mangled name for the class is
    5443              :    "St13bad_exception".  This function would generate the name
    5444              :    "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as:
    5445              :    "_VTV<std::bad_exception>::__vtable_map".  */
    5446              : 
    5447              : 
    5448              : char *
    5449            6 : get_mangled_vtable_map_var_name (tree class_type)
    5450              : {
    5451            6 :   char *var_name = NULL;
    5452            6 :   const char *prefix = "_ZN4_VTVI";
    5453            6 :   const char *postfix = "E12__vtable_mapE";
    5454              : 
    5455            6 :   gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
    5456              : 
    5457            6 :   tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));
    5458              : 
    5459            6 :   if (strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL)
    5460              :     {
    5461            0 :       class_id = get_mangled_id (TYPE_NAME (class_type));
    5462            0 :       vtbl_register_mangled_name (TYPE_NAME (class_type), class_id);
    5463              :     }
    5464              : 
    5465            6 :   unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
    5466              :                      strlen (prefix) +
    5467            6 :                      strlen (postfix) + 1;
    5468              : 
    5469            6 :   var_name = (char *) xmalloc (len);
    5470              : 
    5471            6 :   sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), postfix);
    5472              : 
    5473            6 :   return var_name;
    5474              : }
    5475              : 
    5476              : #include "gt-cp-mangle.h"
        

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.