diff options
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 10 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 57 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 47 |
3 files changed, 111 insertions, 3 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 672d0ec..917a2f8 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,13 @@ +2011-09-23 Cary Coutant <ccoutant@google.com> + + 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-09-23 Ian Lance Taylor <iant@google.com> * md5.c (md5_process_bytes): Correct handling of unaligned diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index d67a9e7..32318e8 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,18 @@ 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)) + || 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 +2371,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 +3099,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[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 +4507,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..64ccb92 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4151,3 +4151,50 @@ 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 +# +--format=gnu-v3 --no-params +_Z2f1IiEvT_S0_S0_._omp_fn.2 +void f1<int>(int, int, int) [clone ._omp_fn.2] +f1<int> +# +--format=gnu-v3 --no-params +_Z3fooi._omp_cpyfn.6 +foo(int) [clone ._omp_cpyfn.6] +foo |