From: John McCall Date: Wed, 18 Aug 2010 19:18:59 +0000 (+0000) Subject: Contextual arity is a feature of mangling expressions; kill off X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e1e89b8af283af34943a477dc6378f1a641df26;p=clang Contextual arity is a feature of mangling expressions; kill off mangleCallExpression. Also, operator names with unknown arity should be mangled as binary operators; this is actually covered by an oddly- positioned sentence in the ABI document. Fixes PR7891. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111395 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 969670a28d..30fd668b0c 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -241,8 +241,7 @@ private: NestedNameSpecifier *Qualifier, DeclarationName Name, unsigned KnownArity); - void mangleCalledExpression(const Expr *E, unsigned KnownArity); - void mangleExpression(const Expr *E); + void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); void mangleCXXCtorType(CXXCtorType T); void mangleCXXDtorType(CXXDtorType T); @@ -1024,24 +1023,21 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { // ::= da # delete[] case OO_Array_Delete: Out << "da"; break; // ::= ps # + (unary) - // ::= pl # + + // ::= pl # + (binary or unknown) case OO_Plus: - assert((Arity == 1 || Arity == 2) && "Invalid arity!"); Out << (Arity == 1? "ps" : "pl"); break; // ::= ng # - (unary) - // ::= mi # - + // ::= mi # - (binary or unknown) case OO_Minus: - assert((Arity == 1 || Arity == 2) && "Invalid arity!"); Out << (Arity == 1? "ng" : "mi"); break; // ::= ad # & (unary) - // ::= an # & + // ::= an # & (binary or unknown) case OO_Amp: - assert((Arity == 1 || Arity == 2) && "Invalid arity!"); Out << (Arity == 1? "ad" : "an"); break; // ::= de # * (unary) - // ::= ml # * + // ::= ml # * (binary or unknown) case OO_Star: - assert((Arity == 1 || Arity == 2) && "Invalid arity!"); + // Use binary when unknown. Out << (Arity == 1? "de" : "ml"); break; // ::= co # ~ case OO_Tilde: Out << "co"; break; @@ -1544,25 +1540,6 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, } -void CXXNameMangler::mangleCalledExpression(const Expr *E, unsigned Arity) { - if (E->getType() != getASTContext().OverloadTy) - return mangleExpression(E); - // FIXME: propagate arity to dependent overloads? - - llvm::PointerIntPair R - = OverloadExpr::find(const_cast(E)); - if (R.getInt()) - Out << "an"; // & - const OverloadExpr *Ovl = R.getPointer(); - if (const UnresolvedMemberExpr *ME = dyn_cast(Ovl)) { - mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(), - ME->getMemberName(), Arity); - return; - } - - mangleUnresolvedName(Ovl->getQualifier(), Ovl->getName(), Arity); -} - /// Mangles a member expression. Implicit accesses are not handled, /// but that should be okay, because you shouldn't be able to /// make an implicit access in a function template declaration. @@ -1578,7 +1555,7 @@ void CXXNameMangler::mangleMemberExpr(const Expr *Base, mangleUnresolvedName(Qualifier, Member, Arity); } -void CXXNameMangler::mangleExpression(const Expr *E) { +void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // ::= // ::= // ::= @@ -1652,14 +1629,14 @@ void CXXNameMangler::mangleExpression(const Expr *E) { } case Expr::CXXDefaultArgExprClass: - mangleExpression(cast(E)->getExpr()); + mangleExpression(cast(E)->getExpr(), Arity); break; case Expr::CXXMemberCallExprClass: // fallthrough case Expr::CallExprClass: { const CallExpr *CE = cast(E); Out << "cl"; - mangleCalledExpression(CE->getCallee(), CE->getNumArgs()); + mangleExpression(CE->getCallee(), CE->getNumArgs()); for (unsigned I = 0, N = CE->getNumArgs(); I != N; ++I) mangleExpression(CE->getArg(I)); Out << 'E'; @@ -1690,7 +1667,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { const MemberExpr *ME = cast(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(), ME->getMemberDecl()->getDeclName(), - UnknownArity); + Arity); break; } @@ -1698,7 +1675,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { const UnresolvedMemberExpr *ME = cast(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(), ME->getMemberName(), - UnknownArity); + Arity); break; } @@ -1707,7 +1684,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { = cast(E); mangleMemberExpr(ME->getBase(), ME->isArrow(), ME->getQualifier(), ME->getMember(), - UnknownArity); + Arity); break; } @@ -1716,7 +1693,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { // using something as close as possible to the original lookup // expression. const UnresolvedLookupExpr *ULE = cast(E); - mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), UnknownArity); + mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity); break; } @@ -1829,13 +1806,13 @@ void CXXNameMangler::mangleExpression(const Expr *E) { const ConditionalOperator *CO = cast(E); mangleOperatorName(OO_Conditional, /*Arity=*/3); mangleExpression(CO->getCond()); - mangleExpression(CO->getLHS()); - mangleExpression(CO->getRHS()); + mangleExpression(CO->getLHS(), Arity); + mangleExpression(CO->getRHS(), Arity); break; } case Expr::ImplicitCastExprClass: { - mangleExpression(cast(E)->getSubExpr()); + mangleExpression(cast(E)->getSubExpr(), Arity); break; } @@ -1863,7 +1840,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { } case Expr::ParenExprClass: - mangleExpression(cast(E)->getSubExpr()); + mangleExpression(cast(E)->getSubExpr(), Arity); break; case Expr::DeclRefExprClass: { @@ -1914,10 +1891,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { // ::= sr # dependent name Out << "sr"; mangleType(QualType(QTy, 0)); - - assert(DRE->getDeclName().getNameKind() == DeclarationName::Identifier && - "Unhandled decl name kind!"); - mangleSourceName(DRE->getDeclName().getAsIdentifierInfo()); + mangleUnqualifiedName(0, DRE->getDeclName(), Arity); break; } @@ -1931,7 +1905,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { break; case Expr::CXXExprWithTemporariesClass: - mangleExpression(cast(E)->getSubExpr()); + mangleExpression(cast(E)->getSubExpr(), Arity); break; case Expr::FloatingLiteralClass: { diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 6636c926ae..c7a6e0096b 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -557,3 +557,31 @@ namespace test17 { func(); // { dg-error "sorry, unimplemented" } } } + +// PR7891 +namespace test18 { + struct A { + int operator+(); + int operator-(); + int operator*(); + int operator&(); + }; + template struct S {}; + + template void f(S<&T::operator+>) {} + template void f(S<&A::operator+>); + + template void f(S<&T::operator- >) {} + template void f(S<&A::operator- >); + + template void f(S<&T::operator*>) {} + template void f(S<&A::operator*>); + + template void f(S<&T::operator&>) {} + template void f(S<&A::operator&>); + + // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE + // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE + // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE + // CHECK: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE +}