diff options
Diffstat (limited to 'lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 41 |
1 files changed, 6 insertions, 35 deletions
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 8a7ac0a83a..2068c2925c 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -79,7 +79,8 @@ public: 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 @@ ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { /*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) { |