diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-02-13 00:15:53 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-02-13 00:15:53 +0000 |
| commit | 8d2aca06975f196a833e3c4cb8dd5270e5de6cbf (patch) | |
| tree | 0db257caeb75fcebfae62a48f3ef7fa7e9f9a7b2 | |
| parent | 94bd8325181c7f8d0422098e62b9b8220f972e86 (diff) | |
| download | bcm5719-llvm-8d2aca06975f196a833e3c4cb8dd5270e5de6cbf.tar.gz bcm5719-llvm-8d2aca06975f196a833e3c4cb8dd5270e5de6cbf.zip | |
[demangler] Support for dependent elaborate type specifiers.
llvm-svn: 324969
| -rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 41 | ||||
| -rw-r--r-- | libcxxabi/test/test_demangle.pass.cpp | 6 |
2 files changed, 44 insertions, 3 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 49b3e12dd0d..5faf0ae263b 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -165,6 +165,7 @@ public: KQualType, KConversionOperatorType, KPostfixQualifiedType, + KElaboratedTypeSpefType, KNameType, KAbiTagAttr, KObjCProtoName, @@ -443,6 +444,22 @@ public: void printLeft(OutputStream &s) const override { s += Name; } }; +class ElaboratedTypeSpefType : public Node { + StringView Kind; + Node *Child; +public: + ElaboratedTypeSpefType(StringView Kind_, Node *Child_) + : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) { + ParameterPackSize = Child->ParameterPackSize; + } + + void printLeft(OutputStream &S) const override { + S += Kind; + S += ' '; + Child->print(S); + } +}; + class AbiTagAttr final : public Node { const Node* Base; StringView Tag; @@ -2235,8 +2252,22 @@ Node *Db::parsePointerToMemberType() { // ::= Tu <name> # dependent elaborated type specifier using 'union' // ::= Te <name> # dependent elaborated type specifier using 'enum' Node *Db::parseClassEnumType() { - // FIXME: try to parse the elaborated type specifiers here! - return legacyParse<parse_name>(); + StringView ElabSpef; + if (consumeIf("Ts")) + ElabSpef = "struct"; + else if (consumeIf("Tu")) + ElabSpef = "union"; + else if (consumeIf("Te")) + ElabSpef = "enum"; + + Node *Name = legacyParse<parse_name>(); + if (Name == nullptr) + return nullptr; + + if (!ElabSpef.empty()) + return make<ElaboratedTypeSpefType>(ElabSpef, Name); + + return Name; } // <qualified-type> ::= <qualifiers> <type> @@ -2495,6 +2526,12 @@ Node *Db::parseType() { } // ::= <template-param> case 'T': { + // This could be an elaborate type specifier on a <class-enum-type>. + if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') { + Result = parseClassEnumType(); + break; + } + Result = legacyParse<parse_template_param>(); if (Result == nullptr) return nullptr; diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index c66161da982..e28f1ec014d 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29658,7 +29658,11 @@ const char* cases[][2] = {"_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*)"} + {"_Z1fPU3AS1KiS0_", "f(int const AS1*, int const AS1*)"}, + + {"_ZN6test471fINS_1SEEEvPTsNT_1cE", "void test47::f<test47::S>(struct test47::S::c*)"}, + {"_ZN6test481fINS_1SEEEvPTuNT_1uE", "void test48::f<test48::S>(union test48::S::u*)"}, + {"_ZN6test451fINS_1SEEEvPTeNT_1eE", "void test45::f<test45::S>(enum test45::S::e*)"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); |

