blob: e25d422d23676c687df5030d235c9cd126434448 [file] [log] [blame]
Charles Davis3a811f12010-05-25 19:52:27 +00001//===------- ItaniumCXXABI.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 Lattnerfc8f0e12011-04-15 05:22:18 +000010// This provides C++ code generation targeting the Itanium C++ ABI. The class
Charles Davis3a811f12010-05-25 19:52:27 +000011// in this file generates structures that follow the Itanium C++ ABI, which is
12// documented at:
13// http://www.codesourcery.com/public/cxx-abi/abi.html
14// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
John McCallee79a4c2010-08-21 22:46:04 +000015//
16// It also supports the closely-related ARM ABI, documented at:
17// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
18//
Charles Davis3a811f12010-05-25 19:52:27 +000019//===----------------------------------------------------------------------===//
20
21#include "CGCXXABI.h"
John McCall0bab0cd2010-08-23 01:21:21 +000022#include "CGRecordLayout.h"
Charles Davis9ee494f2012-06-23 23:44:00 +000023#include "CGVTables.h"
John McCall93d557b2010-08-22 00:05:51 +000024#include "CodeGenFunction.h"
Charles Davis3a811f12010-05-25 19:52:27 +000025#include "CodeGenModule.h"
Craig Topperba77cb92012-09-15 18:47:51 +000026#include "clang/AST/Mangle.h"
27#include "clang/AST/Type.h"
Chandler Carruth3b844ba2013-01-02 11:45:17 +000028#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/Intrinsics.h"
30#include "llvm/IR/Value.h"
Charles Davis3a811f12010-05-25 19:52:27 +000031
32using namespace clang;
John McCall93d557b2010-08-22 00:05:51 +000033using namespace CodeGen;
Charles Davis3a811f12010-05-25 19:52:27 +000034
35namespace {
Charles Davis071cc7d2010-08-16 03:33:14 +000036class ItaniumCXXABI : public CodeGen::CGCXXABI {
John McCall93d557b2010-08-22 00:05:51 +000037protected:
John McCallbabc9a92010-08-22 00:59:17 +000038 bool IsARM;
John McCall0bab0cd2010-08-23 01:21:21 +000039
Charles Davis3a811f12010-05-25 19:52:27 +000040public:
John McCallbabc9a92010-08-22 00:59:17 +000041 ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
Reid Kleckner92e44d92013-03-22 16:13:10 +000042 CGCXXABI(CGM), IsARM(IsARM) { }
John McCall93d557b2010-08-22 00:05:51 +000043
John McCallf16aa102010-08-22 21:01:12 +000044 bool isZeroInitializable(const MemberPointerType *MPT);
John McCallcf2c85e2010-08-22 04:16:24 +000045
Chris Lattner9cbe4f02011-07-09 17:41:47 +000046 llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
John McCall0bab0cd2010-08-23 01:21:21 +000047
John McCall93d557b2010-08-22 00:05:51 +000048 llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
49 llvm::Value *&This,
50 llvm::Value *MemFnPtr,
51 const MemberPointerType *MPT);
John McCall3023def2010-08-22 03:04:22 +000052
John McCall6c2ab1d2010-08-31 21:07:20 +000053 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
54 llvm::Value *Base,
55 llvm::Value *MemPtr,
56 const MemberPointerType *MPT);
57
John McCall0bab0cd2010-08-23 01:21:21 +000058 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
59 const CastExpr *E,
60 llvm::Value *Src);
John McCall4d4e5c12012-02-15 01:22:51 +000061 llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
62 llvm::Constant *Src);
John McCallcf2c85e2010-08-22 04:16:24 +000063
John McCall0bab0cd2010-08-23 01:21:21 +000064 llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
John McCallcf2c85e2010-08-22 04:16:24 +000065
John McCall755d8492011-04-12 00:42:48 +000066 llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
John McCall5808ce42011-02-03 08:15:49 +000067 llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
68 CharUnits offset);
Richard Smith2d6a5672012-01-14 04:30:29 +000069 llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
70 llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
71 CharUnits ThisAdjustment);
John McCall875ab102010-08-22 06:43:33 +000072
John McCall0bab0cd2010-08-23 01:21:21 +000073 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
74 llvm::Value *L,
75 llvm::Value *R,
76 const MemberPointerType *MPT,
77 bool Inequality);
John McCalle9fd7eb2010-08-22 08:30:07 +000078
John McCall0bab0cd2010-08-23 01:21:21 +000079 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
80 llvm::Value *Addr,
81 const MemberPointerType *MPT);
John McCall4c40d982010-08-31 07:33:07 +000082
John McCallecd03b42012-09-25 10:10:39 +000083 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
84 llvm::Value *ptr,
85 QualType type);
86
John McCall4c40d982010-08-31 07:33:07 +000087 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
88 CXXCtorType T,
89 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000090 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000091
92 void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
93 CXXDtorType T,
94 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +000095 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000096
97 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
98 QualType &ResTy,
99 FunctionArgList &Params);
100
101 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCall1e7fe752010-09-02 09:58:18 +0000102
Manman Ren63fd4082013-03-20 16:59:38 +0000103 llvm::Value *EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000104 const CXXConstructorDecl *D,
105 CXXCtorType Type, bool ForVirtualBase,
106 bool Delegating,
107 llvm::Value *This,
108 CallExpr::const_arg_iterator ArgBeg,
109 CallExpr::const_arg_iterator ArgEnd);
110
Timur Iskhodzhanov0f9827f2013-02-15 14:45:22 +0000111 RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
112 const CXXDestructorDecl *Dtor,
113 CXXDtorType DtorType,
114 SourceLocation CallLoc,
115 ReturnValueSlot ReturnValue,
116 llvm::Value *This);
117
Joao Matos285baac2012-07-17 17:10:11 +0000118 StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
David Blaikie2eb9a952012-10-16 22:56:05 +0000119 StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
Joao Matos285baac2012-07-17 17:10:11 +0000120
John McCalle2b45e22012-05-01 05:23:51 +0000121 CharUnits getArrayCookieSizeImpl(QualType elementType);
John McCall1e7fe752010-09-02 09:58:18 +0000122 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
123 llvm::Value *NewPtr,
124 llvm::Value *NumElements,
John McCall6ec278d2011-01-27 09:37:56 +0000125 const CXXNewExpr *expr,
John McCall1e7fe752010-09-02 09:58:18 +0000126 QualType ElementType);
John McCalle2b45e22012-05-01 05:23:51 +0000127 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
128 llvm::Value *allocPtr,
129 CharUnits cookieSize);
John McCall5cd91b52010-09-08 01:44:27 +0000130
John McCall3030eb82010-11-06 09:44:32 +0000131 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
Chandler Carruth0f30a122012-03-30 19:44:53 +0000132 llvm::GlobalVariable *DeclPtr, bool PerformInit);
John McCall20bb1752012-05-01 06:13:13 +0000133 void registerGlobalDtor(CodeGenFunction &CGF, llvm::Constant *dtor,
134 llvm::Constant *addr);
Charles Davis3a811f12010-05-25 19:52:27 +0000135};
John McCallee79a4c2010-08-21 22:46:04 +0000136
137class ARMCXXABI : public ItaniumCXXABI {
138public:
John McCallbabc9a92010-08-22 00:59:17 +0000139 ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
John McCall4c40d982010-08-31 07:33:07 +0000140
141 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
142 CXXCtorType T,
143 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000144 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +0000145
146 void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
147 CXXDtorType T,
148 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000149 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +0000150
151 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
152 QualType &ResTy,
153 FunctionArgList &Params);
154
155 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
156
157 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
158
John McCalle2b45e22012-05-01 05:23:51 +0000159 CharUnits getArrayCookieSizeImpl(QualType elementType);
John McCall1e7fe752010-09-02 09:58:18 +0000160 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
161 llvm::Value *NewPtr,
162 llvm::Value *NumElements,
John McCall6ec278d2011-01-27 09:37:56 +0000163 const CXXNewExpr *expr,
John McCall1e7fe752010-09-02 09:58:18 +0000164 QualType ElementType);
John McCalle2b45e22012-05-01 05:23:51 +0000165 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,
166 CharUnits cookieSize);
John McCall4c40d982010-08-31 07:33:07 +0000167
John McCall4c40d982010-08-31 07:33:07 +0000168 /// \brief Returns true if the given instance method is one of the
169 /// kinds that the ARM ABI says returns 'this'.
Manman Ren63fd4082013-03-20 16:59:38 +0000170 bool HasThisReturn(GlobalDecl GD) const {
171 const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(GD.getDecl());
172 if (!MD) return false;
John McCall4c40d982010-08-31 07:33:07 +0000173 return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) ||
174 (isa<CXXConstructorDecl>(MD)));
175 }
John McCallee79a4c2010-08-21 22:46:04 +0000176};
Charles Davis3a811f12010-05-25 19:52:27 +0000177}
178
Charles Davis071cc7d2010-08-16 03:33:14 +0000179CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
John McCall96fcde02013-01-25 23:36:14 +0000180 switch (CGM.getContext().getTargetInfo().getCXXABI().getKind()) {
181 // For IR-generation purposes, there's no significant difference
182 // between the ARM and iOS ABIs.
183 case TargetCXXABI::GenericARM:
184 case TargetCXXABI::iOS:
185 return new ARMCXXABI(CGM);
Charles Davis3a811f12010-05-25 19:52:27 +0000186
Tim Northoverc264e162013-01-31 12:13:10 +0000187 // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
188 // include the other 32-bit ARM oddities: constructor/destructor return values
189 // and array cookies.
190 case TargetCXXABI::GenericAArch64:
191 return new ItaniumCXXABI(CGM, /*IsARM = */ true);
192
John McCall96fcde02013-01-25 23:36:14 +0000193 case TargetCXXABI::GenericItanium:
194 return new ItaniumCXXABI(CGM);
195
196 case TargetCXXABI::Microsoft:
197 llvm_unreachable("Microsoft ABI is not Itanium-based");
198 }
199 llvm_unreachable("bad ABI kind");
John McCallee79a4c2010-08-21 22:46:04 +0000200}
201
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000202llvm::Type *
John McCall0bab0cd2010-08-23 01:21:21 +0000203ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
204 if (MPT->isMemberDataPointer())
Reid Kleckner92e44d92013-03-22 16:13:10 +0000205 return CGM.PtrDiffTy;
206 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, NULL);
John McCall875ab102010-08-22 06:43:33 +0000207}
208
John McCallbabc9a92010-08-22 00:59:17 +0000209/// In the Itanium and ARM ABIs, method pointers have the form:
210/// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
211///
212/// In the Itanium ABI:
213/// - method pointers are virtual if (memptr.ptr & 1) is nonzero
214/// - the this-adjustment is (memptr.adj)
215/// - the virtual offset is (memptr.ptr - 1)
216///
217/// In the ARM ABI:
218/// - method pointers are virtual if (memptr.adj & 1) is nonzero
219/// - the this-adjustment is (memptr.adj >> 1)
220/// - the virtual offset is (memptr.ptr)
221/// ARM uses 'adj' for the virtual flag because Thumb functions
222/// may be only single-byte aligned.
223///
224/// If the member is virtual, the adjusted 'this' pointer points
225/// to a vtable pointer from which the virtual offset is applied.
226///
227/// If the member is non-virtual, memptr.ptr is the address of
228/// the function to call.
John McCall93d557b2010-08-22 00:05:51 +0000229llvm::Value *
230ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
231 llvm::Value *&This,
232 llvm::Value *MemFnPtr,
233 const MemberPointerType *MPT) {
234 CGBuilderTy &Builder = CGF.Builder;
235
236 const FunctionProtoType *FPT =
237 MPT->getPointeeType()->getAs<FunctionProtoType>();
238 const CXXRecordDecl *RD =
239 cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
240
Chris Lattner2acc6e32011-07-18 04:24:23 +0000241 llvm::FunctionType *FTy =
John McCallde5d3c72012-02-17 03:33:10 +0000242 CGM.getTypes().GetFunctionType(
243 CGM.getTypes().arrangeCXXMethodType(RD, FPT));
John McCall93d557b2010-08-22 00:05:51 +0000244
Reid Kleckner92e44d92013-03-22 16:13:10 +0000245 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
John McCall93d557b2010-08-22 00:05:51 +0000246
John McCallbabc9a92010-08-22 00:59:17 +0000247 llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
248 llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
249 llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
250
John McCalld608cdb2010-08-22 10:59:02 +0000251 // Extract memptr.adj, which is in the second field.
252 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
John McCallbabc9a92010-08-22 00:59:17 +0000253
254 // Compute the true adjustment.
255 llvm::Value *Adj = RawAdj;
256 if (IsARM)
257 Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
John McCall93d557b2010-08-22 00:05:51 +0000258
259 // Apply the adjustment and cast back to the original struct type
260 // for consistency.
John McCallbabc9a92010-08-22 00:59:17 +0000261 llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
262 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
263 This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
John McCall93d557b2010-08-22 00:05:51 +0000264
265 // Load the function pointer.
John McCalld608cdb2010-08-22 10:59:02 +0000266 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
John McCall93d557b2010-08-22 00:05:51 +0000267
268 // If the LSB in the function pointer is 1, the function pointer points to
269 // a virtual function.
John McCallbabc9a92010-08-22 00:59:17 +0000270 llvm::Value *IsVirtual;
271 if (IsARM)
272 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
273 else
274 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
275 IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
John McCall93d557b2010-08-22 00:05:51 +0000276 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
277
278 // In the virtual path, the adjustment left 'This' pointing to the
279 // vtable of the correct base subobject. The "function pointer" is an
John McCallbabc9a92010-08-22 00:59:17 +0000280 // offset within the vtable (+1 for the virtual flag on non-ARM).
John McCall93d557b2010-08-22 00:05:51 +0000281 CGF.EmitBlock(FnVirtual);
282
283 // Cast the adjusted this to a pointer to vtable pointer and load.
Chris Lattner2acc6e32011-07-18 04:24:23 +0000284 llvm::Type *VTableTy = Builder.getInt8PtrTy();
John McCall93d557b2010-08-22 00:05:51 +0000285 llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
John McCallbabc9a92010-08-22 00:59:17 +0000286 VTable = Builder.CreateLoad(VTable, "memptr.vtable");
John McCall93d557b2010-08-22 00:05:51 +0000287
288 // Apply the offset.
John McCallbabc9a92010-08-22 00:59:17 +0000289 llvm::Value *VTableOffset = FnAsInt;
290 if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
291 VTable = Builder.CreateGEP(VTable, VTableOffset);
John McCall93d557b2010-08-22 00:05:51 +0000292
293 // Load the virtual function to call.
294 VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
John McCallbabc9a92010-08-22 00:59:17 +0000295 llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
John McCall93d557b2010-08-22 00:05:51 +0000296 CGF.EmitBranch(FnEnd);
297
298 // In the non-virtual path, the function pointer is actually a
299 // function pointer.
300 CGF.EmitBlock(FnNonVirtual);
301 llvm::Value *NonVirtualFn =
John McCallbabc9a92010-08-22 00:59:17 +0000302 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
John McCall93d557b2010-08-22 00:05:51 +0000303
304 // We're done.
305 CGF.EmitBlock(FnEnd);
Jay Foadbbf3bac2011-03-30 11:28:58 +0000306 llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
John McCall93d557b2010-08-22 00:05:51 +0000307 Callee->addIncoming(VirtualFn, FnVirtual);
308 Callee->addIncoming(NonVirtualFn, FnNonVirtual);
309 return Callee;
310}
John McCall3023def2010-08-22 03:04:22 +0000311
John McCall6c2ab1d2010-08-31 21:07:20 +0000312/// Compute an l-value by applying the given pointer-to-member to a
313/// base object.
314llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
315 llvm::Value *Base,
316 llvm::Value *MemPtr,
317 const MemberPointerType *MPT) {
Reid Kleckner92e44d92013-03-22 16:13:10 +0000318 assert(MemPtr->getType() == CGM.PtrDiffTy);
John McCall6c2ab1d2010-08-31 21:07:20 +0000319
320 CGBuilderTy &Builder = CGF.Builder;
321
Micah Villmow956a5a12012-10-25 15:39:14 +0000322 unsigned AS = Base->getType()->getPointerAddressSpace();
John McCall6c2ab1d2010-08-31 21:07:20 +0000323
324 // Cast to char*.
325 Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
326
327 // Apply the offset, which we assume is non-null.
328 llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
329
330 // Cast the address to the appropriate pointer type, adopting the
331 // address space of the base pointer.
Chris Lattner2acc6e32011-07-18 04:24:23 +0000332 llvm::Type *PType
Douglas Gregoreede61a2010-09-02 17:38:50 +0000333 = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
John McCall6c2ab1d2010-08-31 21:07:20 +0000334 return Builder.CreateBitCast(Addr, PType);
335}
336
John McCall4d4e5c12012-02-15 01:22:51 +0000337/// Perform a bitcast, derived-to-base, or base-to-derived member pointer
338/// conversion.
339///
340/// Bitcast conversions are always a no-op under Itanium.
John McCall0bab0cd2010-08-23 01:21:21 +0000341///
342/// Obligatory offset/adjustment diagram:
343/// <-- offset --> <-- adjustment -->
344/// |--------------------------|----------------------|--------------------|
345/// ^Derived address point ^Base address point ^Member address point
346///
347/// So when converting a base member pointer to a derived member pointer,
348/// we add the offset to the adjustment because the address point has
349/// decreased; and conversely, when converting a derived MP to a base MP
350/// we subtract the offset from the adjustment because the address point
351/// has increased.
352///
353/// The standard forbids (at compile time) conversion to and from
354/// virtual bases, which is why we don't have to consider them here.
355///
356/// The standard forbids (at run time) casting a derived MP to a base
357/// MP when the derived MP does not point to a member of the base.
358/// This is why -1 is a reasonable choice for null data member
359/// pointers.
John McCalld608cdb2010-08-22 10:59:02 +0000360llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000361ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
362 const CastExpr *E,
John McCall4d4e5c12012-02-15 01:22:51 +0000363 llvm::Value *src) {
John McCall2de56d12010-08-25 11:45:40 +0000364 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
John McCall4d4e5c12012-02-15 01:22:51 +0000365 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
366 E->getCastKind() == CK_ReinterpretMemberPointer);
367
368 // Under Itanium, reinterprets don't require any additional processing.
369 if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
370
371 // Use constant emission if we can.
372 if (isa<llvm::Constant>(src))
373 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
374
375 llvm::Constant *adj = getMemberPointerAdjustment(E);
376 if (!adj) return src;
John McCall3023def2010-08-22 03:04:22 +0000377
378 CGBuilderTy &Builder = CGF.Builder;
John McCall4d4e5c12012-02-15 01:22:51 +0000379 bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
John McCall3023def2010-08-22 03:04:22 +0000380
John McCall4d4e5c12012-02-15 01:22:51 +0000381 const MemberPointerType *destTy =
382 E->getType()->castAs<MemberPointerType>();
John McCall875ab102010-08-22 06:43:33 +0000383
John McCall0bab0cd2010-08-23 01:21:21 +0000384 // For member data pointers, this is just a matter of adding the
385 // offset if the source is non-null.
John McCall4d4e5c12012-02-15 01:22:51 +0000386 if (destTy->isMemberDataPointer()) {
387 llvm::Value *dst;
388 if (isDerivedToBase)
389 dst = Builder.CreateNSWSub(src, adj, "adj");
John McCall0bab0cd2010-08-23 01:21:21 +0000390 else
John McCall4d4e5c12012-02-15 01:22:51 +0000391 dst = Builder.CreateNSWAdd(src, adj, "adj");
John McCall0bab0cd2010-08-23 01:21:21 +0000392
393 // Null check.
John McCall4d4e5c12012-02-15 01:22:51 +0000394 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
395 llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
396 return Builder.CreateSelect(isNull, src, dst);
John McCall0bab0cd2010-08-23 01:21:21 +0000397 }
398
John McCalld608cdb2010-08-22 10:59:02 +0000399 // The this-adjustment is left-shifted by 1 on ARM.
400 if (IsARM) {
John McCall4d4e5c12012-02-15 01:22:51 +0000401 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
402 offset <<= 1;
403 adj = llvm::ConstantInt::get(adj->getType(), offset);
John McCalld608cdb2010-08-22 10:59:02 +0000404 }
405
John McCall4d4e5c12012-02-15 01:22:51 +0000406 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
407 llvm::Value *dstAdj;
408 if (isDerivedToBase)
409 dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
John McCalld608cdb2010-08-22 10:59:02 +0000410 else
John McCall4d4e5c12012-02-15 01:22:51 +0000411 dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
John McCalld608cdb2010-08-22 10:59:02 +0000412
John McCall4d4e5c12012-02-15 01:22:51 +0000413 return Builder.CreateInsertValue(src, dstAdj, 1);
414}
415
416llvm::Constant *
417ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
418 llvm::Constant *src) {
419 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
420 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
421 E->getCastKind() == CK_ReinterpretMemberPointer);
422
423 // Under Itanium, reinterprets don't require any additional processing.
424 if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
425
426 // If the adjustment is trivial, we don't need to do anything.
427 llvm::Constant *adj = getMemberPointerAdjustment(E);
428 if (!adj) return src;
429
430 bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
431
432 const MemberPointerType *destTy =
433 E->getType()->castAs<MemberPointerType>();
434
435 // For member data pointers, this is just a matter of adding the
436 // offset if the source is non-null.
437 if (destTy->isMemberDataPointer()) {
438 // null maps to null.
439 if (src->isAllOnesValue()) return src;
440
441 if (isDerivedToBase)
442 return llvm::ConstantExpr::getNSWSub(src, adj);
443 else
444 return llvm::ConstantExpr::getNSWAdd(src, adj);
445 }
446
447 // The this-adjustment is left-shifted by 1 on ARM.
448 if (IsARM) {
449 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
450 offset <<= 1;
451 adj = llvm::ConstantInt::get(adj->getType(), offset);
452 }
453
454 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
455 llvm::Constant *dstAdj;
456 if (isDerivedToBase)
457 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
458 else
459 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
460
461 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
John McCall3023def2010-08-22 03:04:22 +0000462}
John McCallcf2c85e2010-08-22 04:16:24 +0000463
464llvm::Constant *
John McCall0bab0cd2010-08-23 01:21:21 +0000465ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
John McCall0bab0cd2010-08-23 01:21:21 +0000466 // Itanium C++ ABI 2.3:
467 // A NULL pointer is represented as -1.
468 if (MPT->isMemberDataPointer())
Reid Kleckner92e44d92013-03-22 16:13:10 +0000469 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);
John McCalld608cdb2010-08-22 10:59:02 +0000470
Reid Kleckner92e44d92013-03-22 16:13:10 +0000471 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
John McCalld608cdb2010-08-22 10:59:02 +0000472 llvm::Constant *Values[2] = { Zero, Zero };
Chris Lattnerc5cbb902011-06-20 04:01:35 +0000473 return llvm::ConstantStruct::getAnon(Values);
John McCallcf2c85e2010-08-22 04:16:24 +0000474}
475
John McCall5808ce42011-02-03 08:15:49 +0000476llvm::Constant *
477ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
478 CharUnits offset) {
John McCall0bab0cd2010-08-23 01:21:21 +0000479 // Itanium C++ ABI 2.3:
480 // A pointer to data member is an offset from the base address of
481 // the class object containing it, represented as a ptrdiff_t
Reid Kleckner92e44d92013-03-22 16:13:10 +0000482 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
John McCall0bab0cd2010-08-23 01:21:21 +0000483}
484
John McCall755d8492011-04-12 00:42:48 +0000485llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
Richard Smith2d6a5672012-01-14 04:30:29 +0000486 return BuildMemberPointer(MD, CharUnits::Zero());
487}
488
489llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
490 CharUnits ThisAdjustment) {
John McCalld608cdb2010-08-22 10:59:02 +0000491 assert(MD->isInstance() && "Member function must not be static!");
492 MD = MD->getCanonicalDecl();
493
494 CodeGenTypes &Types = CGM.getTypes();
John McCalld608cdb2010-08-22 10:59:02 +0000495
496 // Get the function pointer (or index if this is a virtual function).
497 llvm::Constant *MemPtr[2];
498 if (MD->isVirtual()) {
Peter Collingbourne1d2b3172011-09-26 01:56:30 +0000499 uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
John McCalld608cdb2010-08-22 10:59:02 +0000500
Ken Dyck1246ba62011-04-09 01:30:02 +0000501 const ASTContext &Context = getContext();
502 CharUnits PointerWidth =
Douglas Gregorbcfd1f52011-09-02 00:18:52 +0000503 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
Ken Dyck1246ba62011-04-09 01:30:02 +0000504 uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
John McCalld608cdb2010-08-22 10:59:02 +0000505
506 if (IsARM) {
507 // ARM C++ ABI 3.2.1:
508 // This ABI specifies that adj contains twice the this
509 // adjustment, plus 1 if the member function is virtual. The
510 // least significant bit of adj then makes exactly the same
511 // discrimination as the least significant bit of ptr does for
512 // Itanium.
Reid Kleckner92e44d92013-03-22 16:13:10 +0000513 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
514 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
Richard Smith2d6a5672012-01-14 04:30:29 +0000515 2 * ThisAdjustment.getQuantity() + 1);
John McCalld608cdb2010-08-22 10:59:02 +0000516 } else {
517 // Itanium C++ ABI 2.3:
518 // For a virtual function, [the pointer field] is 1 plus the
519 // virtual table offset (in bytes) of the function,
520 // represented as a ptrdiff_t.
Reid Kleckner92e44d92013-03-22 16:13:10 +0000521 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
522 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
Richard Smith2d6a5672012-01-14 04:30:29 +0000523 ThisAdjustment.getQuantity());
John McCalld608cdb2010-08-22 10:59:02 +0000524 }
525 } else {
John McCall755d8492011-04-12 00:42:48 +0000526 const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
Chris Lattner2acc6e32011-07-18 04:24:23 +0000527 llvm::Type *Ty;
John McCall755d8492011-04-12 00:42:48 +0000528 // Check whether the function has a computable LLVM signature.
Chris Lattnerf742eb02011-07-10 00:18:59 +0000529 if (Types.isFuncTypeConvertible(FPT)) {
John McCall755d8492011-04-12 00:42:48 +0000530 // The function has a computable LLVM signature; use the correct type.
John McCallde5d3c72012-02-17 03:33:10 +0000531 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
John McCalld608cdb2010-08-22 10:59:02 +0000532 } else {
John McCall755d8492011-04-12 00:42:48 +0000533 // Use an arbitrary non-function type to tell GetAddrOfFunction that the
534 // function type is incomplete.
Reid Kleckner92e44d92013-03-22 16:13:10 +0000535 Ty = CGM.PtrDiffTy;
John McCalld608cdb2010-08-22 10:59:02 +0000536 }
John McCall755d8492011-04-12 00:42:48 +0000537 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
John McCalld608cdb2010-08-22 10:59:02 +0000538
Reid Kleckner92e44d92013-03-22 16:13:10 +0000539 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
540 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, (IsARM ? 2 : 1) *
Richard Smith2d6a5672012-01-14 04:30:29 +0000541 ThisAdjustment.getQuantity());
John McCalld608cdb2010-08-22 10:59:02 +0000542 }
John McCall875ab102010-08-22 06:43:33 +0000543
Chris Lattnerc5cbb902011-06-20 04:01:35 +0000544 return llvm::ConstantStruct::getAnon(MemPtr);
John McCall875ab102010-08-22 06:43:33 +0000545}
546
Richard Smith2d6a5672012-01-14 04:30:29 +0000547llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
548 QualType MPType) {
549 const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();
550 const ValueDecl *MPD = MP.getMemberPointerDecl();
551 if (!MPD)
552 return EmitNullMemberPointer(MPT);
553
554 // Compute the this-adjustment.
555 CharUnits ThisAdjustment = CharUnits::Zero();
556 ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
557 bool DerivedMember = MP.isMemberPointerToDerivedMember();
558 const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
559 for (unsigned I = 0, N = Path.size(); I != N; ++I) {
560 const CXXRecordDecl *Base = RD;
561 const CXXRecordDecl *Derived = Path[I];
562 if (DerivedMember)
563 std::swap(Base, Derived);
564 ThisAdjustment +=
565 getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
566 RD = Path[I];
567 }
568 if (DerivedMember)
569 ThisAdjustment = -ThisAdjustment;
570
571 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
572 return BuildMemberPointer(MD, ThisAdjustment);
573
574 CharUnits FieldOffset =
575 getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
576 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
577}
578
John McCalle9fd7eb2010-08-22 08:30:07 +0000579/// The comparison algorithm is pretty easy: the member pointers are
580/// the same if they're either bitwise identical *or* both null.
581///
582/// ARM is different here only because null-ness is more complicated.
583llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000584ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
585 llvm::Value *L,
586 llvm::Value *R,
587 const MemberPointerType *MPT,
588 bool Inequality) {
John McCalle9fd7eb2010-08-22 08:30:07 +0000589 CGBuilderTy &Builder = CGF.Builder;
590
John McCalle9fd7eb2010-08-22 08:30:07 +0000591 llvm::ICmpInst::Predicate Eq;
592 llvm::Instruction::BinaryOps And, Or;
593 if (Inequality) {
594 Eq = llvm::ICmpInst::ICMP_NE;
595 And = llvm::Instruction::Or;
596 Or = llvm::Instruction::And;
597 } else {
598 Eq = llvm::ICmpInst::ICMP_EQ;
599 And = llvm::Instruction::And;
600 Or = llvm::Instruction::Or;
601 }
602
John McCall0bab0cd2010-08-23 01:21:21 +0000603 // Member data pointers are easy because there's a unique null
604 // value, so it just comes down to bitwise equality.
605 if (MPT->isMemberDataPointer())
606 return Builder.CreateICmp(Eq, L, R);
607
608 // For member function pointers, the tautologies are more complex.
609 // The Itanium tautology is:
John McCallde719f72010-08-23 06:56:36 +0000610 // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
John McCall0bab0cd2010-08-23 01:21:21 +0000611 // The ARM tautology is:
John McCallde719f72010-08-23 06:56:36 +0000612 // (L == R) <==> (L.ptr == R.ptr &&
613 // (L.adj == R.adj ||
614 // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
John McCall0bab0cd2010-08-23 01:21:21 +0000615 // The inequality tautologies have exactly the same structure, except
616 // applying De Morgan's laws.
617
618 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
619 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
620
John McCalle9fd7eb2010-08-22 08:30:07 +0000621 // This condition tests whether L.ptr == R.ptr. This must always be
622 // true for equality to hold.
623 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
624
625 // This condition, together with the assumption that L.ptr == R.ptr,
626 // tests whether the pointers are both null. ARM imposes an extra
627 // condition.
628 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
629 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
630
631 // This condition tests whether L.adj == R.adj. If this isn't
632 // true, the pointers are unequal unless they're both null.
John McCalld608cdb2010-08-22 10:59:02 +0000633 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
634 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
John McCalle9fd7eb2010-08-22 08:30:07 +0000635 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
636
637 // Null member function pointers on ARM clear the low bit of Adj,
638 // so the zero condition has to check that neither low bit is set.
639 if (IsARM) {
640 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
641
642 // Compute (l.adj | r.adj) & 1 and test it against zero.
643 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
644 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
645 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
646 "cmp.or.adj");
647 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
648 }
649
650 // Tie together all our conditions.
651 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
652 Result = Builder.CreateBinOp(And, PtrEq, Result,
653 Inequality ? "memptr.ne" : "memptr.eq");
654 return Result;
655}
656
657llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000658ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
659 llvm::Value *MemPtr,
660 const MemberPointerType *MPT) {
John McCalle9fd7eb2010-08-22 08:30:07 +0000661 CGBuilderTy &Builder = CGF.Builder;
John McCall0bab0cd2010-08-23 01:21:21 +0000662
663 /// For member data pointers, this is just a check against -1.
664 if (MPT->isMemberDataPointer()) {
Reid Kleckner92e44d92013-03-22 16:13:10 +0000665 assert(MemPtr->getType() == CGM.PtrDiffTy);
John McCall0bab0cd2010-08-23 01:21:21 +0000666 llvm::Value *NegativeOne =
667 llvm::Constant::getAllOnesValue(MemPtr->getType());
668 return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
669 }
John McCalle9fd7eb2010-08-22 08:30:07 +0000670
Daniel Dunbardb27b5f2011-04-19 23:10:47 +0000671 // In Itanium, a member function pointer is not null if 'ptr' is not null.
John McCalld608cdb2010-08-22 10:59:02 +0000672 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
John McCalle9fd7eb2010-08-22 08:30:07 +0000673
674 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
675 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
676
Daniel Dunbardb27b5f2011-04-19 23:10:47 +0000677 // On ARM, a member function pointer is also non-null if the low bit of 'adj'
678 // (the virtual bit) is set.
John McCalle9fd7eb2010-08-22 08:30:07 +0000679 if (IsARM) {
680 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
John McCalld608cdb2010-08-22 10:59:02 +0000681 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
John McCalle9fd7eb2010-08-22 08:30:07 +0000682 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
Daniel Dunbardb27b5f2011-04-19 23:10:47 +0000683 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
684 "memptr.isvirtual");
685 Result = Builder.CreateOr(Result, IsVirtual);
John McCalle9fd7eb2010-08-22 08:30:07 +0000686 }
687
688 return Result;
689}
John McCall875ab102010-08-22 06:43:33 +0000690
John McCallf16aa102010-08-22 21:01:12 +0000691/// The Itanium ABI requires non-zero initialization only for data
692/// member pointers, for which '0' is a valid offset.
693bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
694 return MPT->getPointeeType()->isFunctionType();
John McCallcf2c85e2010-08-22 04:16:24 +0000695}
John McCall4c40d982010-08-31 07:33:07 +0000696
John McCallecd03b42012-09-25 10:10:39 +0000697/// The Itanium ABI always places an offset to the complete object
698/// at entry -2 in the vtable.
699llvm::Value *ItaniumCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
700 llvm::Value *ptr,
701 QualType type) {
702 // Grab the vtable pointer as an intptr_t*.
703 llvm::Value *vtable = CGF.GetVTablePtr(ptr, CGF.IntPtrTy->getPointerTo());
704
705 // Track back to entry -2 and pull out the offset there.
706 llvm::Value *offsetPtr =
707 CGF.Builder.CreateConstInBoundsGEP1_64(vtable, -2, "complete-offset.ptr");
708 llvm::LoadInst *offset = CGF.Builder.CreateLoad(offsetPtr);
709 offset->setAlignment(CGF.PointerAlignInBytes);
710
711 // Apply the offset.
712 ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy);
713 return CGF.Builder.CreateInBoundsGEP(ptr, offset);
714}
715
John McCall4c40d982010-08-31 07:33:07 +0000716/// The generic ABI passes 'this', plus a VTT if it's initializing a
717/// base subobject.
718void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
719 CXXCtorType Type,
720 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000721 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall9cb2cee2010-09-02 10:25:57 +0000722 ASTContext &Context = getContext();
John McCall4c40d982010-08-31 07:33:07 +0000723
724 // 'this' is already there.
725
726 // Check if we need to add a VTT parameter (which has type void **).
727 if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
728 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
729}
730
731/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
732void ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
733 CXXCtorType Type,
734 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000735 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +0000736 ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
737 ResTy = ArgTys[0];
738}
739
740/// The generic ABI passes 'this', plus a VTT if it's destroying a
741/// base subobject.
742void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
743 CXXDtorType Type,
744 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000745 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall9cb2cee2010-09-02 10:25:57 +0000746 ASTContext &Context = getContext();
John McCall4c40d982010-08-31 07:33:07 +0000747
748 // 'this' is already there.
749
750 // Check if we need to add a VTT parameter (which has type void **).
751 if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
752 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
753}
754
755/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
756/// for non-deleting destructors.
757void ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
758 CXXDtorType Type,
759 CanQualType &ResTy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000760 SmallVectorImpl<CanQualType> &ArgTys) {
John McCall4c40d982010-08-31 07:33:07 +0000761 ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
762
763 if (Type != Dtor_Deleting)
764 ResTy = ArgTys[0];
765}
766
767void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
768 QualType &ResTy,
769 FunctionArgList &Params) {
770 /// Create the 'this' variable.
771 BuildThisParam(CGF, Params);
772
773 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
774 assert(MD->isInstance());
775
776 // Check if we need a VTT parameter as well.
777 if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
John McCall9cb2cee2010-09-02 10:25:57 +0000778 ASTContext &Context = getContext();
John McCall4c40d982010-08-31 07:33:07 +0000779
780 // FIXME: avoid the fake decl
781 QualType T = Context.getPointerType(Context.VoidPtrTy);
782 ImplicitParamDecl *VTTDecl
783 = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
784 &Context.Idents.get("vtt"), T);
John McCalld26bc762011-03-09 04:27:21 +0000785 Params.push_back(VTTDecl);
John McCall4c40d982010-08-31 07:33:07 +0000786 getVTTDecl(CGF) = VTTDecl;
787 }
788}
789
790void ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
791 QualType &ResTy,
792 FunctionArgList &Params) {
793 ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
794
795 // Return 'this' from certain constructors and destructors.
796 if (HasThisReturn(CGF.CurGD))
John McCalld26bc762011-03-09 04:27:21 +0000797 ResTy = Params[0]->getType();
John McCall4c40d982010-08-31 07:33:07 +0000798}
799
800void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
801 /// Initialize the 'this' slot.
802 EmitThisParam(CGF);
803
804 /// Initialize the 'vtt' slot if needed.
805 if (getVTTDecl(CGF)) {
806 getVTTValue(CGF)
807 = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
808 "vtt");
809 }
810}
811
812void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
813 ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
814
815 /// Initialize the return slot to 'this' at the start of the
816 /// function.
817 if (HasThisReturn(CGF.CurGD))
Eli Friedmancec5ebd2012-02-11 02:57:39 +0000818 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
John McCall4c40d982010-08-31 07:33:07 +0000819}
820
Manman Ren63fd4082013-03-20 16:59:38 +0000821llvm::Value *ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000822 const CXXConstructorDecl *D,
823 CXXCtorType Type, bool ForVirtualBase,
824 bool Delegating,
825 llvm::Value *This,
826 CallExpr::const_arg_iterator ArgBeg,
827 CallExpr::const_arg_iterator ArgEnd) {
828 llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase,
829 Delegating);
830 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
831 llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
832
833 // FIXME: Provide a source location here.
834 CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
835 VTT, VTTTy, ArgBeg, ArgEnd);
Manman Ren63fd4082013-03-20 16:59:38 +0000836 return Callee;
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000837}
838
Timur Iskhodzhanov0f9827f2013-02-15 14:45:22 +0000839RValue ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
840 const CXXDestructorDecl *Dtor,
841 CXXDtorType DtorType,
842 SourceLocation CallLoc,
843 ReturnValueSlot ReturnValue,
844 llvm::Value *This) {
845 assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
846
847 const CGFunctionInfo *FInfo
848 = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType);
849 llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
850 llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, DtorType, This, Ty);
851
852 return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
853 /*ImplicitParam=*/0, QualType(), 0, 0);
854}
855
John McCall4c40d982010-08-31 07:33:07 +0000856void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
857 RValue RV, QualType ResultType) {
858 if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
859 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
860
861 // Destructor thunks in the ARM ABI have indeterminate results.
Chris Lattner2acc6e32011-07-18 04:24:23 +0000862 llvm::Type *T =
John McCall4c40d982010-08-31 07:33:07 +0000863 cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
864 RValue Undef = RValue::get(llvm::UndefValue::get(T));
865 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
866}
John McCall1e7fe752010-09-02 09:58:18 +0000867
868/************************** Array allocation cookies **************************/
869
John McCalle2b45e22012-05-01 05:23:51 +0000870CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
871 // The array cookie is a size_t; pad that up to the element alignment.
872 // The cookie is actually right-justified in that space.
873 return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
874 CGM.getContext().getTypeAlignInChars(elementType));
John McCall1e7fe752010-09-02 09:58:18 +0000875}
876
877llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
878 llvm::Value *NewPtr,
879 llvm::Value *NumElements,
John McCall6ec278d2011-01-27 09:37:56 +0000880 const CXXNewExpr *expr,
John McCall1e7fe752010-09-02 09:58:18 +0000881 QualType ElementType) {
John McCalle2b45e22012-05-01 05:23:51 +0000882 assert(requiresArrayCookie(expr));
John McCall1e7fe752010-09-02 09:58:18 +0000883
Micah Villmow956a5a12012-10-25 15:39:14 +0000884 unsigned AS = NewPtr->getType()->getPointerAddressSpace();
John McCall1e7fe752010-09-02 09:58:18 +0000885
John McCall9cb2cee2010-09-02 10:25:57 +0000886 ASTContext &Ctx = getContext();
John McCall1e7fe752010-09-02 09:58:18 +0000887 QualType SizeTy = Ctx.getSizeType();
888 CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
889
890 // The size of the cookie.
891 CharUnits CookieSize =
892 std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
John McCalle2b45e22012-05-01 05:23:51 +0000893 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
John McCall1e7fe752010-09-02 09:58:18 +0000894
895 // Compute an offset to the cookie.
896 llvm::Value *CookiePtr = NewPtr;
897 CharUnits CookieOffset = CookieSize - SizeSize;
898 if (!CookieOffset.isZero())
899 CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
900 CookieOffset.getQuantity());
901
902 // Write the number of elements into the appropriate slot.
903 llvm::Value *NumElementsPtr
904 = CGF.Builder.CreateBitCast(CookiePtr,
905 CGF.ConvertType(SizeTy)->getPointerTo(AS));
906 CGF.Builder.CreateStore(NumElements, NumElementsPtr);
907
908 // Finally, compute a pointer to the actual data buffer by skipping
909 // over the cookie completely.
910 return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
911 CookieSize.getQuantity());
912}
913
John McCalle2b45e22012-05-01 05:23:51 +0000914llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
915 llvm::Value *allocPtr,
916 CharUnits cookieSize) {
917 // The element size is right-justified in the cookie.
918 llvm::Value *numElementsPtr = allocPtr;
919 CharUnits numElementsOffset =
920 cookieSize - CharUnits::fromQuantity(CGF.SizeSizeInBytes);
921 if (!numElementsOffset.isZero())
922 numElementsPtr =
923 CGF.Builder.CreateConstInBoundsGEP1_64(numElementsPtr,
924 numElementsOffset.getQuantity());
John McCall1e7fe752010-09-02 09:58:18 +0000925
Micah Villmow956a5a12012-10-25 15:39:14 +0000926 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000927 numElementsPtr =
928 CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
929 return CGF.Builder.CreateLoad(numElementsPtr);
John McCall1e7fe752010-09-02 09:58:18 +0000930}
931
John McCalle2b45e22012-05-01 05:23:51 +0000932CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
John McCallf3bbb152013-01-25 23:36:19 +0000933 // ARM says that the cookie is always:
John McCall1e7fe752010-09-02 09:58:18 +0000934 // struct array_cookie {
935 // std::size_t element_size; // element_size != 0
936 // std::size_t element_count;
937 // };
John McCallf3bbb152013-01-25 23:36:19 +0000938 // But the base ABI doesn't give anything an alignment greater than
939 // 8, so we can dismiss this as typical ABI-author blindness to
940 // actual language complexity and round up to the element alignment.
941 return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),
942 CGM.getContext().getTypeAlignInChars(elementType));
John McCall1e7fe752010-09-02 09:58:18 +0000943}
944
945llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
John McCallf3bbb152013-01-25 23:36:19 +0000946 llvm::Value *newPtr,
947 llvm::Value *numElements,
John McCall6ec278d2011-01-27 09:37:56 +0000948 const CXXNewExpr *expr,
John McCallf3bbb152013-01-25 23:36:19 +0000949 QualType elementType) {
John McCalle2b45e22012-05-01 05:23:51 +0000950 assert(requiresArrayCookie(expr));
John McCall1e7fe752010-09-02 09:58:18 +0000951
John McCallf3bbb152013-01-25 23:36:19 +0000952 // NewPtr is a char*, but we generalize to arbitrary addrspaces.
953 unsigned AS = newPtr->getType()->getPointerAddressSpace();
John McCall1e7fe752010-09-02 09:58:18 +0000954
955 // The cookie is always at the start of the buffer.
John McCallf3bbb152013-01-25 23:36:19 +0000956 llvm::Value *cookie = newPtr;
John McCall1e7fe752010-09-02 09:58:18 +0000957
958 // The first element is the element size.
John McCallf3bbb152013-01-25 23:36:19 +0000959 cookie = CGF.Builder.CreateBitCast(cookie, CGF.SizeTy->getPointerTo(AS));
960 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,
961 getContext().getTypeSizeInChars(elementType).getQuantity());
962 CGF.Builder.CreateStore(elementSize, cookie);
John McCall1e7fe752010-09-02 09:58:18 +0000963
964 // The second element is the element count.
John McCallf3bbb152013-01-25 23:36:19 +0000965 cookie = CGF.Builder.CreateConstInBoundsGEP1_32(cookie, 1);
966 CGF.Builder.CreateStore(numElements, cookie);
John McCall1e7fe752010-09-02 09:58:18 +0000967
968 // Finally, compute a pointer to the actual data buffer by skipping
969 // over the cookie completely.
John McCallf3bbb152013-01-25 23:36:19 +0000970 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
971 return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
972 cookieSize.getQuantity());
John McCall1e7fe752010-09-02 09:58:18 +0000973}
974
John McCalle2b45e22012-05-01 05:23:51 +0000975llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
976 llvm::Value *allocPtr,
977 CharUnits cookieSize) {
978 // The number of elements is at offset sizeof(size_t) relative to
979 // the allocated pointer.
980 llvm::Value *numElementsPtr
981 = CGF.Builder.CreateConstInBoundsGEP1_64(allocPtr, CGF.SizeSizeInBytes);
John McCall1e7fe752010-09-02 09:58:18 +0000982
Micah Villmow956a5a12012-10-25 15:39:14 +0000983 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000984 numElementsPtr =
985 CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
986 return CGF.Builder.CreateLoad(numElementsPtr);
John McCall1e7fe752010-09-02 09:58:18 +0000987}
988
John McCall5cd91b52010-09-08 01:44:27 +0000989/*********************** Static local initialization **************************/
990
991static llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000992 llvm::PointerType *GuardPtrTy) {
John McCall5cd91b52010-09-08 01:44:27 +0000993 // int __cxa_guard_acquire(__guard *guard_object);
Chris Lattner2acc6e32011-07-18 04:24:23 +0000994 llvm::FunctionType *FTy =
John McCall5cd91b52010-09-08 01:44:27 +0000995 llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
Jay Foadda549e82011-07-29 13:56:53 +0000996 GuardPtrTy, /*isVarArg=*/false);
Nick Lewyckye76872e2012-02-13 23:45:02 +0000997 return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire",
Bill Wendlingc4c62fd2013-01-31 00:30:05 +0000998 llvm::AttributeSet::get(CGM.getLLVMContext(),
999 llvm::AttributeSet::FunctionIndex,
Bill Wendling72390b32012-12-20 19:27:06 +00001000 llvm::Attribute::NoUnwind));
John McCall5cd91b52010-09-08 01:44:27 +00001001}
1002
1003static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
Chris Lattner9cbe4f02011-07-09 17:41:47 +00001004 llvm::PointerType *GuardPtrTy) {
John McCall5cd91b52010-09-08 01:44:27 +00001005 // void __cxa_guard_release(__guard *guard_object);
Chris Lattner2acc6e32011-07-18 04:24:23 +00001006 llvm::FunctionType *FTy =
Chris Lattner8b418682012-02-07 00:39:47 +00001007 llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
Nick Lewyckye76872e2012-02-13 23:45:02 +00001008 return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release",
Bill Wendlingc4c62fd2013-01-31 00:30:05 +00001009 llvm::AttributeSet::get(CGM.getLLVMContext(),
1010 llvm::AttributeSet::FunctionIndex,
Bill Wendling72390b32012-12-20 19:27:06 +00001011 llvm::Attribute::NoUnwind));
John McCall5cd91b52010-09-08 01:44:27 +00001012}
1013
1014static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
Chris Lattner9cbe4f02011-07-09 17:41:47 +00001015 llvm::PointerType *GuardPtrTy) {
John McCall5cd91b52010-09-08 01:44:27 +00001016 // void __cxa_guard_abort(__guard *guard_object);
Chris Lattner2acc6e32011-07-18 04:24:23 +00001017 llvm::FunctionType *FTy =
Chris Lattner8b418682012-02-07 00:39:47 +00001018 llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
Nick Lewyckye76872e2012-02-13 23:45:02 +00001019 return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort",
Bill Wendlingc4c62fd2013-01-31 00:30:05 +00001020 llvm::AttributeSet::get(CGM.getLLVMContext(),
1021 llvm::AttributeSet::FunctionIndex,
Bill Wendling72390b32012-12-20 19:27:06 +00001022 llvm::Attribute::NoUnwind));
John McCall5cd91b52010-09-08 01:44:27 +00001023}
1024
1025namespace {
1026 struct CallGuardAbort : EHScopeStack::Cleanup {
1027 llvm::GlobalVariable *Guard;
Chandler Carruth0f30a122012-03-30 19:44:53 +00001028 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
John McCall5cd91b52010-09-08 01:44:27 +00001029
John McCallad346f42011-07-12 20:27:29 +00001030 void Emit(CodeGenFunction &CGF, Flags flags) {
John McCallbd7370a2013-02-28 19:01:20 +00001031 CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
1032 Guard);
John McCall5cd91b52010-09-08 01:44:27 +00001033 }
1034 };
1035}
1036
1037/// The ARM code here follows the Itanium code closely enough that we
1038/// just special-case it at particular places.
John McCall3030eb82010-11-06 09:44:32 +00001039void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
1040 const VarDecl &D,
John McCall355bba72012-03-30 21:00:39 +00001041 llvm::GlobalVariable *var,
1042 bool shouldPerformInit) {
John McCall5cd91b52010-09-08 01:44:27 +00001043 CGBuilderTy &Builder = CGF.Builder;
John McCall3030eb82010-11-06 09:44:32 +00001044
1045 // We only need to use thread-safe statics for local variables;
1046 // global initialization is always single-threaded.
John McCall0502a222011-06-17 07:33:57 +00001047 bool threadsafe =
David Blaikie4e4d0842012-03-11 07:00:24 +00001048 (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
Anders Carlsson173d5122011-04-27 04:37:08 +00001049
Anders Carlsson173d5122011-04-27 04:37:08 +00001050 // If we have a global variable with internal linkage and thread-safe statics
1051 // are disabled, we can just let the guard variable be of type i8.
John McCall355bba72012-03-30 21:00:39 +00001052 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1053
1054 llvm::IntegerType *guardTy;
John McCall0502a222011-06-17 07:33:57 +00001055 if (useInt8GuardVariable) {
John McCall355bba72012-03-30 21:00:39 +00001056 guardTy = CGF.Int8Ty;
John McCall0502a222011-06-17 07:33:57 +00001057 } else {
Tim Northoverc264e162013-01-31 12:13:10 +00001058 // Guard variables are 64 bits in the generic ABI and size width on ARM
1059 // (i.e. 32-bit on AArch32, 64-bit on AArch64).
1060 guardTy = (IsARM ? CGF.SizeTy : CGF.Int64Ty);
Anders Carlsson173d5122011-04-27 04:37:08 +00001061 }
John McCall355bba72012-03-30 21:00:39 +00001062 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
John McCall5cd91b52010-09-08 01:44:27 +00001063
John McCall355bba72012-03-30 21:00:39 +00001064 // Create the guard variable if we don't already have it (as we
1065 // might if we're double-emitting this function body).
1066 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1067 if (!guard) {
1068 // Mangle the name for the guard.
1069 SmallString<256> guardName;
1070 {
1071 llvm::raw_svector_ostream out(guardName);
1072 getMangleContext().mangleItaniumGuardVariable(&D, out);
1073 out.flush();
1074 }
John McCall112c9672010-11-02 21:04:24 +00001075
John McCall355bba72012-03-30 21:00:39 +00001076 // Create the guard variable with a zero-initializer.
1077 // Just absorb linkage and visibility from the guarded variable.
1078 guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
1079 false, var->getLinkage(),
1080 llvm::ConstantInt::get(guardTy, 0),
1081 guardName.str());
1082 guard->setVisibility(var->getVisibility());
1083
1084 CGM.setStaticLocalDeclGuardAddress(&D, guard);
1085 }
John McCall49d26d22012-03-30 07:09:50 +00001086
John McCall5cd91b52010-09-08 01:44:27 +00001087 // Test whether the variable has completed initialization.
John McCall355bba72012-03-30 21:00:39 +00001088 llvm::Value *isInitialized;
John McCall5cd91b52010-09-08 01:44:27 +00001089
1090 // ARM C++ ABI 3.2.3.1:
1091 // To support the potential use of initialization guard variables
1092 // as semaphores that are the target of ARM SWP and LDREX/STREX
1093 // synchronizing instructions we define a static initialization
1094 // guard variable to be a 4-byte aligned, 4- byte word with the
1095 // following inline access protocol.
1096 // #define INITIALIZED 1
1097 // if ((obj_guard & INITIALIZED) != INITIALIZED) {
1098 // if (__cxa_guard_acquire(&obj_guard))
1099 // ...
1100 // }
John McCall0502a222011-06-17 07:33:57 +00001101 if (IsARM && !useInt8GuardVariable) {
John McCall355bba72012-03-30 21:00:39 +00001102 llvm::Value *V = Builder.CreateLoad(guard);
Tim Northoverc264e162013-01-31 12:13:10 +00001103 llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1);
1104 V = Builder.CreateAnd(V, Test1);
John McCall355bba72012-03-30 21:00:39 +00001105 isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
John McCall5cd91b52010-09-08 01:44:27 +00001106
1107 // Itanium C++ ABI 3.3.2:
1108 // The following is pseudo-code showing how these functions can be used:
1109 // if (obj_guard.first_byte == 0) {
1110 // if ( __cxa_guard_acquire (&obj_guard) ) {
1111 // try {
1112 // ... initialize the object ...;
1113 // } catch (...) {
1114 // __cxa_guard_abort (&obj_guard);
1115 // throw;
1116 // }
1117 // ... queue object destructor with __cxa_atexit() ...;
1118 // __cxa_guard_release (&obj_guard);
1119 // }
1120 // }
1121 } else {
1122 // Load the first byte of the guard variable.
Chandler Carruth0f30a122012-03-30 19:44:53 +00001123 llvm::LoadInst *LI =
John McCall355bba72012-03-30 21:00:39 +00001124 Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
Chandler Carruth0f30a122012-03-30 19:44:53 +00001125 LI->setAlignment(1);
John McCall5cd91b52010-09-08 01:44:27 +00001126
Eli Friedmaneb43f4a2011-09-13 22:21:56 +00001127 // Itanium ABI:
1128 // An implementation supporting thread-safety on multiprocessor
1129 // systems must also guarantee that references to the initialized
1130 // object do not occur before the load of the initialization flag.
1131 //
1132 // In LLVM, we do this by marking the load Acquire.
1133 if (threadsafe)
Chandler Carruth0f30a122012-03-30 19:44:53 +00001134 LI->setAtomic(llvm::Acquire);
Eli Friedmaneb43f4a2011-09-13 22:21:56 +00001135
John McCall355bba72012-03-30 21:00:39 +00001136 isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
John McCall5cd91b52010-09-08 01:44:27 +00001137 }
1138
1139 llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
1140 llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
1141
1142 // Check if the first byte of the guard variable is zero.
John McCall355bba72012-03-30 21:00:39 +00001143 Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
John McCall5cd91b52010-09-08 01:44:27 +00001144
1145 CGF.EmitBlock(InitCheckBlock);
1146
1147 // Variables used when coping with thread-safe statics and exceptions.
John McCall0502a222011-06-17 07:33:57 +00001148 if (threadsafe) {
John McCall5cd91b52010-09-08 01:44:27 +00001149 // Call __cxa_guard_acquire.
1150 llvm::Value *V
John McCallbd7370a2013-02-28 19:01:20 +00001151 = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
John McCall5cd91b52010-09-08 01:44:27 +00001152
1153 llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
1154
1155 Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
1156 InitBlock, EndBlock);
1157
1158 // Call __cxa_guard_abort along the exceptional edge.
John McCall355bba72012-03-30 21:00:39 +00001159 CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
John McCall5cd91b52010-09-08 01:44:27 +00001160
1161 CGF.EmitBlock(InitBlock);
1162 }
1163
1164 // Emit the initializer and add a global destructor if appropriate.
John McCall355bba72012-03-30 21:00:39 +00001165 CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
John McCall5cd91b52010-09-08 01:44:27 +00001166
John McCall0502a222011-06-17 07:33:57 +00001167 if (threadsafe) {
John McCall5cd91b52010-09-08 01:44:27 +00001168 // Pop the guard-abort cleanup if we pushed one.
1169 CGF.PopCleanupBlock();
1170
1171 // Call __cxa_guard_release. This cannot throw.
John McCallbd7370a2013-02-28 19:01:20 +00001172 CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
John McCall5cd91b52010-09-08 01:44:27 +00001173 } else {
John McCall355bba72012-03-30 21:00:39 +00001174 Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
John McCall5cd91b52010-09-08 01:44:27 +00001175 }
1176
1177 CGF.EmitBlock(EndBlock);
1178}
John McCall20bb1752012-05-01 06:13:13 +00001179
1180/// Register a global destructor using __cxa_atexit.
1181static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
1182 llvm::Constant *dtor,
1183 llvm::Constant *addr) {
1184 // We're assuming that the destructor function is something we can
1185 // reasonably call with the default CC. Go ahead and cast it to the
1186 // right prototype.
1187 llvm::Type *dtorTy =
1188 llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
1189
1190 // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
1191 llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
1192 llvm::FunctionType *atexitTy =
1193 llvm::FunctionType::get(CGF.IntTy, paramTys, false);
1194
1195 // Fetch the actual function.
1196 llvm::Constant *atexit =
1197 CGF.CGM.CreateRuntimeFunction(atexitTy, "__cxa_atexit");
1198 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
1199 fn->setDoesNotThrow();
1200
1201 // Create a variable that binds the atexit to this shared object.
1202 llvm::Constant *handle =
1203 CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
1204
1205 llvm::Value *args[] = {
1206 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
1207 llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
1208 handle
1209 };
John McCallbd7370a2013-02-28 19:01:20 +00001210 CGF.EmitNounwindRuntimeCall(atexit, args);
John McCall20bb1752012-05-01 06:13:13 +00001211}
1212
1213/// Register a global destructor as best as we know how.
1214void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
1215 llvm::Constant *dtor,
1216 llvm::Constant *addr) {
1217 // Use __cxa_atexit if available.
1218 if (CGM.getCodeGenOpts().CXAAtExit) {
1219 return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr);
1220 }
1221
1222 // In Apple kexts, we want to add a global destructor entry.
1223 // FIXME: shouldn't this be guarded by some variable?
Richard Smith7edf9e32012-11-01 22:30:59 +00001224 if (CGM.getLangOpts().AppleKext) {
John McCall20bb1752012-05-01 06:13:13 +00001225 // Generate a global destructor entry.
1226 return CGM.AddCXXDtorEntry(dtor, addr);
1227 }
1228
1229 CGF.registerGlobalDtorWithAtExit(dtor, addr);
1230}