summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCXXABI.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-05-09 21:01:17 +0000
committerReid Kleckner <reid@kleckner.net>2013-05-09 21:01:17 +0000
commit452abac4b344742c94703c1165dc0f51caeff8e3 (patch)
tree018e2872760236d164959a5968bb51a8ac3fd499 /clang/lib/CodeGen/CGCXXABI.cpp
parentf03b2e8385b476546c2f5f54fe3685cd36605e6e (diff)
downloadbcm5719-llvm-452abac4b344742c94703c1165dc0f51caeff8e3.tar.gz
bcm5719-llvm-452abac4b344742c94703c1165dc0f51caeff8e3.zip
[ms-cxxabi] Implement member pointer conversions
Summary: This only supports converting along non-virtual inheritance paths by changing the field offset or the non-virtual base adjustment. This implements three kinds of conversions: - codegen for Value conversions - Constant emission for APValue - Constant folding for CastExprs In almost all constant initialization settings EmitMemberPointer(APValue) is called, except when the expression contains a reinterpret cast. reinterpret casts end up being a big corner case because the null value changes between different kinds of member pointers. Reviewers: rsmith CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D741 llvm-svn: 181543
Diffstat (limited to 'clang/lib/CodeGen/CGCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 68fecb2d0cb..4a125e6d7fa 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -251,6 +251,28 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
E->path_end());
}
+CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) {
+ // TODO: Store base specifiers in APValue member pointer paths so we can
+ // easily reuse CGM.GetNonVirtualBaseClassOffset().
+ const ValueDecl *MPD = MP.getMemberPointerDecl();
+ CharUnits ThisAdjustment = CharUnits::Zero();
+ ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
+ bool DerivedMember = MP.isMemberPointerToDerivedMember();
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
+ for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+ const CXXRecordDecl *Base = RD;
+ const CXXRecordDecl *Derived = Path[I];
+ if (DerivedMember)
+ std::swap(Base, Derived);
+ ThisAdjustment +=
+ getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
+ RD = Path[I];
+ }
+ if (DerivedMember)
+ ThisAdjustment = -ThisAdjustment;
+ return ThisAdjustment;
+}
+
llvm::BasicBlock *CGCXXABI::EmitCtorCompleteObjectHandler(
CodeGenFunction &CGF) {
if (CGM.getTarget().getCXXABI().hasConstructorVariants())
OpenPOWER on IntegriCloud