diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-02 03:37:46 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-02 03:37:46 +0000 |
commit | 45147d0098a34c3705f74ca121b27d7736ac113a (patch) | |
tree | b9b7bbb4c3f74db93afbe0de4e982f52db40e80d /lib/CodeGen/CGExprConstant.cpp | |
parent | 63b071f28ea936772634c176a34de2bf0301f79c (diff) |
Move pointer to data member emission to CodeGenModule and use it in CGExprConstant. Fixes PR5674.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95063 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprConstant.cpp')
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index a9a07d5b75..fba70cb88f 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -438,16 +438,16 @@ public: if (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) { QualType T = MPT->getPointeeType(); - if (T->isFunctionProtoType()) { - DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr()); - - return EmitMemberFunctionPointer(cast<CXXMethodDecl>(DRE->getDecl())); - } + DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr()); + + NamedDecl *ND = DRE->getDecl(); + if (T->isFunctionProtoType()) + return EmitMemberFunctionPointer(cast<CXXMethodDecl>(ND)); - // FIXME: Should we handle other member pointer types here too, - // or should they be handled by Expr::Evaluate? + // We have a pointer to data member. + return CGM.EmitPointerToDataMember(cast<FieldDecl>(ND)); } - + return 0; } @@ -959,3 +959,27 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T)); } + +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)); + + unsigned FieldNo = getTypes().getLLVMFieldNo(FD); + uint64_t Offset = + getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo); + + const llvm::Type *PtrDiffTy = + getTypes().ConvertType(getContext().getPointerDiffType()); + + return llvm::ConstantInt::get(PtrDiffTy, Offset); +} |