+/* Encode 0 as _, and 1+ as n-1_. */
+
+static void
+write_compact_number (int num)
+{
+ if (num > 0)
+ write_unsigned_number (num - 1);
+ write_char ('_');
+}
+
+/* Return how many unnamed types precede TYPE in its enclosing class. */
+
+static int
+nested_anon_class_index (tree type)
+{
+ int index = 0;
+ tree member = TYPE_FIELDS (TYPE_CONTEXT (type));
+ for (; member; member = TREE_CHAIN (member))
+ if (DECL_IMPLICIT_TYPEDEF_P (member))
+ {
+ tree memtype = TREE_TYPE (member);
+ if (memtype == type)
+ return index;
+ else if (TYPE_ANONYMOUS_P (memtype))
+ ++index;
+ }
+
+ gcc_unreachable ();
+}
+
+/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
+
+static void
+write_unnamed_type_name (const tree type __attribute__ ((__unused__)))
+{
+ int discriminator;
+ MANGLE_TRACE_TREE ("unnamed-type-name", type);
+
+ if (TYPE_FUNCTION_SCOPE_P (type))
+ discriminator = local_class_index (type);
+ else if (TYPE_CLASS_SCOPE_P (type))
+ discriminator = nested_anon_class_index (type);
+ else
+ {
+ gcc_assert (no_linkage_check (type, /*relaxed_p=*/true));
+ /* Just use the old mangling at namespace scope. */
+ write_source_name (TYPE_IDENTIFIER (type));
+ return;
+ }
+
+ write_string ("Ut");
+ write_compact_number (discriminator);
+}
+
+/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
+ <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters */
+
+static void
+write_closure_type_name (const tree type)
+{
+ tree fn = lambda_function (type);
+ tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+ MANGLE_TRACE_TREE ("closure-type-name", type);
+
+ write_string ("Ul");
+ write_method_parms (parms, DECL_NONSTATIC_MEMBER_FUNCTION_P (fn), fn);
+ write_char ('E');
+ write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
+}
+