]> granicus.if.org Git - clang/commitdiff
Mangle member expressions. Also invented.
authorJohn McCall <rjmccall@apple.com>
Thu, 4 Feb 2010 02:56:29 +0000 (02:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 4 Feb 2010 02:56:29 +0000 (02:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95284 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/CodeGen/Mangle.cpp
test/CodeGenCXX/mangle.cpp

index 918dde6d4d2f2e16b415defaf5e8f563e4ae30f8..76ef02df4bedf06bfaf1998c797900d373b27f13 100644 (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; }
index 97fb393e0e284fc541bd3c0c527133baf1f10fbd..69752b923e0062d64ce8ac0796087329f052d17e 100644 (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);
index 2e9afd028177b3fcd46c6bc8660bfed0fa5f3456..a1dc67bee4318d54ceb5dc9cb692c1f8e5a376e5 100644 (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(
 }