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) {