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/CGExprScalar.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/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 73 |
1 files changed, 21 insertions, 52 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 4d4ddd948c..4487f17f60 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -414,11 +414,8 @@ Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { return Builder.CreateFCmpUNE(Src, Zero, "tobool"); } - if (SrcType->isMemberPointerType()) { - // Compare against -1. - llvm::Value *NegativeOne = llvm::Constant::getAllOnesValue(Src->getType()); - return Builder.CreateICmpNE(Src, NegativeOne, "tobool"); - } + if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType)) + return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT); assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) && "Unknown scalar type to convert"); @@ -567,14 +564,10 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, } Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { - const llvm::Type *LTy = ConvertType(Ty); - - if (!Ty->isMemberDataPointerType()) - return llvm::Constant::getNullValue(LTy); - - // Itanium C++ ABI 2.3: - // A NULL pointer is represented as -1. - return llvm::ConstantInt::get(LTy, -1ULL, /*isSigned=*/true); + if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) + return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT); + + return llvm::Constant::getNullValue(ConvertType(Ty)); } //===----------------------------------------------------------------------===// @@ -994,17 +987,15 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { case CastExpr::CK_FunctionToPointerDecay: return EmitLValue(E).getAddress(); - case CastExpr::CK_NullToMemberPointer: + case CastExpr::CK_NullToMemberPointer: { // If the subexpression's type is the C++0x nullptr_t, emit the // subexpression, which may have side effects. if (E->getType()->isNullPtrType()) (void) Visit(E); - if (CE->getType()->isMemberFunctionPointerType()) - return CGF.CGM.getCXXABI().EmitNullMemberFunctionPointer( - CE->getType()->getAs<MemberPointerType>()); - - return CGF.CGM.EmitNullConstant(DestTy); + const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>(); + return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT); + } case CastExpr::CK_BaseToDerivedMemberPointer: case CastExpr::CK_DerivedToBaseMemberPointer: { @@ -1016,33 +1007,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { // actual control flow may be required in order to perform the // check, which it is for data member pointers (but not member // function pointers on Itanium and ARM). - - if (CE->getType()->isMemberFunctionPointerType()) - return CGF.CGM.getCXXABI().EmitMemberFunctionPointerConversion(CGF, CE, - Src); - - // See if we need to adjust the pointer. - const CXXRecordDecl *BaseDecl = - cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()-> - getClass()->getAs<RecordType>()->getDecl()); - const CXXRecordDecl *DerivedDecl = - cast<CXXRecordDecl>(CE->getType()->getAs<MemberPointerType>()-> - getClass()->getAs<RecordType>()->getDecl()); - if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) - std::swap(DerivedDecl, BaseDecl); - - if (llvm::Constant *Adj = - CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, - CE->path_begin(), - CE->path_end())) { - if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer) - Src = Builder.CreateNSWSub(Src, Adj, "adj"); - else - Src = Builder.CreateNSWAdd(Src, Adj, "adj"); - } - - return Src; + return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src); } + case CastExpr::CK_ConstructorConversion: assert(0 && "Should be unreachable!"); @@ -1096,10 +1063,13 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { case CastExpr::CK_FloatingCast: return EmitScalarConversion(Visit(E), E->getType(), DestTy); - case CastExpr::CK_MemberPointerToBoolean: - return CGF.EvaluateExprAsBool(E); + case CastExpr::CK_MemberPointerToBoolean: { + llvm::Value *MemPtr = Visit(E); + const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); + return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT); } - + } + // Handle cases where the source is an non-complex type. if (!CGF.hasAggregateLLVMType(E->getType())) { @@ -1821,14 +1791,13 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, TestAndClearIgnoreResultAssign(); Value *Result; QualType LHSTy = E->getLHS()->getType(); - if (LHSTy->isMemberFunctionPointerType()) { + if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) { assert(E->getOpcode() == BinaryOperator::EQ || E->getOpcode() == BinaryOperator::NE); Value *LHS = CGF.EmitScalarExpr(E->getLHS()); Value *RHS = CGF.EmitScalarExpr(E->getRHS()); - Result = CGF.CGM.getCXXABI().EmitMemberFunctionPointerComparison( - CGF, LHS, RHS, LHSTy->getAs<MemberPointerType>(), - E->getOpcode() == BinaryOperator::NE); + Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison( + CGF, LHS, RHS, MPT, E->getOpcode() == BinaryOperator::NE); } else if (!LHSTy->isAnyComplexType()) { Value *LHS = Visit(E->getLHS()); Value *RHS = Visit(E->getRHS()); |