blob: f2fd848d264598f0ef3bd1e9f715f3e3c5bdc181 [file] [log] [blame]
Charles Davis53c59df2010-08-16 03:33:14 +00001//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner57540c52011-04-15 05:22:18 +000010// This provides C++ AST support targeting the Microsoft Visual C++
Charles Davis53c59df2010-08-16 03:33:14 +000011// ABI.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CXXABI.h"
16#include "clang/AST/ASTContext.h"
Chandler Carruth5553d0d2014-01-07 11:51:46 +000017#include "clang/AST/Attr.h"
Charles Davis53c59df2010-08-16 03:33:14 +000018#include "clang/AST/DeclCXX.h"
Reid Klecknerd8110b62013-09-10 20:14:30 +000019#include "clang/AST/MangleNumberingContext.h"
Anders Carlsson60a62632010-11-25 01:51:53 +000020#include "clang/AST/RecordLayout.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/TargetInfo.h"
Charles Davis53c59df2010-08-16 03:33:14 +000023
24using namespace clang;
25
26namespace {
Reid Klecknerd8110b62013-09-10 20:14:30 +000027
28/// \brief Numbers things which need to correspond across multiple TUs.
29/// Typically these are things like static locals, lambdas, or blocks.
30class MicrosoftNumberingContext : public MangleNumberingContext {
Reid Klecknerd8110b62013-09-10 20:14:30 +000031public:
David Majnemer2206bf52014-03-05 08:57:59 +000032 virtual unsigned getManglingNumber(const VarDecl *VD, Scope *S) {
33 return S->getMSLocalManglingNumber();
34 }
Reid Klecknerd8110b62013-09-10 20:14:30 +000035
David Majnemer2206bf52014-03-05 08:57:59 +000036 virtual unsigned getManglingNumber(const TagDecl *TD, Scope *S) {
37 return S->getMSLocalManglingNumber();
Reid Klecknerd8110b62013-09-10 20:14:30 +000038 }
39};
40
Charles Davis53c59df2010-08-16 03:33:14 +000041class MicrosoftCXXABI : public CXXABI {
42 ASTContext &Context;
43public:
44 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
45
Reid Kleckner3a52abf2013-03-28 20:02:56 +000046 std::pair<uint64_t, unsigned>
47 getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const;
Charles Davis31575f72010-10-29 03:25:11 +000048
Timur Iskhodzhanovc5098ad2012-07-12 09:50:54 +000049 CallingConv getDefaultMethodCallConv(bool isVariadic) const {
Benjamin Kramer08db4612013-04-04 17:07:04 +000050 if (!isVariadic &&
51 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
Charles Davis31575f72010-10-29 03:25:11 +000052 return CC_X86ThisCall;
Benjamin Kramer08db4612013-04-04 17:07:04 +000053 return CC_C;
Charles Davis31575f72010-10-29 03:25:11 +000054 }
Anders Carlsson60a62632010-11-25 01:51:53 +000055
56 bool isNearlyEmpty(const CXXRecordDecl *RD) const {
57 // FIXME: Audit the corners
58 if (!RD->isDynamicClass())
59 return false;
60
61 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
62
63 // In the Microsoft ABI, classes can have one or two vtable pointers.
Ken Dyck316d6f62011-02-01 01:52:10 +000064 CharUnits PointerSize =
Douglas Gregore8bbc122011-09-02 00:18:52 +000065 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
Ken Dyck316d6f62011-02-01 01:52:10 +000066 return Layout.getNonVirtualSize() == PointerSize ||
67 Layout.getNonVirtualSize() == PointerSize * 2;
Anders Carlsson60a62632010-11-25 01:51:53 +000068 }
Reid Klecknerd8110b62013-09-10 20:14:30 +000069
70 MangleNumberingContext *createMangleNumberingContext() const {
71 return new MicrosoftNumberingContext();
72 }
Charles Davis53c59df2010-08-16 03:33:14 +000073};
74}
75
Reid Kleckner3a52abf2013-03-28 20:02:56 +000076// getNumBases() seems to only give us the number of direct bases, and not the
77// total. This function tells us if we inherit from anybody that uses MI, or if
78// we have a non-primary base class, which uses the multiple inheritance model.
Benjamin Kramer08db4612013-04-04 17:07:04 +000079static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
Reid Kleckner3a52abf2013-03-28 20:02:56 +000080 while (RD->getNumBases() > 0) {
81 if (RD->getNumBases() > 1)
82 return true;
83 assert(RD->getNumBases() == 1);
Benjamin Kramer08db4612013-04-04 17:07:04 +000084 const CXXRecordDecl *Base =
85 RD->bases_begin()->getType()->getAsCXXRecordDecl();
Reid Kleckner3a52abf2013-03-28 20:02:56 +000086 if (RD->isPolymorphic() && !Base->isPolymorphic())
87 return true;
88 RD = Base;
89 }
90 return false;
91}
92
David Majnemer2c4e00a2014-01-29 22:07:36 +000093MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
94 if (!hasDefinition())
David Majnemer1cdd96d2014-01-17 09:01:00 +000095 return MSInheritanceAttr::Keyword_unspecified_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +000096 if (getNumVBases() > 0)
David Majnemer1cdd96d2014-01-17 09:01:00 +000097 return MSInheritanceAttr::Keyword_virtual_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +000098 if (usesMultipleInheritanceModel(this))
David Majnemer1cdd96d2014-01-17 09:01:00 +000099 return MSInheritanceAttr::Keyword_multiple_inheritance;
100 return MSInheritanceAttr::Keyword_single_inheritance;
101}
102
103MSInheritanceAttr::Spelling
104CXXRecordDecl::getMSInheritanceModel() const {
105 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
106 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
David Majnemer2c4e00a2014-01-29 22:07:36 +0000107 return IA->getSemanticSpelling();
David Majnemer1cdd96d2014-01-17 09:01:00 +0000108}
109
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000110MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
111 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
112 return VDA->getVtorDispMode();
113 return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
114}
115
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000116// Returns the number of pointer and integer slots used to represent a member
117// pointer in the MS C++ ABI.
118//
119// Member function pointers have the following general form; however, fields
120// are dropped as permitted (under the MSVC interpretation) by the inheritance
121// model of the actual class.
122//
123// struct {
124// // A pointer to the member function to call. If the member function is
125// // virtual, this will be a thunk that forwards to the appropriate vftable
126// // slot.
127// void *FunctionPointerOrVirtualThunk;
128//
129// // An offset to add to the address of the vbtable pointer after (possibly)
130// // selecting the virtual base but before resolving and calling the function.
131// // Only needed if the class has any virtual bases or bases at a non-zero
132// // offset.
133// int NonVirtualBaseAdjustment;
134//
Reid Kleckner96f8f932014-02-05 17:27:08 +0000135// // The offset of the vb-table pointer within the object. Only needed for
136// // incomplete types.
137// int VBPtrOffset;
138//
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000139// // An offset within the vb-table that selects the virtual base containing
140// // the member. Loading from this offset produces a new offset that is
141// // added to the address of the vb-table pointer to produce the base.
142// int VirtualBaseAdjustmentOffset;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000143// };
Reid Kleckner2341ae32013-04-11 18:13:19 +0000144static std::pair<unsigned, unsigned>
145getMSMemberPointerSlots(const MemberPointerType *MPT) {
David Majnemer1cdd96d2014-01-17 09:01:00 +0000146 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
147 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
148 unsigned Ptrs = 0;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000149 unsigned Ints = 0;
Reid Kleckner96f8f932014-02-05 17:27:08 +0000150 if (MPT->isMemberFunctionPointer())
151 Ptrs = 1;
152 else
153 Ints = 1;
154 if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
155 Inheritance))
156 Ints++;
157 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
158 Ints++;
159 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
160 Ints++;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000161 return std::make_pair(Ptrs, Ints);
162}
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000163
Benjamin Kramer08db4612013-04-04 17:07:04 +0000164std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
165 const MemberPointerType *MPT) const {
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000166 const TargetInfo &Target = Context.getTargetInfo();
167 assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
168 Target.getTriple().getArch() == llvm::Triple::x86_64);
169 unsigned Ptrs, Ints;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000170 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000171 // The nominal struct is laid out with pointers followed by ints and aligned
172 // to a pointer width if any are present and an int width otherwise.
173 unsigned PtrSize = Target.getPointerWidth(0);
174 unsigned IntSize = Target.getIntWidth();
175 uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
Reid Klecknerbd63b332014-01-31 22:28:50 +0000176 unsigned Align;
177
178 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
179 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
180 // function memptrs.
181 if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
182 Align = 8 * 8;
183 else if (Ptrs)
184 Align = Target.getPointerAlign(0);
185 else
186 Align = Target.getIntAlign();
187
188 if (Target.getTriple().getArch() == llvm::Triple::x86_64)
189 Width = llvm::RoundUpToAlignment(Width, Align);
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000190 return std::make_pair(Width, Align);
Charles Davis53c59df2010-08-16 03:33:14 +0000191}
192
193CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
194 return new MicrosoftCXXABI(Ctx);
195}
196