From: John McCall Date: Thu, 4 Feb 2010 02:56:29 +0000 (+0000) Subject: Mangle member expressions. Also invented. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2f27bf854f0519810b34afd209089cc75536b757;p=clang Mangle member expressions. Also invented. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95284 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 918dde6d4d..76ef02df4b 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1924,6 +1924,10 @@ public: assert(!isImplicitAccess()); return cast(Base); } + const Expr *getBase() const { + assert(!isImplicitAccess()); + return cast(Base); + } void setBase(Expr *E) { Base = E; } QualType getBaseType() const { return BaseType; } diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 97fb393e0e..69752b923e 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -132,6 +132,10 @@ private: bool MangleReturnType); void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); + void mangleMemberExpr(const Expr *Base, bool IsArrow, + NestedNameSpecifier *Qualifier, + DeclarationName Name, + unsigned KnownArity); void mangleCalledExpression(const Expr *E, unsigned KnownArity); void mangleExpression(const Expr *E); void mangleCXXCtorType(CXXCtorType T); @@ -1108,16 +1112,43 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, void CXXNameMangler::mangleCalledExpression(const Expr *E, unsigned Arity) { if (E->getType() != getASTContext().OverloadTy) mangleExpression(E); + // 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. +/// +/// The standard ABI does not describe how member expressions should +/// be mangled, so this is very unstandardized. We mangle as if it +/// were a binary operator, except that the RHS is mangled as an +/// abstract name. +/// +/// The standard ABI also does not assign a mangling to the dot +/// operator, so we arbitrarily select 'me'. +void CXXNameMangler::mangleMemberExpr(const Expr *Base, + bool IsArrow, + NestedNameSpecifier *Qualifier, + DeclarationName Member, + unsigned Arity) { + Out << (IsArrow ? "pt" : "me"); + mangleExpression(Base); + mangleUnresolvedName(Qualifier, Member, Arity); +} + void CXXNameMangler::mangleExpression(const Expr *E) { // ::= // ::= @@ -1151,6 +1182,31 @@ void CXXNameMangler::mangleExpression(const Expr *E) { break; } + case Expr::MemberExprClass: { + const MemberExpr *ME = cast(E); + mangleMemberExpr(ME->getBase(), ME->isArrow(), + ME->getQualifier(), ME->getMemberDecl()->getDeclName(), + UnknownArity); + break; + } + + case Expr::UnresolvedMemberExprClass: { + const UnresolvedMemberExpr *ME = cast(E); + mangleMemberExpr(ME->getBase(), ME->isArrow(), + ME->getQualifier(), ME->getMemberName(), + UnknownArity); + break; + } + + case Expr::CXXDependentScopeMemberExprClass: { + const CXXDependentScopeMemberExpr *ME + = cast(E); + mangleMemberExpr(ME->getBase(), ME->isArrow(), + ME->getQualifier(), ME->getMember(), + UnknownArity); + break; + } + case Expr::UnresolvedLookupExprClass: { // The ABI doesn't cover how to mangle overload sets, so we mangle // using something as close as possible to the original lookup @@ -1214,7 +1270,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) { mangleExpression(BO->getLHS()); mangleExpression(BO->getRHS()); break; - } + } case Expr::ConditionalOperatorClass: { const ConditionalOperator *CO = cast(E); diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 2e9afd0281..a1dc67bee4 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -356,4 +356,12 @@ namespace test0 { h(buffer); } // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c( + + template void j(char (&buffer)[sizeof(T().buffer)]) {} + struct A { double buffer[128]; }; + void test4() { + char buffer[1024]; + j(buffer); + } + // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszmecvT__E6buffer_c( }