[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181543 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index e117e28..f786956 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -573,22 +573,7 @@
if (!MPD)
return EmitNullMemberPointer(MPT);
- // Compute the this-adjustment.
- 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;
+ CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
return BuildMemberPointer(MD, ThisAdjustment);