aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ExprCXX.h4
-rw-r--r--lib/CodeGen/Mangle.cpp58
-rw-r--r--test/CodeGenCXX/mangle.cpp8
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(
}