Author: epilk Date: Tue Feb 13 17:08:20 2018 New Revision: 325093 URL: http://llvm.org/viewvc/llvm-project?rev=325093&view=rev Log: [demangler] Support for exception specifications on function types.
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=325093&r1=325092&r2=325093&view=diff ============================================================================== --- libcxxabi/trunk/src/cxa_demangle.cpp (original) +++ libcxxabi/trunk/src/cxa_demangle.cpp Tue Feb 13 17:08:20 2018 @@ -175,6 +175,8 @@ public: KPointerToMemberType, KArrayType, KFunctionType, + KNoexceptSpec, + KDynamicExceptionSpec, KFunctionEncoding, KLiteralOperator, KSpecialName, @@ -720,16 +722,21 @@ class FunctionType final : public Node { NodeArray Params; Qualifiers CVQuals; FunctionRefQual RefQual; + Node *ExceptionSpec; public: FunctionType(Node *Ret_, NodeArray Params_, Qualifiers CVQuals_, - FunctionRefQual RefQual_) + FunctionRefQual RefQual_, Node *ExceptionSpec_) : Node(KFunctionType, Ret_->ParameterPackSize, /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, /*FunctionCache=*/Cache::Yes), - Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_) { + Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_), + ExceptionSpec(ExceptionSpec_) { for (Node *P : Params) ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize); + if (ExceptionSpec != nullptr) + ParameterPackSize = + std::min(ParameterPackSize, ExceptionSpec->ParameterPackSize); } bool hasRHSComponentSlow(OutputStream &) const override { return true; } @@ -764,6 +771,39 @@ public: S += " &"; else if (RefQual == FrefQualRValue) S += " &&"; + + if (ExceptionSpec != nullptr) { + S += ' '; + ExceptionSpec->print(S); + } + } +}; + +class NoexceptSpec : public Node { + Node *E; +public: + NoexceptSpec(Node *E_) : Node(KNoexceptSpec, E_->ParameterPackSize), E(E_) {} + + void printLeft(OutputStream &S) const override { + S += "noexcept("; + E->print(S); + S += ")"; + } +}; + +class DynamicExceptionSpec : public Node { + NodeArray Types; +public: + DynamicExceptionSpec(NodeArray Types_) + : Node(KDynamicExceptionSpec), Types(Types_) { + for (Node *T : Types) + ParameterPackSize = std::min(ParameterPackSize, T->ParameterPackSize); + } + + void printLeft(OutputStream &S) const override { + S += "throw("; + Types.printWithComma(S); + S += ')'; } }; @@ -2370,6 +2410,29 @@ StringView Db::parseBareSourceName() { // <ref-qualifier> ::= O # && ref-qualifier Node *Db::parseFunctionType() { Qualifiers CVQuals = parseCVQualifiers(); + + Node *ExceptionSpec = nullptr; + if (consumeIf("Do")) { + ExceptionSpec = make<NameType>("noexcept"); + } else if (consumeIf("DO")) { + Node *E = parseExpr(); + if (E == nullptr || !consumeIf('E')) + return nullptr; + ExceptionSpec = make<NoexceptSpec>(E); + } else if (consumeIf("Dw")) { + size_t SpecsBegin = Names.size(); + while (!consumeIf('E')) { + Node *T = parseType(); + if (T == nullptr) + return nullptr; + Names.push_back(T); + } + ExceptionSpec = + make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin)); + } + + consumeIf("Dx"); // transaction safe + if (!consumeIf('F')) return nullptr; consumeIf('Y'); // extern "C" @@ -2399,7 +2462,8 @@ Node *Db::parseFunctionType() { } NodeArray Params = popTrailingNodeArray(ParamsBegin); - return make<FunctionType>(ReturnType, Params, CVQuals, ReferenceQualifier); + return make<FunctionType>(ReturnType, Params, CVQuals, + ReferenceQualifier, ExceptionSpec); } // extension: @@ -2599,7 +2663,11 @@ Node *Db::parseType() { if (look(AfterQuals) == 'r') ++AfterQuals; if (look(AfterQuals) == 'V') ++AfterQuals; if (look(AfterQuals) == 'K') ++AfterQuals; - if (look(AfterQuals) == 'F') { + + if (look(AfterQuals) == 'F' || + (look(AfterQuals) == 'D' && + (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' || + look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) { Result = parseFunctionType(); break; } @@ -2761,6 +2829,14 @@ Node *Db::parseType() { Result = make<ParameterPackExpansion>(Child); break; } + // Exception specifier on a function type. + case 'o': + case 'O': + case 'w': + // Transaction safe function type. + case 'x': + Result = parseFunctionType(); + break; } break; // ::= <function-type> Modified: libcxxabi/trunk/test/test_demangle.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=325093&r1=325092&r2=325093&view=diff ============================================================================== --- libcxxabi/trunk/test/test_demangle.pass.cpp (original) +++ libcxxabi/trunk/test/test_demangle.pass.cpp Tue Feb 13 17:08:20 2018 @@ -29694,6 +29694,22 @@ const char* cases[][2] = // Inheriting constructors: {"_ZN1BCI21AEi", "B::B(int)"}, {"_ZN1DCI21CIiEET_", "D::D(int)"}, + + // Exception specifiers: + {"_Z1bPDoFivE", "b(int (*)() noexcept)"}, + {"_Z1fILb0EEvPDOT_EFivE", "void f<false>(int (*)() noexcept(false))"}, + {"_Z1fILb1EEvPDOT_EFivE", "void f<true>(int (*)() noexcept(true))"}, + {"_Z1gIJEEvPDwDpT_EFivE", "void g<>(int (*)() throw())"}, + {"_Z1gIJfEEvPDwDpT_EFivE", "void g<float>(int (*)() throw(float))"}, + {"_Z1hIJEEPDwDpT_iEFivEPDwiS1_EFivE", "int (*h<>(int (*)() throw(int)))() throw(int)"}, + {"_Z1hIJfEEPDwDpT_iEFivEPDwiS1_EFivE", "int (*h<float>(int (*)() throw(int, float)))() throw(float, int)"}, + {"_Z1iIJEEPDwiDpT_EFivEPS2_", "int (*i<>(int (*)() throw(int)))() throw(int)"}, + {"_Z1iIJEEPDwiDpT_EFivES3_", "int (*i<>(int (*)() throw(int)))() throw(int)"}, + {"_Z1iIJfEEPDwiDpT_EFivEPS2_", "int (*i<float>(int (*)() throw(int, float)))() throw(int, float)"}, + {"_Z1iIJfEEPDwiDpT_EFivES3_", "int (*i<float>(int (*)() throw(int, float)))() throw(int, float)"}, + {"_Z1pILb1EEiM1SKDOT_EFivRE", "int p<true>(int (S::*)() const & noexcept(true))"}, + {"_Z1pIJicfEEiM1SVKDwDpT_EFivOE", "int p<int, char, float>(int (S::*)() const volatile && throw(int, char, float))"}, + {"_Z1pM1SDoFivE", "p(int (S::*)() noexcept)"}, }; 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