blob: 0603d3b7b9b5f3fbab104d67250f6a0756d0f091 [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 {
David Majnemer118da502014-08-22 04:22:50 +000031 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
32 unsigned LambdaManglingNumber;
33 unsigned StaticLocalNumber;
34
Reid Klecknerd8110b62013-09-10 20:14:30 +000035public:
David Majnemer118da502014-08-22 04:22:50 +000036 MicrosoftNumberingContext()
37 : MangleNumberingContext(), LambdaManglingNumber(0),
38 StaticLocalNumber(0) {}
39
40 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
41 return ++LambdaManglingNumber;
42 }
43
Fariborz Jahanian5afc8692014-10-01 16:56:40 +000044 unsigned getManglingNumber(const BlockDecl *BD) override {
David Majnemer118da502014-08-22 04:22:50 +000045 const Type *Ty = nullptr;
46 return ++ManglingNumbers[Ty];
47 }
48
49 unsigned getStaticLocalNumber(const VarDecl *VD) override {
50 return ++StaticLocalNumber;
51 }
52
Craig Toppercbce6e92014-03-11 06:22:39 +000053 unsigned getManglingNumber(const VarDecl *VD,
54 unsigned MSLocalManglingNumber) override {
David Majnemerf27217f2014-03-05 18:55:38 +000055 return MSLocalManglingNumber;
David Majnemer2206bf52014-03-05 08:57:59 +000056 }
Reid Klecknerd8110b62013-09-10 20:14:30 +000057
Craig Toppercbce6e92014-03-11 06:22:39 +000058 unsigned getManglingNumber(const TagDecl *TD,
59 unsigned MSLocalManglingNumber) override {
David Majnemerf27217f2014-03-05 18:55:38 +000060 return MSLocalManglingNumber;
Reid Klecknerd8110b62013-09-10 20:14:30 +000061 }
62};
63
Charles Davis53c59df2010-08-16 03:33:14 +000064class MicrosoftCXXABI : public CXXABI {
65 ASTContext &Context;
66public:
67 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
68
Reid Kleckner3a52abf2013-03-28 20:02:56 +000069 std::pair<uint64_t, unsigned>
Craig Toppercbce6e92014-03-11 06:22:39 +000070 getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
Charles Davis31575f72010-10-29 03:25:11 +000071
Craig Toppercbce6e92014-03-11 06:22:39 +000072 CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
Benjamin Kramer08db4612013-04-04 17:07:04 +000073 if (!isVariadic &&
74 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
Charles Davis31575f72010-10-29 03:25:11 +000075 return CC_X86ThisCall;
Benjamin Kramer08db4612013-04-04 17:07:04 +000076 return CC_C;
Charles Davis31575f72010-10-29 03:25:11 +000077 }
Anders Carlsson60a62632010-11-25 01:51:53 +000078
Craig Toppercbce6e92014-03-11 06:22:39 +000079 bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
Anders Carlsson60a62632010-11-25 01:51:53 +000080 // FIXME: Audit the corners
81 if (!RD->isDynamicClass())
82 return false;
83
84 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
85
86 // In the Microsoft ABI, classes can have one or two vtable pointers.
Ken Dyck316d6f62011-02-01 01:52:10 +000087 CharUnits PointerSize =
Douglas Gregore8bbc122011-09-02 00:18:52 +000088 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
Ken Dyck316d6f62011-02-01 01:52:10 +000089 return Layout.getNonVirtualSize() == PointerSize ||
90 Layout.getNonVirtualSize() == PointerSize * 2;
Anders Carlsson60a62632010-11-25 01:51:53 +000091 }
Reid Klecknerd8110b62013-09-10 20:14:30 +000092
Craig Toppercbce6e92014-03-11 06:22:39 +000093 MangleNumberingContext *createMangleNumberingContext() const override {
Reid Klecknerd8110b62013-09-10 20:14:30 +000094 return new MicrosoftNumberingContext();
95 }
Charles Davis53c59df2010-08-16 03:33:14 +000096};
97}
98
Reid Kleckner3a52abf2013-03-28 20:02:56 +000099// getNumBases() seems to only give us the number of direct bases, and not the
100// total. This function tells us if we inherit from anybody that uses MI, or if
101// we have a non-primary base class, which uses the multiple inheritance model.
Benjamin Kramer08db4612013-04-04 17:07:04 +0000102static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000103 while (RD->getNumBases() > 0) {
104 if (RD->getNumBases() > 1)
105 return true;
106 assert(RD->getNumBases() == 1);
Benjamin Kramer08db4612013-04-04 17:07:04 +0000107 const CXXRecordDecl *Base =
108 RD->bases_begin()->getType()->getAsCXXRecordDecl();
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000109 if (RD->isPolymorphic() && !Base->isPolymorphic())
110 return true;
111 RD = Base;
112 }
113 return false;
114}
115
David Majnemer2c4e00a2014-01-29 22:07:36 +0000116MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
David Majnemer5ef4fe72014-06-13 06:43:46 +0000117 if (!hasDefinition() || isParsingBaseSpecifiers())
David Majnemer1cdd96d2014-01-17 09:01:00 +0000118 return MSInheritanceAttr::Keyword_unspecified_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +0000119 if (getNumVBases() > 0)
David Majnemer1cdd96d2014-01-17 09:01:00 +0000120 return MSInheritanceAttr::Keyword_virtual_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +0000121 if (usesMultipleInheritanceModel(this))
David Majnemer1cdd96d2014-01-17 09:01:00 +0000122 return MSInheritanceAttr::Keyword_multiple_inheritance;
123 return MSInheritanceAttr::Keyword_single_inheritance;
124}
125
126MSInheritanceAttr::Spelling
127CXXRecordDecl::getMSInheritanceModel() const {
128 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
129 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
David Majnemer2c4e00a2014-01-29 22:07:36 +0000130 return IA->getSemanticSpelling();
David Majnemer1cdd96d2014-01-17 09:01:00 +0000131}
132
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000133MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
134 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
135 return VDA->getVtorDispMode();
136 return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
137}
138
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000139// Returns the number of pointer and integer slots used to represent a member
140// pointer in the MS C++ ABI.
141//
142// Member function pointers have the following general form; however, fields
143// are dropped as permitted (under the MSVC interpretation) by the inheritance
144// model of the actual class.
145//
146// struct {
147// // A pointer to the member function to call. If the member function is
148// // virtual, this will be a thunk that forwards to the appropriate vftable
149// // slot.
150// void *FunctionPointerOrVirtualThunk;
151//
152// // An offset to add to the address of the vbtable pointer after (possibly)
153// // selecting the virtual base but before resolving and calling the function.
154// // Only needed if the class has any virtual bases or bases at a non-zero
155// // offset.
156// int NonVirtualBaseAdjustment;
157//
Reid Kleckner96f8f932014-02-05 17:27:08 +0000158// // The offset of the vb-table pointer within the object. Only needed for
159// // incomplete types.
160// int VBPtrOffset;
161//
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000162// // An offset within the vb-table that selects the virtual base containing
163// // the member. Loading from this offset produces a new offset that is
164// // added to the address of the vb-table pointer to produce the base.
165// int VirtualBaseAdjustmentOffset;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000166// };
Reid Kleckner2341ae32013-04-11 18:13:19 +0000167static std::pair<unsigned, unsigned>
168getMSMemberPointerSlots(const MemberPointerType *MPT) {
David Majnemer1cdd96d2014-01-17 09:01:00 +0000169 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
170 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
171 unsigned Ptrs = 0;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000172 unsigned Ints = 0;
Reid Kleckner96f8f932014-02-05 17:27:08 +0000173 if (MPT->isMemberFunctionPointer())
174 Ptrs = 1;
175 else
176 Ints = 1;
177 if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
178 Inheritance))
179 Ints++;
180 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
181 Ints++;
182 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
183 Ints++;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000184 return std::make_pair(Ptrs, Ints);
185}
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000186
Benjamin Kramer08db4612013-04-04 17:07:04 +0000187std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
188 const MemberPointerType *MPT) const {
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000189 const TargetInfo &Target = Context.getTargetInfo();
190 assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
191 Target.getTriple().getArch() == llvm::Triple::x86_64);
192 unsigned Ptrs, Ints;
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000193 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000194 // The nominal struct is laid out with pointers followed by ints and aligned
195 // to a pointer width if any are present and an int width otherwise.
196 unsigned PtrSize = Target.getPointerWidth(0);
197 unsigned IntSize = Target.getIntWidth();
198 uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
Reid Klecknerbd63b332014-01-31 22:28:50 +0000199 unsigned Align;
200
201 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
202 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
203 // function memptrs.
204 if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
205 Align = 8 * 8;
206 else if (Ptrs)
207 Align = Target.getPointerAlign(0);
208 else
209 Align = Target.getIntAlign();
210
211 if (Target.getTriple().getArch() == llvm::Triple::x86_64)
212 Width = llvm::RoundUpToAlignment(Width, Align);
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000213 return std::make_pair(Width, Align);
Charles Davis53c59df2010-08-16 03:33:14 +0000214}
215
216CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
217 return new MicrosoftCXXABI(Ctx);
218}
219