blob: d22a5e90728590d472ac72283d864ebafd80f663 [file] [log] [blame]
Charles Davis74ce8592010-06-09 23:25:41 +00001//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
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++ code generation targeting the Microsoft Visual C++ ABI.
Charles Davis74ce8592010-06-09 23:25:41 +000011// The class in this file generates structures that follow the Microsoft
12// Visual C++ ABI, which is actually not very well documented at all outside
13// of Microsoft.
14//
15//===----------------------------------------------------------------------===//
16
17#include "CGCXXABI.h"
18#include "CodeGenModule.h"
Charles Davis74ce8592010-06-09 23:25:41 +000019#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Charles Davis74ce8592010-06-09 23:25:41 +000021
22using namespace clang;
23using namespace CodeGen;
24
25namespace {
26
Charles Davis53c59df2010-08-16 03:33:14 +000027class MicrosoftCXXABI : public CGCXXABI {
Charles Davis74ce8592010-06-09 23:25:41 +000028public:
Peter Collingbourne0ff0b372011-01-13 18:57:25 +000029 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
John McCall5d865c322010-08-31 07:33:07 +000030
Timur Iskhodzhanov8fe501d2013-04-17 12:54:10 +000031 bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {
32 // Structures that are not C++03 PODs are always indirect.
33 return !RD->isPOD();
34 }
35
36 RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const {
37 if (RD->hasNonTrivialCopyConstructor())
38 return RAA_DirectInMemory;
39 return RAA_Default;
40 }
41
Joao Matos2ce88ef2012-07-17 17:10:11 +000042 StringRef GetPureVirtualCallName() { return "_purecall"; }
David Blaikieeb7d5982012-10-16 22:56:05 +000043 // No known support for deleted functions in MSVC yet, so this choice is
44 // arbitrary.
45 StringRef GetDeletedVirtualCallName() { return "_purecall"; }
Joao Matos2ce88ef2012-07-17 17:10:11 +000046
John McCall82fb8922012-09-25 10:10:39 +000047 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
48 llvm::Value *ptr,
49 QualType type);
50
John McCall5d865c322010-08-31 07:33:07 +000051 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
52 CXXCtorType Type,
53 CanQualType &ResTy,
John McCall0f999f32012-09-25 08:00:39 +000054 SmallVectorImpl<CanQualType> &ArgTys);
John McCall5d865c322010-08-31 07:33:07 +000055
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +000056 llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF);
57
John McCall5d865c322010-08-31 07:33:07 +000058 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
59 CXXDtorType Type,
60 CanQualType &ResTy,
Timur Iskhodzhanovee6bc532013-02-13 08:37:51 +000061 SmallVectorImpl<CanQualType> &ArgTys);
John McCall5d865c322010-08-31 07:33:07 +000062
63 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
64 QualType &ResTy,
John McCall0f999f32012-09-25 08:00:39 +000065 FunctionArgList &Params);
John McCall5d865c322010-08-31 07:33:07 +000066
John McCall0f999f32012-09-25 08:00:39 +000067 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCall29036752011-01-27 02:46:02 +000068
Manman Ren01754612013-03-20 16:59:38 +000069 llvm::Value *EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +000070 const CXXConstructorDecl *D,
71 CXXCtorType Type, bool ForVirtualBase,
72 bool Delegating,
73 llvm::Value *This,
74 CallExpr::const_arg_iterator ArgBeg,
75 CallExpr::const_arg_iterator ArgEnd);
76
Timur Iskhodzhanovd6197112013-02-15 14:45:22 +000077 RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
78 const CXXDestructorDecl *Dtor,
79 CXXDtorType DtorType,
80 SourceLocation CallLoc,
81 ReturnValueSlot ReturnValue,
82 llvm::Value *This);
83
John McCallc84ed6a2012-05-01 06:13:13 +000084 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
85 llvm::GlobalVariable *DeclPtr,
86 bool PerformInit);
87
John McCall29036752011-01-27 02:46:02 +000088 // ==== Notes on array cookies =========
89 //
90 // MSVC seems to only use cookies when the class has a destructor; a
91 // two-argument usual array deallocation function isn't sufficient.
92 //
93 // For example, this code prints "100" and "1":
94 // struct A {
95 // char x;
96 // void *operator new[](size_t sz) {
97 // printf("%u\n", sz);
98 // return malloc(sz);
99 // }
100 // void operator delete[](void *p, size_t sz) {
101 // printf("%u\n", sz);
102 // free(p);
103 // }
104 // };
105 // int main() {
106 // A *p = new A[100];
107 // delete[] p;
108 // }
109 // Whereas it prints "104" and "104" if you give A a destructor.
John McCallb91cd662012-05-01 05:23:51 +0000110
111 bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
112 bool requiresArrayCookie(const CXXNewExpr *expr);
113 CharUnits getArrayCookieSizeImpl(QualType type);
114 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
115 llvm::Value *NewPtr,
116 llvm::Value *NumElements,
117 const CXXNewExpr *expr,
118 QualType ElementType);
119 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
120 llvm::Value *allocPtr,
121 CharUnits cookieSize);
John McCall0f999f32012-09-25 08:00:39 +0000122 static bool needThisReturn(GlobalDecl GD);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000123
124private:
Reid Kleckner2341ae32013-04-11 18:13:19 +0000125 llvm::Constant *getZeroInt() {
126 return llvm::ConstantInt::get(CGM.IntTy, 0);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000127 }
128
Reid Kleckner2341ae32013-04-11 18:13:19 +0000129 llvm::Constant *getAllOnesInt() {
130 return llvm::Constant::getAllOnesValue(CGM.IntTy);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000131 }
132
Reid Kleckner2341ae32013-04-11 18:13:19 +0000133 void
134 GetNullMemberPointerFields(const MemberPointerType *MPT,
135 llvm::SmallVectorImpl<llvm::Constant *> &fields);
136
137 llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD,
138 llvm::Value *Base,
139 llvm::Value *VirtualBaseAdjustmentOffset,
140 llvm::Value *VBPtrOffset /* optional */);
141
Reid Kleckner407e8b62013-03-22 19:02:54 +0000142public:
Reid Kleckner2341ae32013-04-11 18:13:19 +0000143 virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
144
145 virtual bool isZeroInitializable(const MemberPointerType *MPT);
146
Reid Kleckner407e8b62013-03-22 19:02:54 +0000147 virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
148
149 virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
150 CharUnits offset);
151
Reid Kleckner700c3ee2013-04-30 20:15:14 +0000152 virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
153 llvm::Value *L,
154 llvm::Value *R,
155 const MemberPointerType *MPT,
156 bool Inequality);
157
Reid Kleckner407e8b62013-03-22 19:02:54 +0000158 virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
159 llvm::Value *MemPtr,
160 const MemberPointerType *MPT);
161
162 virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
163 llvm::Value *Base,
164 llvm::Value *MemPtr,
165 const MemberPointerType *MPT);
166
Reid Kleckner2341ae32013-04-11 18:13:19 +0000167 virtual llvm::Value *
168 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
169 llvm::Value *&This,
170 llvm::Value *MemPtr,
171 const MemberPointerType *MPT);
172
Charles Davis74ce8592010-06-09 23:25:41 +0000173};
174
175}
176
John McCall82fb8922012-09-25 10:10:39 +0000177llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
178 llvm::Value *ptr,
179 QualType type) {
180 // FIXME: implement
181 return ptr;
182}
183
John McCall0f999f32012-09-25 08:00:39 +0000184bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
185 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
186 return isa<CXXConstructorDecl>(MD);
187}
188
189void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
190 CXXCtorType Type,
191 CanQualType &ResTy,
192 SmallVectorImpl<CanQualType> &ArgTys) {
193 // 'this' is already in place
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000194
John McCall0f999f32012-09-25 08:00:39 +0000195 // Ctor returns this ptr
196 ResTy = ArgTys[0];
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000197
198 const CXXRecordDecl *Class = Ctor->getParent();
199 if (Class->getNumVBases()) {
200 // Constructors of classes with virtual bases take an implicit parameter.
201 ArgTys.push_back(CGM.getContext().IntTy);
202 }
203}
204
205llvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler(
206 CodeGenFunction &CGF) {
207 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
208 assert(IsMostDerivedClass &&
209 "ctor for a class with virtual bases must have an implicit parameter");
210 llvm::Value *IsCompleteObject
211 = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
212
213 llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");
214 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases");
215 CGF.Builder.CreateCondBr(IsCompleteObject,
216 CallVbaseCtorsBB, SkipVbaseCtorsBB);
217
218 CGF.EmitBlock(CallVbaseCtorsBB);
219 // FIXME: emit vbtables somewhere around here.
220
221 // CGF will put the base ctor calls in this basic block for us later.
222
223 return SkipVbaseCtorsBB;
John McCall0f999f32012-09-25 08:00:39 +0000224}
225
Timur Iskhodzhanovee6bc532013-02-13 08:37:51 +0000226void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
227 CXXDtorType Type,
228 CanQualType &ResTy,
229 SmallVectorImpl<CanQualType> &ArgTys) {
230 // 'this' is already in place
231 // TODO: 'for base' flag
232
233 if (Type == Dtor_Deleting) {
234 // The scalar deleting destructor takes an implicit bool parameter.
235 ArgTys.push_back(CGM.getContext().BoolTy);
236 }
237}
238
239static bool IsDeletingDtor(GlobalDecl GD) {
240 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
241 if (isa<CXXDestructorDecl>(MD)) {
242 return GD.getDtorType() == Dtor_Deleting;
243 }
244 return false;
245}
246
John McCall0f999f32012-09-25 08:00:39 +0000247void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
248 QualType &ResTy,
249 FunctionArgList &Params) {
250 BuildThisParam(CGF, Params);
251 if (needThisReturn(CGF.CurGD)) {
252 ResTy = Params[0]->getType();
253 }
Timur Iskhodzhanovee6bc532013-02-13 08:37:51 +0000254
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000255 ASTContext &Context = getContext();
256 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
257 if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
258 ImplicitParamDecl *IsMostDerived
259 = ImplicitParamDecl::Create(Context, 0,
260 CGF.CurGD.getDecl()->getLocation(),
261 &Context.Idents.get("is_most_derived"),
262 Context.IntTy);
263 Params.push_back(IsMostDerived);
264 getStructorImplicitParamDecl(CGF) = IsMostDerived;
265 } else if (IsDeletingDtor(CGF.CurGD)) {
Timur Iskhodzhanovee6bc532013-02-13 08:37:51 +0000266 ImplicitParamDecl *ShouldDelete
267 = ImplicitParamDecl::Create(Context, 0,
268 CGF.CurGD.getDecl()->getLocation(),
269 &Context.Idents.get("should_call_delete"),
270 Context.BoolTy);
271 Params.push_back(ShouldDelete);
272 getStructorImplicitParamDecl(CGF) = ShouldDelete;
273 }
John McCall0f999f32012-09-25 08:00:39 +0000274}
275
276void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
277 EmitThisParam(CGF);
278 if (needThisReturn(CGF.CurGD)) {
279 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
280 }
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000281
282 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
283 if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
284 assert(getStructorImplicitParamDecl(CGF) &&
285 "no implicit parameter for a constructor with virtual bases?");
286 getStructorImplicitParamValue(CGF)
287 = CGF.Builder.CreateLoad(
288 CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
289 "is_most_derived");
290 }
291
Timur Iskhodzhanovee6bc532013-02-13 08:37:51 +0000292 if (IsDeletingDtor(CGF.CurGD)) {
293 assert(getStructorImplicitParamDecl(CGF) &&
294 "no implicit parameter for a deleting destructor?");
295 getStructorImplicitParamValue(CGF)
296 = CGF.Builder.CreateLoad(
297 CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
298 "should_call_delete");
299 }
John McCall0f999f32012-09-25 08:00:39 +0000300}
301
Manman Ren01754612013-03-20 16:59:38 +0000302llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000303 const CXXConstructorDecl *D,
304 CXXCtorType Type, bool ForVirtualBase,
305 bool Delegating,
306 llvm::Value *This,
307 CallExpr::const_arg_iterator ArgBeg,
308 CallExpr::const_arg_iterator ArgEnd) {
309 assert(Type == Ctor_Complete || Type == Ctor_Base);
310 llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete);
311
312 llvm::Value *ImplicitParam = 0;
313 QualType ImplicitParamTy;
314 if (D->getParent()->getNumVBases()) {
315 ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
316 ImplicitParamTy = getContext().IntTy;
317 }
318
319 // FIXME: Provide a source location here.
320 CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
321 ImplicitParam, ImplicitParamTy,
322 ArgBeg, ArgEnd);
Manman Ren01754612013-03-20 16:59:38 +0000323 return Callee;
Timur Iskhodzhanov57cbe5c2013-02-27 13:46:31 +0000324}
325
Timur Iskhodzhanovd6197112013-02-15 14:45:22 +0000326RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
327 const CXXDestructorDecl *Dtor,
328 CXXDtorType DtorType,
329 SourceLocation CallLoc,
330 ReturnValueSlot ReturnValue,
331 llvm::Value *This) {
332 assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
333
334 // We have only one destructor in the vftable but can get both behaviors
335 // by passing an implicit bool parameter.
336 const CGFunctionInfo *FInfo
337 = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting);
338 llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
339 llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty);
340
341 ASTContext &Context = CGF.getContext();
342 llvm::Value *ImplicitParam
343 = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()),
344 DtorType == Dtor_Deleting);
345
346 return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
347 ImplicitParam, Context.BoolTy, 0, 0);
348}
349
John McCallb91cd662012-05-01 05:23:51 +0000350bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
351 QualType elementType) {
352 // Microsoft seems to completely ignore the possibility of a
353 // two-argument usual deallocation function.
354 return elementType.isDestructedType();
355}
356
357bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
358 // Microsoft seems to completely ignore the possibility of a
359 // two-argument usual deallocation function.
360 return expr->getAllocatedType().isDestructedType();
361}
362
363CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
364 // The array cookie is always a size_t; we then pad that out to the
365 // alignment of the element type.
366 ASTContext &Ctx = getContext();
367 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
368 Ctx.getTypeAlignInChars(type));
369}
370
371llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
372 llvm::Value *allocPtr,
373 CharUnits cookieSize) {
Micah Villmowea2fea22012-10-25 15:39:14 +0000374 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCallb91cd662012-05-01 05:23:51 +0000375 llvm::Value *numElementsPtr =
376 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
377 return CGF.Builder.CreateLoad(numElementsPtr);
378}
379
380llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
381 llvm::Value *newPtr,
382 llvm::Value *numElements,
383 const CXXNewExpr *expr,
384 QualType elementType) {
385 assert(requiresArrayCookie(expr));
386
387 // The size of the cookie.
388 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
389
390 // Compute an offset to the cookie.
391 llvm::Value *cookiePtr = newPtr;
392
393 // Write the number of elements into the appropriate slot.
Micah Villmowea2fea22012-10-25 15:39:14 +0000394 unsigned AS = newPtr->getType()->getPointerAddressSpace();
John McCallb91cd662012-05-01 05:23:51 +0000395 llvm::Value *numElementsPtr
396 = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
397 CGF.Builder.CreateStore(numElements, numElementsPtr);
398
399 // Finally, compute a pointer to the actual data buffer by skipping
400 // over the cookie completely.
401 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
402 cookieSize.getQuantity());
403}
404
John McCallc84ed6a2012-05-01 06:13:13 +0000405void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
406 llvm::GlobalVariable *DeclPtr,
407 bool PerformInit) {
408 // FIXME: this code was only tested for global initialization.
409 // Not sure whether we want thread-safe static local variables as VS
410 // doesn't make them thread-safe.
411
Richard Smithdbf74ba2013-04-14 23:01:42 +0000412 if (D.getTLSKind())
413 CGM.ErrorUnsupported(&D, "dynamic TLS initialization");
414
John McCallc84ed6a2012-05-01 06:13:13 +0000415 // Emit the initializer and add a global destructor if appropriate.
416 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
417}
418
Reid Kleckner2341ae32013-04-11 18:13:19 +0000419// Member pointer helpers.
420static bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) {
421 return Inheritance == MSIM_Unspecified;
Reid Kleckner407e8b62013-03-22 19:02:54 +0000422}
423
Reid Kleckner700c3ee2013-04-30 20:15:14 +0000424static bool hasOnlyOneField(MSInheritanceModel Inheritance) {
425 return Inheritance <= MSIM_SinglePolymorphic;
426}
427
Reid Kleckner2341ae32013-04-11 18:13:19 +0000428// Only member pointers to functions need a this adjustment, since it can be
429// combined with the field offset for data pointers.
430static bool hasNonVirtualBaseAdjustmentField(const MemberPointerType *MPT,
431 MSInheritanceModel Inheritance) {
432 return (MPT->isMemberFunctionPointer() &&
433 Inheritance >= MSIM_Multiple);
434}
435
436static bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) {
437 return Inheritance >= MSIM_Virtual;
438}
439
440// Use zero for the field offset of a null data member pointer if we can
441// guarantee that zero is not a valid field offset, or if the member pointer has
442// multiple fields. Polymorphic classes have a vfptr at offset zero, so we can
443// use zero for null. If there are multiple fields, we can use zero even if it
444// is a valid field offset because null-ness testing will check the other
445// fields.
446static bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) {
447 return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single;
448}
449
450bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
451 // Null-ness for function memptrs only depends on the first field, which is
452 // the function pointer. The rest don't matter, so we can zero initialize.
453 if (MPT->isMemberFunctionPointer())
454 return true;
455
456 // The virtual base adjustment field is always -1 for null, so if we have one
457 // we can't zero initialize. The field offset is sometimes also -1 if 0 is a
458 // valid field offset.
459 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
460 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
461 return (!hasVirtualBaseAdjustmentField(Inheritance) &&
462 nullFieldOffsetIsZero(Inheritance));
463}
464
465llvm::Type *
466MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
467 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
468 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
469 llvm::SmallVector<llvm::Type *, 4> fields;
470 if (MPT->isMemberFunctionPointer())
471 fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk
472 else
473 fields.push_back(CGM.IntTy); // FieldOffset
474
475 if (hasVBPtrOffsetField(Inheritance))
476 fields.push_back(CGM.IntTy);
477 if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
478 fields.push_back(CGM.IntTy);
479 if (hasVirtualBaseAdjustmentField(Inheritance))
480 fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset
481
482 if (fields.size() == 1)
483 return fields[0];
484 return llvm::StructType::get(CGM.getLLVMContext(), fields);
485}
486
487void MicrosoftCXXABI::
488GetNullMemberPointerFields(const MemberPointerType *MPT,
489 llvm::SmallVectorImpl<llvm::Constant *> &fields) {
490 assert(fields.empty());
491 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
492 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
493 if (MPT->isMemberFunctionPointer()) {
494 // FunctionPointerOrVirtualThunk
495 fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
496 } else {
497 if (nullFieldOffsetIsZero(Inheritance))
498 fields.push_back(getZeroInt()); // FieldOffset
499 else
500 fields.push_back(getAllOnesInt()); // FieldOffset
Reid Kleckner407e8b62013-03-22 19:02:54 +0000501 }
Reid Kleckner2341ae32013-04-11 18:13:19 +0000502
503 if (hasVBPtrOffsetField(Inheritance))
504 fields.push_back(getZeroInt());
505 if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
506 fields.push_back(getZeroInt());
507 if (hasVirtualBaseAdjustmentField(Inheritance))
508 fields.push_back(getAllOnesInt());
Reid Kleckner407e8b62013-03-22 19:02:54 +0000509}
510
511llvm::Constant *
512MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
Reid Kleckner2341ae32013-04-11 18:13:19 +0000513 llvm::SmallVector<llvm::Constant *, 4> fields;
514 GetNullMemberPointerFields(MPT, fields);
515 if (fields.size() == 1)
516 return fields[0];
517 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
518 assert(Res->getType() == ConvertMemberPointerType(MPT));
519 return Res;
Reid Kleckner407e8b62013-03-22 19:02:54 +0000520}
521
522llvm::Constant *
523MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
524 CharUnits offset) {
Reid Kleckner2341ae32013-04-11 18:13:19 +0000525 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
526 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
527 llvm::SmallVector<llvm::Constant *, 4> fields;
528 fields.push_back(llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()));
529 if (hasVBPtrOffsetField(Inheritance)) {
530 int64_t VBPtrOffset =
531 getContext().getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
532 fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset));
533 }
534 assert(!hasNonVirtualBaseAdjustmentField(MPT, Inheritance));
535 // The virtual base field starts out zero. It is adjusted by conversions to
536 // member pointer types of a more derived class. See http://llvm.org/PR15713
537 if (hasVirtualBaseAdjustmentField(Inheritance))
538 fields.push_back(getZeroInt());
539 if (fields.size() == 1)
540 return fields[0];
541 return llvm::ConstantStruct::getAnon(fields);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000542}
543
Reid Kleckner700c3ee2013-04-30 20:15:14 +0000544/// Member pointers are the same if they're either bitwise identical *or* both
545/// null. Null-ness for function members is determined by the first field,
546/// while for data member pointers we must compare all fields.
547llvm::Value *
548MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
549 llvm::Value *L,
550 llvm::Value *R,
551 const MemberPointerType *MPT,
552 bool Inequality) {
553 CGBuilderTy &Builder = CGF.Builder;
554
555 // Handle != comparisons by switching the sense of all boolean operations.
556 llvm::ICmpInst::Predicate Eq;
557 llvm::Instruction::BinaryOps And, Or;
558 if (Inequality) {
559 Eq = llvm::ICmpInst::ICMP_NE;
560 And = llvm::Instruction::Or;
561 Or = llvm::Instruction::And;
562 } else {
563 Eq = llvm::ICmpInst::ICMP_EQ;
564 And = llvm::Instruction::And;
565 Or = llvm::Instruction::Or;
566 }
567
568 // If this is a single field member pointer (single inheritance), this is a
569 // single icmp.
570 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
571 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
572 if (hasOnlyOneField(Inheritance))
573 return Builder.CreateICmp(Eq, L, R);
574
575 // Compare the first field.
576 llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0");
577 llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0");
578 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first");
579
580 // Compare everything other than the first field.
581 llvm::Value *Res = 0;
582 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
583 for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
584 llvm::Value *LF = Builder.CreateExtractValue(L, I);
585 llvm::Value *RF = Builder.CreateExtractValue(R, I);
586 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest");
587 if (Res)
588 Res = Builder.CreateBinOp(And, Res, Cmp);
589 else
590 Res = Cmp;
591 }
592
593 // Check if the first field is 0 if this is a function pointer.
594 if (MPT->isMemberFunctionPointer()) {
595 // (l1 == r1 && ...) || l0 == 0
596 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
597 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero");
598 Res = Builder.CreateBinOp(Or, Res, IsZero);
599 }
600
601 // Combine the comparison of the first field, which must always be true for
602 // this comparison to succeeed.
603 return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp");
604}
605
Reid Kleckner407e8b62013-03-22 19:02:54 +0000606llvm::Value *
607MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
608 llvm::Value *MemPtr,
609 const MemberPointerType *MPT) {
610 CGBuilderTy &Builder = CGF.Builder;
Reid Kleckner2341ae32013-04-11 18:13:19 +0000611 llvm::SmallVector<llvm::Constant *, 4> fields;
612 // We only need one field for member functions.
613 if (MPT->isMemberFunctionPointer())
614 fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
615 else
616 GetNullMemberPointerFields(MPT, fields);
617 assert(!fields.empty());
618 llvm::Value *FirstField = MemPtr;
619 if (MemPtr->getType()->isStructTy())
620 FirstField = Builder.CreateExtractValue(MemPtr, 0);
621 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0");
Reid Kleckner407e8b62013-03-22 19:02:54 +0000622
Reid Kleckner2341ae32013-04-11 18:13:19 +0000623 // For function member pointers, we only need to test the function pointer
624 // field. The other fields if any can be garbage.
625 if (MPT->isMemberFunctionPointer())
626 return Res;
627
628 // Otherwise, emit a series of compares and combine the results.
629 for (int I = 1, E = fields.size(); I < E; ++I) {
630 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
631 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp");
632 Res = Builder.CreateAnd(Res, Next, "memptr.tobool");
633 }
634 return Res;
635}
636
637// Returns an adjusted base cast to i8*, since we do more address arithmetic on
638// it.
639llvm::Value *
640MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
641 const CXXRecordDecl *RD, llvm::Value *Base,
642 llvm::Value *VirtualBaseAdjustmentOffset,
643 llvm::Value *VBPtrOffset) {
644 CGBuilderTy &Builder = CGF.Builder;
645 Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy);
646 llvm::BasicBlock *OriginalBB = 0;
647 llvm::BasicBlock *SkipAdjustBB = 0;
648 llvm::BasicBlock *VBaseAdjustBB = 0;
649
650 // In the unspecified inheritance model, there might not be a vbtable at all,
651 // in which case we need to skip the virtual base lookup. If there is a
652 // vbtable, the first entry is a no-op entry that gives back the original
653 // base, so look for a virtual base adjustment offset of zero.
654 if (VBPtrOffset) {
655 OriginalBB = Builder.GetInsertBlock();
656 VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust");
657 SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust");
658 llvm::Value *IsVirtual =
659 Builder.CreateICmpNE(VirtualBaseAdjustmentOffset, getZeroInt(),
660 "memptr.is_vbase");
661 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
662 CGF.EmitBlock(VBaseAdjustBB);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000663 }
664
Reid Kleckner2341ae32013-04-11 18:13:19 +0000665 // If we weren't given a dynamic vbptr offset, RD should be complete and we'll
666 // know the vbptr offset.
667 if (!VBPtrOffset) {
668 CharUnits offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
669 VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
670 }
671 // Load the vbtable pointer from the vbtable offset in the instance.
672 llvm::Value *VBPtr =
673 Builder.CreateInBoundsGEP(Base, VBPtrOffset, "memptr.vbptr");
674 llvm::Value *VBTable =
675 Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0));
676 VBTable = Builder.CreateLoad(VBTable, "memptr.vbtable");
677 // Load an i32 offset from the vb-table.
678 llvm::Value *VBaseOffs =
679 Builder.CreateInBoundsGEP(VBTable, VirtualBaseAdjustmentOffset);
680 VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0));
681 VBaseOffs = Builder.CreateLoad(VBaseOffs, "memptr.vbase_offs");
682 // Add it to VBPtr. GEP will sign extend the i32 value for us.
683 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
684
685 // Merge control flow with the case where we didn't have to adjust.
686 if (VBaseAdjustBB) {
687 Builder.CreateBr(SkipAdjustBB);
688 CGF.EmitBlock(SkipAdjustBB);
689 llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base");
690 Phi->addIncoming(Base, OriginalBB);
691 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
692 return Phi;
693 }
694 return AdjustedBase;
Reid Kleckner407e8b62013-03-22 19:02:54 +0000695}
696
697llvm::Value *
698MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
699 llvm::Value *Base,
700 llvm::Value *MemPtr,
701 const MemberPointerType *MPT) {
Reid Kleckner2341ae32013-04-11 18:13:19 +0000702 assert(MPT->isMemberDataPointer());
Reid Kleckner407e8b62013-03-22 19:02:54 +0000703 unsigned AS = Base->getType()->getPointerAddressSpace();
704 llvm::Type *PType =
705 CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
706 CGBuilderTy &Builder = CGF.Builder;
Reid Kleckner2341ae32013-04-11 18:13:19 +0000707 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
708 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
Reid Kleckner407e8b62013-03-22 19:02:54 +0000709
Reid Kleckner2341ae32013-04-11 18:13:19 +0000710 // Extract the fields we need, regardless of model. We'll apply them if we
711 // have them.
712 llvm::Value *FieldOffset = MemPtr;
713 llvm::Value *VirtualBaseAdjustmentOffset = 0;
714 llvm::Value *VBPtrOffset = 0;
715 if (MemPtr->getType()->isStructTy()) {
716 // We need to extract values.
717 unsigned I = 0;
718 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
719 if (hasVBPtrOffsetField(Inheritance))
720 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
721 if (hasVirtualBaseAdjustmentField(Inheritance))
722 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000723 }
724
Reid Kleckner2341ae32013-04-11 18:13:19 +0000725 if (VirtualBaseAdjustmentOffset) {
726 Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset,
727 VBPtrOffset);
Reid Kleckner407e8b62013-03-22 19:02:54 +0000728 }
Reid Kleckner2341ae32013-04-11 18:13:19 +0000729 llvm::Value *Addr =
730 Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset");
Reid Kleckner407e8b62013-03-22 19:02:54 +0000731
732 // Cast the address to the appropriate pointer type, adopting the address
733 // space of the base pointer.
734 return Builder.CreateBitCast(Addr, PType);
735}
736
Reid Kleckner2341ae32013-04-11 18:13:19 +0000737llvm::Value *
738MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
739 llvm::Value *&This,
740 llvm::Value *MemPtr,
741 const MemberPointerType *MPT) {
742 assert(MPT->isMemberFunctionPointer());
743 const FunctionProtoType *FPT =
744 MPT->getPointeeType()->castAs<FunctionProtoType>();
745 const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
746 llvm::FunctionType *FTy =
747 CGM.getTypes().GetFunctionType(
748 CGM.getTypes().arrangeCXXMethodType(RD, FPT));
749 CGBuilderTy &Builder = CGF.Builder;
750
751 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
752
753 // Extract the fields we need, regardless of model. We'll apply them if we
754 // have them.
755 llvm::Value *FunctionPointer = MemPtr;
756 llvm::Value *NonVirtualBaseAdjustment = NULL;
757 llvm::Value *VirtualBaseAdjustmentOffset = NULL;
758 llvm::Value *VBPtrOffset = NULL;
759 if (MemPtr->getType()->isStructTy()) {
760 // We need to extract values.
761 unsigned I = 0;
762 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
763 if (hasVBPtrOffsetField(Inheritance))
764 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
765 if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
766 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
767 if (hasVirtualBaseAdjustmentField(Inheritance))
768 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
769 }
770
771 if (VirtualBaseAdjustmentOffset) {
772 This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset,
773 VBPtrOffset);
774 }
775
776 if (NonVirtualBaseAdjustment) {
777 // Apply the adjustment and cast back to the original struct type.
778 llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
779 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
780 This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
781 }
782
783 return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
784}
785
Charles Davis53c59df2010-08-16 03:33:14 +0000786CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davis74ce8592010-06-09 23:25:41 +0000787 return new MicrosoftCXXABI(CGM);
788}
789