From 1dabfdcf6fb11bf6a1f13ce6e9b1294fc57b804f Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 14 Feb 2015 13:23:54 +0000 Subject: [PATCH] ItaniumMangle: Correctly mangle We had two bugs: - We were missing the "on" prefix for unresolved operators. - We didn't handle the mangling of destructors at all. This fixes PR22584. llvm-svn: 229255 --- clang/lib/AST/ItaniumMangle.cpp | 88 ++++++++++++++++++++++++++++------------ clang/test/CodeGenCXX/mangle.cpp | 40 ++++++++++++++---- 2 files changed, 95 insertions(+), 33 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index eae82a2..fdb2564 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -372,6 +372,7 @@ private: void mangleAArch64NeonVectorType(const VectorType *T); void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); + void mangleMemberExprBase(const Expr *base, bool isArrow); void mangleMemberExpr(const Expr *base, bool isArrow, NestedNameSpecifier *qualifier, NamedDecl *firstQualifierLookup, @@ -1050,6 +1051,27 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, DeclarationName name, unsigned knownArity) { if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup); + switch (name.getNameKind()) { + // ::= + case DeclarationName::Identifier: + break; + // ::= on + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXLiteralOperatorName: + case DeclarationName::CXXOperatorName: + Out << "on"; + break; + case DeclarationName::CXXDestructorName: + llvm_unreachable("Can't mangle a constructor name!"); + case DeclarationName::CXXConstructorName: + llvm_unreachable("Can't mangle a constructor name!"); + case DeclarationName::CXXUsingDirective: + llvm_unreachable("Can't mangle a using directive name!"); + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCZeroArgSelector: + llvm_unreachable("Can't mangle Objective-C selector names here!"); + } mangleUnqualifiedName(nullptr, name, knownArity); } @@ -1532,7 +1554,8 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) { DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); assert(Dependent && "Unknown template name kind?"); - manglePrefix(Dependent->getQualifier()); + if (NestedNameSpecifier *Qualifier = Dependent->getQualifier()) + manglePrefix(Qualifier); mangleUnscopedTemplateName(Template); } @@ -2522,6 +2545,29 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, } +void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) { + // Ignore member expressions involving anonymous unions. + while (const auto *RT = Base->getType()->getAs()) { + if (!RT->getDecl()->isAnonymousStructOrUnion()) + break; + const auto *ME = dyn_cast(Base); + if (!ME) + break; + Base = ME->getBase(); + IsArrow = ME->isArrow(); + } + + if (Base->isImplicitCXXThis()) { + // Note: GCC mangles member expressions to the implicit 'this' as + // *this., whereas we represent them as this->. The Itanium C++ ABI + // does not specify anything here, so we follow GCC. + Out << "dtdefpT"; + } else { + Out << (IsArrow ? "pt" : "dt"); + mangleExpression(Base); + } +} + /// Mangles a member expression. void CXXNameMangler::mangleMemberExpr(const Expr *base, bool isArrow, @@ -2531,29 +2577,8 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, unsigned arity) { // ::= dt // ::= pt - if (base) { - - // Ignore member expressions involving anonymous unions. - while (const auto *RT = base->getType()->getAs()) { - if (!RT->getDecl()->isAnonymousStructOrUnion()) - break; - const auto *ME = dyn_cast(base); - if (!ME) - break; - base = ME->getBase(); - isArrow = ME->isArrow(); - } - - if (base->isImplicitCXXThis()) { - // Note: GCC mangles member expressions to the implicit 'this' as - // *this., whereas we represent them as this->. The Itanium C++ ABI - // does not specify anything here, so we follow GCC. - Out << "dtdefpT"; - } else { - Out << (isArrow ? "pt" : "dt"); - mangleExpression(base); - } - } + if (base) + mangleMemberExprBase(base, isArrow); mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity); } @@ -2651,7 +2676,6 @@ recurse: // FIXME: invent manglings for all these. case Expr::BlockExprClass: - case Expr::CXXPseudoDestructorExprClass: case Expr::ChooseExprClass: case Expr::CompoundLiteralExprClass: case Expr::ExtVectorElementExprClass: @@ -2809,6 +2833,20 @@ recurse: break; } + case Expr::CXXPseudoDestructorExprClass: { + const auto *PDE = cast(E); + if (const Expr *Base = PDE->getBase()) + mangleMemberExprBase(Base, PDE->isArrow()); + if (NestedNameSpecifier *Qualifier = PDE->getQualifier()) + mangleUnresolvedPrefix(Qualifier, /*FirstQualifierLookup=*/nullptr); + // ::= dn + Out << "dn"; + // ::= + // ::= + manglePrefix(PDE->getDestroyedType()); + break; + } + case Expr::MemberExprClass: { const MemberExpr *ME = cast(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index 9af0d9d..3b4123e 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -577,10 +577,10 @@ namespace test18 { template void f(S<&T::operator&>) {} template void f(S<&A::operator&>); - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE } // rdar://problem/8332117 @@ -601,11 +601,11 @@ namespace test19 { // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE( template void g(S<&A::f >); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE( template void g(S<&A::operator+>); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE( template void g(S<&A::operator int>); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE( template void g(S<&A::operator- >); } @@ -839,7 +839,7 @@ namespace test35 { template void f1(decltype(sizeof(&T::template operator+))) {} - // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE + // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE template void f1(__SIZE_TYPE__); } @@ -1013,3 +1013,27 @@ namespace test50 { auto v = fin; // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE() } + +namespace test51 { + template + decltype(T().~T()) fun() {} + template void fun(); + // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv + template void fun(); + // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv + template void fun >(); + // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv + + template + decltype(S1().~S1()) fun1() {}; + template + decltype(U().~S1()) fun2() {} + template + decltype(S1().~U()) fun3() {} + template void fun1(); + // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv + template void fun2, int>(); + // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv + template void fun3, int>(); + // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv +} -- 2.7.4