Mangle member expressions. Also invented.

llvm-svn: 95284
This commit is contained in:
John McCall 2010-02-04 02:56:29 +00:00
parent 42fa84a880
commit d061b4429e
3 changed files with 69 additions and 1 deletions

View File

@ -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; }

View File

@ -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);

View File

@ -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(
}