Author: epilk Date: Mon Feb 12 16:15:46 2018 New Revision: 324968 URL: http://llvm.org/viewvc/llvm-project?rev=324968&view=rev Log: [demangler] All <qualifiers> on one type should share one entry in the substitution table.
Previously, both <extended-qualifier>s and <CV-qualifiers> got their own entries. Modified: libcxxabi/trunk/src/cxa_demangle.cpp libcxxabi/trunk/test/test_demangle.pass.cpp Modified: libcxxabi/trunk/src/cxa_demangle.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=324968&r1=324967&r2=324968&view=diff ============================================================================== --- libcxxabi/trunk/src/cxa_demangle.cpp (original) +++ libcxxabi/trunk/src/cxa_demangle.cpp Mon Feb 12 16:15:46 2018 @@ -1977,6 +1977,7 @@ struct Db { Node *parseArrayType(); Node *parsePointerToMemberType(); Node *parseClassEnumType(); + Node *parseQualifiedType(bool &AppliesToFunction); // FIXME: remove this when all the parse_* functions have been rewritten. template <const char *(*parse_fn)(const char *, const char *, Db &)> @@ -2238,6 +2239,52 @@ Node *Db::parseClassEnumType() { return legacyParse<parse_name>(); } +// <qualified-type> ::= <qualifiers> <type> +// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers> +// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier +Node *Db::parseQualifiedType(bool &AppliesToFunction) { + if (consumeIf('U')) { + StringView Qual = parseBareSourceName(); + if (Qual.empty()) + return nullptr; + + // FIXME parse the optional <template-args> here! + + // extension ::= U <objc-name> <objc-type> # objc-type<identifier> + if (Qual.startsWith("objcproto")) { + StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); + StringView Proto; + { + SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()), + SaveLast(Last, ProtoSourceName.end()); + Proto = parseBareSourceName(); + } + if (Proto.empty()) + return nullptr; + Node *Child = parseQualifiedType(AppliesToFunction); + if (Child == nullptr) + return nullptr; + return make<ObjCProtoName>(Child, Proto); + } + + Node *Child = parseQualifiedType(AppliesToFunction); + if (Child == nullptr) + return nullptr; + return make<VendorExtQualType>(Child, Qual); + } + + Qualifiers Quals = parseCVQualifiers(); + AppliesToFunction = look() == 'F'; + Node *Ty = parseType(); + if (Ty == nullptr) + return nullptr; + if (Quals != QualNone) { + return AppliesToFunction ? + make<FunctionQualType>(Ty, Quals) : make<QualType>(Ty, Quals); + } + return Ty; +} + // <type> ::= <builtin-type> // ::= <qualified-type> // ::= <function-type> @@ -2265,18 +2312,10 @@ Node *Db::parseType() { // ::= <qualified-type> case 'r': case 'V': - case 'K': { - Qualifiers Q = parseCVQualifiers(); - bool AppliesToFunction = look() == 'F'; - - Node *Child = parseType(); - if (Child == nullptr) - return nullptr; - - if (AppliesToFunction) - Result = make<FunctionQualType>(Child, Q); - else - Result = make<QualType>(Child, Q); + case 'K': + case 'U': { + bool AppliesToFunction = false; + Result = parseQualifiedType(AppliesToFunction); // Itanium C++ ABI 5.1.5.3: // For the purposes of substitution, the CV-qualifiers and ref-qualifier @@ -2285,39 +2324,6 @@ Node *Db::parseType() { return Result; break; } - // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier - case 'U': { - // FIXME: We should fold this into the cvr qualifier parsing above. This - // currently adds too many entries into the substitution table if multiple - // qualifiers are present on the same type, as all the qualifiers on a type - // should just get one entry in the substitution table. - ++First; - StringView Qual = parseBareSourceName(); - if (Qual.empty()) - return nullptr; - - // FIXME parse the optional <template-args> here! - - Result = parseType(); - if (Result == nullptr) - return nullptr; - - // extension ::= U <objc-name> <objc-type> # objc-type<identifier> - if (Qual.startsWith("objcproto")) { - StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); - StringView Proto; - { - SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()), - SaveLast(Last, ProtoSourceName.end()); - Proto = parseBareSourceName(); - } - if (Proto.empty()) - return nullptr; - Result = make<ObjCProtoName>(Result, Proto); - } else - Result = make<VendorExtQualType>(Result, Qual); - break; - } // <builtin-type> ::= v # void case 'v': ++First; Modified: libcxxabi/trunk/test/test_demangle.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=324968&r1=324967&r2=324968&view=diff ============================================================================== --- libcxxabi/trunk/test/test_demangle.pass.cpp (original) +++ libcxxabi/trunk/test/test_demangle.pass.cpp Mon Feb 12 16:15:46 2018 @@ -29656,6 +29656,9 @@ const char* cases[][2] = {"_ZN5test73fT4IiEEDTcvT_Li1EES1_", "decltype((int)(1)) test7::fT4<int>(int)"}, {"_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_", "decltype((test7::B)(1, 2)) test7::fT6<test7::B>(test7::B)"}, {"_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv", "decltype(foo<int>()) test8::X<int>::bar<int>() const"}, + + // Multiple qualifiers on the same type should all get the same entry in the substitution table. + {"_Z1fPU3AS1KiS0_", "f(int const AS1*, int const AS1*)"} }; const unsigned N = sizeof(cases) / sizeof(cases[0]); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits