diff options
-rw-r--r-- | include/clang/AST/ExprCXX.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 58 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle.cpp | 8 |
3 files changed, 69 insertions, 1 deletions
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<Expr>(Base); } + const Expr *getBase() const { + assert(!isImplicitAccess()); + return cast<Expr>(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<OverloadExpr*,1> R = OverloadExpr::find(const_cast<Expr*>(E)); if (R.getInt()) Out << "an"; // & const OverloadExpr *Ovl = R.getPointer(); + if (const UnresolvedMemberExpr *ME = dyn_cast<UnresolvedMemberExpr>(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) { // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> @@ -1151,6 +1182,31 @@ void CXXNameMangler::mangleExpression(const Expr *E) { break; } + case Expr::MemberExprClass: { + const MemberExpr *ME = cast<MemberExpr>(E); + mangleMemberExpr(ME->getBase(), ME->isArrow(), + ME->getQualifier(), ME->getMemberDecl()->getDeclName(), + UnknownArity); + break; + } + + case Expr::UnresolvedMemberExprClass: { + const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E); + mangleMemberExpr(ME->getBase(), ME->isArrow(), + ME->getQualifier(), ME->getMemberName(), + UnknownArity); + break; + } + + case Expr::CXXDependentScopeMemberExprClass: { + const CXXDependentScopeMemberExpr *ME + = cast<CXXDependentScopeMemberExpr>(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<ConditionalOperator>(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<float>(buffer); } // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c( + + template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {} + struct A { double buffer[128]; }; + void test4() { + char buffer[1024]; + j<A>(buffer); + } + // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszmecvT__E6buffer_c( } |