diff options
| author | Reid Kleckner <reid@kleckner.net> | 2013-05-09 21:01:17 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2013-05-09 21:01:17 +0000 |
| commit | 452abac4b344742c94703c1165dc0f51caeff8e3 (patch) | |
| tree | 018e2872760236d164959a5968bb51a8ac3fd499 /clang/lib/CodeGen/CGCXXABI.cpp | |
| parent | f03b2e8385b476546c2f5f54fe3685cd36605e6e (diff) | |
| download | bcm5719-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.cpp | 22 |
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()) |

