aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-02 03:37:46 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-02 03:37:46 +0000
commit45147d0098a34c3705f74ca121b27d7736ac113a (patch)
treeb9b7bbb4c3f74db93afbe0de4e982f52db40e80d /lib/CodeGen/CGExprConstant.cpp
parent63b071f28ea936772634c176a34de2bf0301f79c (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.cpp40
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);
+}