diff options
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); +} |