diff options
| -rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 40 | ||||
| -rw-r--r-- | libcxxabi/test/test_demangle.cpp | 2 |
2 files changed, 31 insertions, 11 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 2ad832ad5e2..ff28c79bee3 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -38,7 +38,8 @@ template <class C> template <class C> const char* parse_encoding(const char* first, const char* last, C& db); template <class C> - const char* parse_name(const char* first, const char* last, C& db); + const char* parse_name(const char* first, const char* last, C& db, + bool* ends_with_template_args = 0); template <class C> const char* parse_expression(const char* first, const char* last, C& db); template <class C> @@ -3897,7 +3898,8 @@ parse_template_args(const char* first, const char* last, C& db) template <class C> const char* -parse_nested_name(const char* first, const char* last, C& db) +parse_nested_name(const char* first, const char* last, C& db, + bool* ends_with_template_args) { if (first != last && *first == 'N') { @@ -3928,8 +3930,10 @@ parse_nested_name(const char* first, const char* last, C& db) return first; } bool pop_subs = false; + bool component_ends_with_template_args = false; while (*t0 != 'E') { + component_ends_with_template_args = false; const char* t1; switch (*t0) { @@ -3999,6 +4003,7 @@ parse_nested_name(const char* first, const char* last, C& db) db.names.back().first += name; db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); t0 = t1; + component_ends_with_template_args = true; } else return first; @@ -4030,6 +4035,8 @@ parse_nested_name(const char* first, const char* last, C& db) db.cv = cv; if (pop_subs && !db.subs.empty()) db.subs.pop_back(); + if (ends_with_template_args) + *ends_with_template_args = component_ends_with_template_args; } return first; } @@ -4077,7 +4084,8 @@ parse_discriminator(const char* first, const char* last) template <class C> const char* -parse_local_name(const char* first, const char* last, C& db) +parse_local_name(const char* first, const char* last, C& db, + bool* ends_with_template_args) { if (first != last && *first == 'Z') { @@ -4099,7 +4107,8 @@ parse_local_name(const char* first, const char* last, C& db) if (t1 != last && *t1 == '_') { t = t1 + 1; - t1 = parse_name(t, last, db); + t1 = parse_name(t, last, db, + ends_with_template_args); if (t1 != t) { if (db.names.size() < 2) @@ -4117,7 +4126,8 @@ parse_local_name(const char* first, const char* last, C& db) break; default: { - const char* t1 = parse_name(t, last, db); + const char* t1 = parse_name(t, last, db, + ends_with_template_args); if (t1 != t) { // parse but ignore discriminator @@ -4149,7 +4159,8 @@ parse_local_name(const char* first, const char* last, C& db) template <class C> const char* -parse_name(const char* first, const char* last, C& db) +parse_name(const char* first, const char* last, C& db, + bool* ends_with_template_args) { if (last - first >= 2) { @@ -4161,14 +4172,16 @@ parse_name(const char* first, const char* last, C& db) { case 'N': { - const char* t1 = parse_nested_name(t0, last, db); + const char* t1 = parse_nested_name(t0, last, db, + ends_with_template_args); if (t1 != t0) first = t1; break; } case 'Z': { - const char* t1 = parse_local_name(t0, last, db); + const char* t1 = parse_local_name(t0, last, db, + ends_with_template_args); if (t1 != t0) first = t1; break; @@ -4193,6 +4206,8 @@ parse_name(const char* first, const char* last, C& db) db.names.pop_back(); db.names.back().first += tmp; first = t1; + if (ends_with_template_args) + *ends_with_template_args = true; } } else // <unscoped-name> @@ -4213,6 +4228,8 @@ parse_name(const char* first, const char* last, C& db) db.names.pop_back(); db.names.back().first += tmp; first = t1; + if (ends_with_template_args) + *ends_with_template_args = true; } } } @@ -4476,7 +4493,9 @@ parse_encoding(const char* first, const char* last, C& db) break; default: { - const char* t = parse_name(first, last, db); + bool ends_with_template_args = false; + const char* t = parse_name(first, last, db, + &ends_with_template_args); unsigned cv = db.cv; unsigned ref = db.ref; if (t != first) @@ -4492,8 +4511,7 @@ parse_encoding(const char* first, const char* last, C& db) const typename C::String& nm = db.names.back().first; if (nm.empty()) return first; - if (!db.parsed_ctor_dtor_cv && nm.back() == '>' && nm[nm.size()-2] != '-' - && nm[nm.size()-2] != '>') + if (!db.parsed_ctor_dtor_cv && ends_with_template_args) { t2 = parse_type(t, last, db); if (t2 == t) diff --git a/libcxxabi/test/test_demangle.cpp b/libcxxabi/test/test_demangle.cpp index e00c9138b55..15cb3a14dae 100644 --- a/libcxxabi/test/test_demangle.cpp +++ b/libcxxabi/test/test_demangle.cpp @@ -24,6 +24,8 @@ const char* cases[][2] = {"_Z1A1B1C", "A(B, C)"}, {"_Z4testI1A1BE1Cv", "C test<A, B>()"}, {"_Z4testI1A1BET0_T_S3_", "B test<A, B>(A, A)"}, + {"_ZN1SgtEi", "S::operator>(int)"}, + {"_ZrsI1QEiT_i", "int operator>><Q>(Q, int)"}, {"_ZN13dyldbootstrap5startEPK12macho_headeriPPKcl", "dyldbootstrap::start(macho_header const*, int, char const**, long)"}, {"_ZN4dyld17getExecutablePathEv", "dyld::getExecutablePath()"}, {"_ZN4dyld22mainExecutablePreboundEv", "dyld::mainExecutablePrebound()"}, |

