aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-04-11 18:13:19 +0000
committerReid Kleckner <reid@kleckner.net>2013-04-11 18:13:19 +0000
commita3609b0c7685346308ed2c8022f94949bbfe7cdf (patch)
tree6eed7cf92072db17d06badd27a0ff359f4b613bc /lib/AST
parent413549fbd85f507855f1adb355cb855faf4d8b55 (diff)
[ms-cxxabi] Implement member pointer emission and dereferencing
Summary: Handles all inheritance models for both data and function member pointers. Also implements isZeroInitializable() and refactors some of the null member pointer code. MSVC supports converting member pointers through virtual bases, which clang does not (yet?) support. Implementing that extension is covered by http://llvm.org/15713 Reviewers: rjmccall CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D613 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179305 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 6553e9d749..fd932f7330 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -89,8 +89,8 @@ MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
if (this->getNumVBases() > 0)
return MSIM_Virtual;
if (usesMultipleInheritanceModel(this))
- return MSIM_Multiple;
- return MSIM_Single;
+ return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
+ return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
}
// Returns the number of pointer and integer slots used to represent a member
@@ -119,15 +119,15 @@ MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
//
// // The offset of the vb-table pointer within the object. Only needed for
// // incomplete types.
-// int VBTableOffset;
+// int VBPtrOffset;
// };
-std::pair<unsigned, unsigned>
-MemberPointerType::getMSMemberPointerSlots() const {
- const CXXRecordDecl *RD = this->getClass()->getAsCXXRecordDecl();
+static std::pair<unsigned, unsigned>
+getMSMemberPointerSlots(const MemberPointerType *MPT) {
+ const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
unsigned Ptrs;
unsigned Ints = 0;
- if (this->isMemberFunctionPointer()) {
+ if (MPT->isMemberFunctionPointer()) {
// Member function pointers are a struct of a function pointer followed by a
// variable number of ints depending on the inheritance model used. The
// function pointer is a real function if it is non-virtual and a vftable
@@ -137,7 +137,9 @@ MemberPointerType::getMSMemberPointerSlots() const {
switch (Inheritance) {
case MSIM_Unspecified: ++Ints; // VBTableOffset
case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
+ case MSIM_MultiplePolymorphic:
case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment
+ case MSIM_SinglePolymorphic:
case MSIM_Single: break; // Nothing
}
} else {
@@ -147,7 +149,9 @@ MemberPointerType::getMSMemberPointerSlots() const {
switch (Inheritance) {
case MSIM_Unspecified: ++Ints; // VBTableOffset
case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
+ case MSIM_MultiplePolymorphic:
case MSIM_Multiple: // Nothing
+ case MSIM_SinglePolymorphic:
case MSIM_Single: ++Ints; // Field offset
}
}
@@ -160,7 +164,7 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
Target.getTriple().getArch() == llvm::Triple::x86_64);
unsigned Ptrs, Ints;
- llvm::tie(Ptrs, Ints) = MPT->getMSMemberPointerSlots();
+ llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
// The nominal struct is laid out with pointers followed by ints and aligned
// to a pointer width if any are present and an int width otherwise.
unsigned PtrSize = Target.getPointerWidth(0);