aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-23 01:21:21 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-23 01:21:21 +0000
commit0bab0cdab751248ca389a5592bcb70eac5d39260 (patch)
treec94ff2becd4c318148c7ece7e236a6482de526a7 /lib/CodeGen/CGExprConstant.cpp
parent5172ed92b42f0bc6a022542a08f7b18af821bcb3 (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.cpp53
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);
-}