More capturing of 'this':  implicit member expressions.  Getting that
right for anonymous struct/union members led to me discovering some
seemingly broken code in that area of Sema, which I fixed, partly by  
changing the representation of member pointer constants so that    
IndirectFieldDecls aren't expanded.  This led to assorted cleanups with   
member pointers in CodeGen, and while I was doing that I saw some random
other things to clean up.                   



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124785 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index 8a7ac0a..2068c29 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -79,7 +79,8 @@
   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
 
   llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
-  llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
+  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
+                                        CharUnits offset);
 
   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
                                            llvm::Value *L,
@@ -493,43 +494,13 @@
                                    /*Packed=*/false);
 }
 
-static uint64_t getFieldOffset(const FieldDecl *FD, CodeGenModule &CGM) {
-  const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(FD->getParent());
-  const llvm::StructType *ClassLTy = RL.getLLVMType();
-
-  unsigned FieldNo = RL.getLLVMFieldNo(FD);
-  return
-       CGM.getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
-}
-
-llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const FieldDecl *FD) {
+llvm::Constant *
+ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
+                                     CharUnits offset) {
   // Itanium C++ ABI 2.3:
   //   A pointer to data member is an offset from the base address of
   //   the class object containing it, represented as a ptrdiff_t
-
-  const RecordDecl *parent = FD->getParent();
-  if (!parent->isAnonymousStructOrUnion())
-    return llvm::ConstantInt::get(getPtrDiffTy(), getFieldOffset(FD, CGM));
-
-  // Handle a field injected from an anonymous struct or union.
-
-  assert(FD->getDeclName() && "Requested pointer to member with no name!");
-
-  // Find the record which the field was injected into.
-  while (parent->isAnonymousStructOrUnion())
-    parent = cast<RecordDecl>(parent->getParent());
-
-  RecordDecl::lookup_const_result lookup = parent->lookup(FD->getDeclName());
-  assert(lookup.first != lookup.second && "Didn't find the field!");
-  const IndirectFieldDecl *indirectFD = cast<IndirectFieldDecl>(*lookup.first);
-
-  uint64_t Offset = 0;
-  for (IndirectFieldDecl::chain_iterator
-         I= indirectFD->chain_begin(), E= indirectFD->chain_end(); I!=E; ++I) {
-    Offset += getFieldOffset(cast<FieldDecl>(*I), CGM);
-  }
-
-  return llvm::ConstantInt::get(getPtrDiffTy(), Offset);
+  return llvm::ConstantInt::get(getPtrDiffTy(), offset.getQuantity());
 }
 
 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {