diff options
author | John McCall <rjmccall@apple.com> | 2010-08-23 01:21:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-23 01:21:21 +0000 |
commit | 0bab0cdab751248ca389a5592bcb70eac5d39260 (patch) | |
tree | c94ff2becd4c318148c7ece7e236a6482de526a7 /lib/CodeGen/CGExprConstant.cpp | |
parent | 5172ed92b42f0bc6a022542a08f7b18af821bcb3 (diff) |
Abstract out everything having to do with member pointers into the ABI
class; they should just be completely opaque throughout IR gen now,
although I haven't really audited that.
Fix a bug apparently inherited from gcc-4.2 where we failed to null-check
member data pointers when performing derived-to-base or base-to-derived
conversions on them.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111789 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 53 |
1 files changed, 6 insertions, 47 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 48826492df..0dcee6ef6a 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -454,22 +454,15 @@ public: return Visit(E->getInitializer()); } - llvm::Constant *EmitMemberFunctionPointer(CXXMethodDecl *MD) { - return CGM.getCXXABI().EmitMemberFunctionPointer(MD); - } - llvm::Constant *VisitUnaryAddrOf(UnaryOperator *E) { if (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) { - QualType T = MPT->getPointeeType(); DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr()); - NamedDecl *ND = DRE->getDecl(); - if (T->isFunctionProtoType()) - return EmitMemberFunctionPointer(cast<CXXMethodDecl>(ND)); - - // We have a pointer to data member. - return CGM.EmitPointerToDataMember(cast<FieldDecl>(ND)); + if (MPT->isMemberFunctionPointer()) + return CGM.getCXXABI().EmitMemberPointer(cast<CXXMethodDecl>(ND)); + else + return CGM.getCXXABI().EmitMemberPointer(cast<FieldDecl>(ND)); } return 0; @@ -535,24 +528,16 @@ public: } case CastExpr::CK_NullToMemberPointer: { const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); - if (MPT->getPointeeType()->isFunctionType()) - return CGM.getCXXABI().EmitNullMemberFunctionPointer(MPT); - return CGM.EmitNullConstant(E->getType()); + return CGM.getCXXABI().EmitNullMemberPointer(MPT); } case CastExpr::CK_BaseToDerivedMemberPointer: { - const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); - - // TODO: support data-member conversions here! - if (!MPT->getPointeeType()->isFunctionType()) - return 0; - Expr *SubExpr = E->getSubExpr(); llvm::Constant *C = CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF); if (!C) return 0; - return CGM.getCXXABI().EmitMemberFunctionPointerConversion(C, E); + return CGM.getCXXABI().EmitMemberPointerConversion(C, E); } case CastExpr::CK_BitCast: @@ -1134,29 +1119,3 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { return llvm::ConstantInt::get(getTypes().ConvertTypeForMem(T), -1ULL, /*isSigned=*/true); } - -llvm::Constant * -CodeGenModule::EmitPointerToDataMember(const FieldDecl *FD) { - - // 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 CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(FD->getParent()); - QualType ClassType = - getContext().getTypeDeclType(const_cast<CXXRecordDecl *>(ClassDecl)); - - const llvm::StructType *ClassLTy = - cast<llvm::StructType>(getTypes().ConvertType(ClassType)); - - const CGRecordLayout &RL = - getTypes().getCGRecordLayout(FD->getParent()); - unsigned FieldNo = RL.getLLVMFieldNo(FD); - uint64_t Offset = - getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo); - - const llvm::Type *PtrDiffTy = - getTypes().ConvertType(getContext().getPointerDiffType()); - - return llvm::ConstantInt::get(PtrDiffTy, Offset); -} |