summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-02-05 17:27:08 +0000
committerReid Kleckner <reid@kleckner.net>2014-02-05 17:27:08 +0000
commit96f8f9339d80cc34de01928550237172e6d17164 (patch)
treef439d407ce2905e718b931b5a9d50e6d0feafbda /clang/lib/AST/MicrosoftCXXABI.cpp
parent9725016af3219eab09a64e91b83c1699b86cf2e9 (diff)
downloadbcm5719-llvm-96f8f9339d80cc34de01928550237172e6d17164.tar.gz
bcm5719-llvm-96f8f9339d80cc34de01928550237172e6d17164.zip
MS ABI: Mangle member pointer template arguments
Member pointers are mangled as they would be represented at runtime. They can be a single integer literal, single decl, or a tuple with some more numbers tossed in. With Clang today, most of those numbers will be zero because we reject pointers to members of virtual bases. This change required moving VTableContextBase ownership from CodeGenVTables to ASTContext, because mangling now depends on vtable layout. I also hoisted the inheritance model helpers up to be inline static methods of MSInheritanceAttr. This makes the AST code that deals with member pointers much more readable. MSVC doesn't appear to have stable manglings of null member pointers: - Null data memptrs in function templates have a mangling collision with the first field of a non-polymorphic single inheritance class. - The mangling of null data memptrs changes if you add casts. - Large null function memptrs in class templates crash MSVC. Clang uses the class template mangling for null data memptrs and the function template mangling for null function memptrs to deal with this. Reviewers: majnemer Differential Revision: http://llvm-reviews.chandlerc.com/D2695 llvm-svn: 200857
Diffstat (limited to 'clang/lib/AST/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/AST/MicrosoftCXXABI.cpp50
1 files changed, 15 insertions, 35 deletions
diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp
index 27b3e341c4b..03d0d505514 100644
--- a/clang/lib/AST/MicrosoftCXXABI.cpp
+++ b/clang/lib/AST/MicrosoftCXXABI.cpp
@@ -136,14 +136,14 @@ void CXXRecordDecl::setMSInheritanceModel() {
// // offset.
// int NonVirtualBaseAdjustment;
//
+// // The offset of the vb-table pointer within the object. Only needed for
+// // incomplete types.
+// int VBPtrOffset;
+//
// // An offset within the vb-table that selects the virtual base containing
// // the member. Loading from this offset produces a new offset that is
// // added to the address of the vb-table pointer to produce the base.
// int VirtualBaseAdjustmentOffset;
-//
-// // The offset of the vb-table pointer within the object. Only needed for
-// // incomplete types.
-// int VBPtrOffset;
// };
static std::pair<unsigned, unsigned>
getMSMemberPointerSlots(const MemberPointerType *MPT) {
@@ -151,37 +151,17 @@ getMSMemberPointerSlots(const MemberPointerType *MPT) {
MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
unsigned Ptrs = 0;
unsigned Ints = 0;
- 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
- // slot thunk if it is virtual. The ints select the object base passed for
- // the 'this' pointer.
- Ptrs = 1; // First slot is always a function pointer.
- switch (Inheritance) {
- case MSInheritanceAttr::Keyword_unspecified_inheritance:
- ++Ints; // VBTableOffset
- case MSInheritanceAttr::Keyword_virtual_inheritance:
- ++Ints; // VirtualBaseAdjustmentOffset
- case MSInheritanceAttr::Keyword_multiple_inheritance:
- ++Ints; // NonVirtualBaseAdjustment
- case MSInheritanceAttr::Keyword_single_inheritance:
- break; // Nothing
- }
- } else {
- // Data pointers are an aggregate of ints. The first int is an offset
- // followed by vbtable-related offsets.
- Ints = 1; // We always have a field offset.
- switch (Inheritance) {
- case MSInheritanceAttr::Keyword_unspecified_inheritance:
- ++Ints; // VBTableOffset
- case MSInheritanceAttr::Keyword_virtual_inheritance:
- ++Ints; // VirtualBaseAdjustmentOffset
- case MSInheritanceAttr::Keyword_multiple_inheritance:
- case MSInheritanceAttr::Keyword_single_inheritance:
- break; // Nothing
- }
- }
+ if (MPT->isMemberFunctionPointer())
+ Ptrs = 1;
+ else
+ Ints = 1;
+ if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
+ Inheritance))
+ Ints++;
+ if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ Ints++;
+ if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ Ints++;
return std::make_pair(Ptrs, Ints);
}
OpenPOWER on IntegriCloud