diff mbox

[libiberty] Add demangler support for cloned function symbols (PR 40831)

Message ID CAHACq4pgXSgvvQfgkfUQMYMc+N3eNMqHcJDs3NKctcHUJHpG6A@mail.gmail.com
State New
Headers show

Commit Message

Cary Coutant Aug. 20, 2011, 12:57 a.m. UTC
> OK, thanks. Dmitry G. also commented that the patch does not work "for
> `_Z3fooi.1988' or `_Z3fooi.part.9.165493.constprop.775.31805'."
> Apparently, there can be multiple numeric suffixes, and a cloned
> function can be cloned again. Is it worth trying to identify the kinds
> of cloning in the demangled name, or should I just look for a generic
> pattern instead?

Here's an updated patch that generalizes the clone suffix pattern recognition.

Does this look OK for trunk?

I've bootstrapped and regression tested on x86_64.

-cary


2011-08-19   Cary Coutant  <ccoutant@google.com>

	* include/demangle.h (enum demangle_component_type):
	* libiberty/cp-demangle.c (struct d_info):
	(CP_STATIC_IF_GLIBCPP_V3):
	(struct d_print_info):
	* libiberty/testsuite/demangle-expected (DFA):

include/ChangeLog:

	PR 40831
	* demangle.h (enum demangle_component_type): Add
	DEMANGLE_COMPONENT_CLONE.

libiberty/ChangeLog:

	PR 40831
	* cp-demangle.c (d_make_comp): Add new component type.
	(cplus_demangle_mangled_name): Check for clone suffixes.
	(d_parmlist): Don't error out if we see '.'.
	(d_clone_suffix): New function.
	(d_print_comp): Print info for clone suffixes.
	* testsuite/demangle-expected: Add new testcases.
2011-08-19   Cary Coutant  <ccoutant@google.com>

	* include/demangle.h (enum demangle_component_type):
	* libiberty/cp-demangle.c (struct d_info):
	(CP_STATIC_IF_GLIBCPP_V3):
	(struct d_print_info):
	* libiberty/testsuite/demangle-expected (DFA):

include/ChangeLog:

	PR 40831
	* demangle.h (enum demangle_component_type): Add
	DEMANGLE_COMPONENT_CLONE.

libiberty/ChangeLog:

	PR 40831
	* cp-demangle.c (d_make_comp): Add new component type.
	(cplus_demangle_mangled_name): Check for clone suffixes.
	(d_parmlist): Don't error out if we see '.'.
	(d_clone_suffix): New function.
	(d_print_comp): Print info for clone suffixes.
	* testsuite/demangle-expected: Add new testcases.


commit 69ffd5c629215428cf817dfd11bc4fc5f7d07715
Author: Cary Coutant <ccoutant@google.com>
Date:   Thu Apr 7 17:36:13 2011 -0700

    Demangle cloned function names.

Comments

Cary Coutant Sept. 1, 2011, 6:39 p.m. UTC | #1
Ping?

http://gcc.gnu.org/ml/gcc-patches/2011-08/msg01626.html

-cary

On Fri, Aug 19, 2011 at 5:57 PM, Cary Coutant <ccoutant@google.com> wrote:
>> OK, thanks. Dmitry G. also commented that the patch does not work "for
>> `_Z3fooi.1988' or `_Z3fooi.part.9.165493.constprop.775.31805'."
>> Apparently, there can be multiple numeric suffixes, and a cloned
>> function can be cloned again. Is it worth trying to identify the kinds
>> of cloning in the demangled name, or should I just look for a generic
>> pattern instead?
>
> Here's an updated patch that generalizes the clone suffix pattern recognition.
>
> Does this look OK for trunk?
>
> I've bootstrapped and regression tested on x86_64.
>
> -cary
>
>
> 2011-08-19   Cary Coutant  <ccoutant@google.com>
>
>        * include/demangle.h (enum demangle_component_type):
>        * libiberty/cp-demangle.c (struct d_info):
>        (CP_STATIC_IF_GLIBCPP_V3):
>        (struct d_print_info):
>        * libiberty/testsuite/demangle-expected (DFA):
>
> include/ChangeLog:
>
>        PR 40831
>        * demangle.h (enum demangle_component_type): Add
>        DEMANGLE_COMPONENT_CLONE.
>
> libiberty/ChangeLog:
>
>        PR 40831
>        * cp-demangle.c (d_make_comp): Add new component type.
>        (cplus_demangle_mangled_name): Check for clone suffixes.
>        (d_parmlist): Don't error out if we see '.'.
>        (d_clone_suffix): New function.
>        (d_print_comp): Print info for clone suffixes.
>        * testsuite/demangle-expected: Add new testcases.
>
Cary Coutant Sept. 8, 2011, 10:04 p.m. UTC | #2
Ping?

http://gcc.gnu.org/ml/gcc-patches/2011-08/msg01626.html

-cary


include/ChangeLog:

       PR 40831
       * demangle.h (enum demangle_component_type): Add
       DEMANGLE_COMPONENT_CLONE.

libiberty/ChangeLog:

       PR 40831
       * cp-demangle.c (d_make_comp): Add new component type.
       (cplus_demangle_mangled_name): Check for clone suffixes.
       (d_parmlist): Don't error out if we see '.'.
       (d_clone_suffix): New function.
       (d_print_comp): Print info for clone suffixes.
       * testsuite/demangle-expected: Add new testcases.
diff mbox

Patch

diff --git a/include/demangle.h b/include/demangle.h
index 53f6c54..960e88e 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -402,7 +402,9 @@  enum demangle_component_type
   /* An unnamed type.  */
   DEMANGLE_COMPONENT_UNNAMED_TYPE,
   /* A pack expansion.  */
-  DEMANGLE_COMPONENT_PACK_EXPANSION
+  DEMANGLE_COMPONENT_PACK_EXPANSION,
+  /* A cloned function.  */
+  DEMANGLE_COMPONENT_CLONE
 };
 
 /* Types which are only used internally.  */
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index d67a9e7..11da407 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -417,6 +417,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 *);
 
@@ -802,6 +805,7 @@  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:
       if (left == NULL || right == NULL)
 	return NULL;
       break;
@@ -1034,7 +1038,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.  */
 
@@ -1042,6 +1046,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
@@ -1050,7 +1056,17 @@  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)
+    while (d_peek_char (di) == '.'
+	   && (IS_LOWER (d_peek_next_char (di))
+	       || IS_DIGIT (d_peek_next_char (di))))
+      p = d_clone_suffix (di, p);
+
+  return p;
 }
 
 /* Return whether a function should have a return type.  The argument
@@ -2354,7 +2370,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)
@@ -3082,6 +3098,33 @@  d_unnamed_type (struct d_info *di)
   return ret;
 }
 
+/* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
+*/
+
+static struct demangle_component *
+d_clone_suffix (struct d_info *di, struct demangle_component *encoding)
+{
+  const char *suffix = d_str (di);
+  const char *pend = suffix;
+  struct demangle_component *n;
+
+  if (*pend == '.' && IS_LOWER (pend[1]))
+    {
+      pend += 2;
+      while (IS_LOWER (*pend) || *pend == '_')
+	++pend;
+    }
+  while (*pend == '.' && IS_DIGIT (pend[1]))
+    {
+      pend += 2;
+      while (IS_DIGIT (*pend))
+	++pend;
+    }
+  d_advance (di, pend - suffix);
+  n = d_make_name (di, suffix, pend - suffix);
+  return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n);
+}
+
 /* Add a new substitution.  */
 
 static int
@@ -4463,6 +4506,13 @@  d_print_comp (struct d_print_info *dpi, int options,
       d_append_char (dpi, '}');
       return;
 
+    case DEMANGLE_COMPONENT_CLONE:
+      d_print_comp (dpi, options, d_left (dc));
+      d_append_string (dpi, " [clone ");
+      d_print_comp (dpi, options, d_right (dc));
+      d_append_char (dpi, ']');
+      return;
+
     default:
       d_print_error (dpi);
       return;
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 3737cfd..ebc5ce0 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4151,3 +4151,40 @@  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 .clone.1]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.constprop.2
+fo5(__int128) [clone .constprop.2]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.isra.3
+fo5(__int128) [clone .isra.3]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z3fo5n.part.4
+fo5(__int128) [clone .part.4]
+fo5
+#
+--format=gnu-v3 --no-params
+_Z12to_be_clonediPv.clone.0
+to_be_cloned(int, void*) [clone .clone.0]
+to_be_cloned
+#
+--format=gnu-v3 --no-params
+_Z3fooi.1988
+foo(int) [clone .1988]
+foo
+#
+--format=gnu-v3 --no-params
+_Z3fooi.part.9.165493.constprop.775.31805
+foo(int) [clone .part.9.165493] [clone .constprop.775.31805]
+foo