@@ -396,7 +396,15 @@ enum demangle_component_type
/* An unnamed type. */
DEMANGLE_COMPONENT_UNNAMED_TYPE,
/* A pack expansion. */
- DEMANGLE_COMPONENT_PACK_EXPANSION
+ DEMANGLE_COMPONENT_PACK_EXPANSION,
+ /* An old-style constant-propagation clone. */
+ DEMANGLE_COMPONENT_CLONE,
+ /* A constant-propagation clone. */
+ DEMANGLE_COMPONENT_CONSTPROP_CLONE,
+ /* An inter-procedural SRA clone. */
+ DEMANGLE_COMPONENT_ISRA_CLONE,
+ /* A partial inlining clone. */
+ DEMANGLE_COMPONENT_PART_CLONE
};
/* Types which are only used internally. */
@@ -208,6 +208,19 @@ static void d_init_info (const char *, int, size_t, struct d_info *);
#define ANONYMOUS_NAMESPACE_PREFIX_LEN \
(sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)
+/* Suffixes that may be appended to a mangled name to indicate
+ a cloned function. */
+
+struct clone_suffix_list
+{
+ /* The suffix. */
+ const char *suffix;
+ /* The length of the suffix. */
+ int suffix_len;
+ /* The component type to represent the clone. */
+ enum demangle_component_type type;
+};
+
/* Information we keep for the standard substitutions. */
struct d_standard_sub_info
@@ -419,6 +432,9 @@ static struct demangle_component *d_lambda (struct d_info *);
static struct demangle_component *d_unnamed_type (struct d_info *);
+static struct demangle_component *
+d_clone_suffix (struct d_info *, struct demangle_component *);
+
static int
d_add_substitution (struct d_info *, struct demangle_component *);
@@ -804,6 +820,10 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
case DEMANGLE_COMPONENT_LITERAL_NEG:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
+ case DEMANGLE_COMPONENT_CLONE:
+ case DEMANGLE_COMPONENT_CONSTPROP_CLONE:
+ case DEMANGLE_COMPONENT_ISRA_CLONE:
+ case DEMANGLE_COMPONENT_PART_CLONE:
if (left == NULL || right == NULL)
return NULL;
break;
@@ -1036,7 +1056,7 @@ d_make_sub (struct d_info *di, const char *name, int len)
return p;
}
-/* <mangled-name> ::= _Z <encoding>
+/* <mangled-name> ::= _Z <encoding> [<clone-suffix>]
TOP_LEVEL is non-zero when called at the top level. */
@@ -1044,6 +1064,8 @@ CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
+ struct demangle_component *p;
+
if (! d_check_char (di, '_')
/* Allow missing _ if not at toplevel to work around a
bug in G++ abi-version=2 mangling; see the comment in
@@ -1052,7 +1074,16 @@ cplus_demangle_mangled_name (struct d_info *di, int top_level)
return NULL;
if (! d_check_char (di, 'Z'))
return NULL;
- return d_encoding (di, top_level);
+ p = d_encoding (di, top_level);
+
+ /* If at top level and parsing parameters, check for a clone
+ suffix. */
+ if (top_level &&
+ ((di->options & DMGL_PARAMS) != 0)
+ && d_peek_char (di) == '.')
+ p = d_clone_suffix (di, p);
+
+ return p;
}
/* Return whether a function should have a return type. The argument
@@ -2346,7 +2377,7 @@ d_parmlist (struct d_info *di)
struct demangle_component *type;
char peek = d_peek_char (di);
- if (peek == '\0' || peek == 'E')
+ if (peek == '\0' || peek == 'E' || peek == '.')
break;
type = cplus_demangle_type (di);
if (type == NULL)
@@ -3066,6 +3097,47 @@ d_unnamed_type (struct d_info *di)
return ret;
}
+/* <clone-suffix> ::= .clone. <nonnegative number>
+ ::= .constprop. <nonnegative number>
+ ::= .isra. <nonnegative number>
+ ::= .part. <nonnegative number>
+*/
+
+static const struct clone_suffix_list clone_suffixes[] =
+{
+ { NL (".clone."), DEMANGLE_COMPONENT_CLONE },
+ { NL (".constprop."), DEMANGLE_COMPONENT_CONSTPROP_CLONE },
+ { NL (".isra."), DEMANGLE_COMPONENT_ISRA_CLONE },
+ { NL (".part."), DEMANGLE_COMPONENT_PART_CLONE },
+};
+
+static struct demangle_component *
+d_clone_suffix (struct d_info *di, struct demangle_component *encoding)
+{
+ const char *suffix;
+ const struct clone_suffix_list *p;
+ const struct clone_suffix_list *pend;
+
+ suffix = d_str (di);
+ pend = (&clone_suffixes[0]
+ + sizeof clone_suffixes / sizeof clone_suffixes[0]);
+ for (p = &clone_suffixes[0]; p < pend; ++p)
+ {
+ if (strncmp (suffix, p->suffix, p->suffix_len) == 0)
+ {
+ struct demangle_component *n;
+
+ if (! IS_DIGIT (suffix[p->suffix_len]))
+ return encoding;
+ d_advance (di, p->suffix_len);
+ n = d_number_component (di);
+ return d_make_comp (di, p->type, encoding, n);
+ }
+ }
+
+ return encoding;
+}
+
/* Add a new substitution. */
static int
@@ -4343,6 +4415,34 @@ d_print_comp (struct d_print_info *dpi,
d_append_char (dpi, '}');
return;
+ case DEMANGLE_COMPONENT_CLONE:
+ d_print_comp (dpi, d_left (dc));
+ d_append_string (dpi, " [clone #");
+ d_print_comp (dpi, d_right (dc));
+ d_append_char (dpi, ']');
+ return;
+
+ case DEMANGLE_COMPONENT_CONSTPROP_CLONE:
+ d_print_comp (dpi, d_left (dc));
+ d_append_string (dpi, " [CP clone #");
+ d_print_comp (dpi, d_right (dc));
+ d_append_char (dpi, ']');
+ return;
+
+ case DEMANGLE_COMPONENT_ISRA_CLONE:
+ d_print_comp (dpi, d_left (dc));
+ d_append_string (dpi, " [ISRA clone #");
+ d_print_comp (dpi, d_right (dc));
+ d_append_char (dpi, ']');
+ return;
+
+ case DEMANGLE_COMPONENT_PART_CLONE:
+ d_print_comp (dpi, d_left (dc));
+ d_append_string (dpi, " [partial inlining clone #");
+ d_print_comp (dpi, d_right (dc));
+ d_append_char (dpi, ']');
+ return;
+
default:
d_print_error (dpi);
return;
@@ -4092,3 +4092,30 @@ DFA
--format=auto
_ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_
Psi::VariantDetail::SelectVisitorResult<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>::type Psi::Variant<char, char const*>::visit<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&&&)...)
+#
+# Clone suffix tests
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.clone.1
+fo5(__int128) [clone #1]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.constprop.2
+fo5(__int128) [CP clone #2]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.isra.3
+fo5(__int128) [ISRA clone #3]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.part.4
+fo5(__int128) [partial inlining clone #4]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z12to_be_clonediPv.clone.0
+to_be_cloned(int, void*) [clone #0]
+to_be_cloned