blob: 85b52c632204ff89f7e61893f0cd8dfce104fecf [file] [log] [blame]
Charles Davis4e786dd2010-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//
10// This provides C++ code generation targetting the Itanium C++ ABI. The class
11// 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 McCall86353412010-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 Davis4e786dd2010-05-25 19:52:27 +000019//===----------------------------------------------------------------------===//
20
21#include "CGCXXABI.h"
John McCall7a9aac22010-08-23 01:21:21 +000022#include "CGRecordLayout.h"
John McCall475999d2010-08-22 00:05:51 +000023#include "CodeGenFunction.h"
Charles Davis4e786dd2010-05-25 19:52:27 +000024#include "CodeGenModule.h"
25#include "Mangle.h"
John McCall475999d2010-08-22 00:05:51 +000026#include <clang/AST/Type.h>
John McCall7a9aac22010-08-23 01:21:21 +000027#include <llvm/Target/TargetData.h>
John McCall475999d2010-08-22 00:05:51 +000028#include <llvm/Value.h>
Charles Davis4e786dd2010-05-25 19:52:27 +000029
30using namespace clang;
John McCall475999d2010-08-22 00:05:51 +000031using namespace CodeGen;
Charles Davis4e786dd2010-05-25 19:52:27 +000032
33namespace {
Charles Davis53c59df2010-08-16 03:33:14 +000034class ItaniumCXXABI : public CodeGen::CGCXXABI {
John McCall7a9aac22010-08-23 01:21:21 +000035private:
36 const llvm::IntegerType *PtrDiffTy;
John McCall475999d2010-08-22 00:05:51 +000037protected:
Charles Davis4e786dd2010-05-25 19:52:27 +000038 CodeGen::MangleContext MangleCtx;
John McCalld9c6c0b2010-08-22 00:59:17 +000039 bool IsARM;
John McCall7a9aac22010-08-23 01:21:21 +000040
41 // It's a little silly for us to cache this.
42 const llvm::IntegerType *getPtrDiffTy() {
43 if (!PtrDiffTy) {
John McCall9bca9232010-09-02 10:25:57 +000044 QualType T = getContext().getPointerDiffType();
John McCall7a9aac22010-08-23 01:21:21 +000045 const llvm::Type *Ty = CGM.getTypes().ConvertTypeRecursive(T);
46 PtrDiffTy = cast<llvm::IntegerType>(Ty);
47 }
48 return PtrDiffTy;
49 }
50
John McCall8ed55a52010-09-02 09:58:18 +000051 bool NeedsArrayCookie(QualType ElementType);
52
Charles Davis4e786dd2010-05-25 19:52:27 +000053public:
John McCalld9c6c0b2010-08-22 00:59:17 +000054 ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
John McCall9bca9232010-09-02 10:25:57 +000055 CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(getContext(), CGM.getDiags()),
John McCall7a9aac22010-08-23 01:21:21 +000056 IsARM(IsARM) { }
Charles Davis4e786dd2010-05-25 19:52:27 +000057
58 CodeGen::MangleContext &getMangleContext() {
59 return MangleCtx;
60 }
John McCall475999d2010-08-22 00:05:51 +000061
John McCall614dbdc2010-08-22 21:01:12 +000062 bool isZeroInitializable(const MemberPointerType *MPT);
John McCall84fa5102010-08-22 04:16:24 +000063
John McCall7a9aac22010-08-23 01:21:21 +000064 const llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
65
John McCall475999d2010-08-22 00:05:51 +000066 llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
67 llvm::Value *&This,
68 llvm::Value *MemFnPtr,
69 const MemberPointerType *MPT);
John McCalla8bbb822010-08-22 03:04:22 +000070
John McCallc134eb52010-08-31 21:07:20 +000071 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
72 llvm::Value *Base,
73 llvm::Value *MemPtr,
74 const MemberPointerType *MPT);
75
John McCall7a9aac22010-08-23 01:21:21 +000076 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
77 const CastExpr *E,
78 llvm::Value *Src);
John McCall84fa5102010-08-22 04:16:24 +000079
John McCall7a9aac22010-08-23 01:21:21 +000080 llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
81 const CastExpr *E);
John McCall84fa5102010-08-22 04:16:24 +000082
John McCall7a9aac22010-08-23 01:21:21 +000083 llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
John McCall84fa5102010-08-22 04:16:24 +000084
John McCall7a9aac22010-08-23 01:21:21 +000085 llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
86 llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
John McCall1c456c82010-08-22 06:43:33 +000087
John McCall7a9aac22010-08-23 01:21:21 +000088 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
89 llvm::Value *L,
90 llvm::Value *R,
91 const MemberPointerType *MPT,
92 bool Inequality);
John McCall131d97d2010-08-22 08:30:07 +000093
John McCall7a9aac22010-08-23 01:21:21 +000094 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
95 llvm::Value *Addr,
96 const MemberPointerType *MPT);
John McCall5d865c322010-08-31 07:33:07 +000097
98 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
99 CXXCtorType T,
100 CanQualType &ResTy,
101 llvm::SmallVectorImpl<CanQualType> &ArgTys);
102
103 void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
104 CXXDtorType T,
105 CanQualType &ResTy,
106 llvm::SmallVectorImpl<CanQualType> &ArgTys);
107
108 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
109 QualType &ResTy,
110 FunctionArgList &Params);
111
112 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCall8ed55a52010-09-02 09:58:18 +0000113
114 CharUnits GetArrayCookieSize(QualType ElementType);
115 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
116 llvm::Value *NewPtr,
117 llvm::Value *NumElements,
118 QualType ElementType);
119 void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
120 QualType ElementType, llvm::Value *&NumElements,
121 llvm::Value *&AllocPtr, CharUnits &CookieSize);
Charles Davis4e786dd2010-05-25 19:52:27 +0000122};
John McCall86353412010-08-21 22:46:04 +0000123
124class ARMCXXABI : public ItaniumCXXABI {
125public:
John McCalld9c6c0b2010-08-22 00:59:17 +0000126 ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
John McCall5d865c322010-08-31 07:33:07 +0000127
128 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
129 CXXCtorType T,
130 CanQualType &ResTy,
131 llvm::SmallVectorImpl<CanQualType> &ArgTys);
132
133 void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
134 CXXDtorType T,
135 CanQualType &ResTy,
136 llvm::SmallVectorImpl<CanQualType> &ArgTys);
137
138 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
139 QualType &ResTy,
140 FunctionArgList &Params);
141
142 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
143
144 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
145
John McCall8ed55a52010-09-02 09:58:18 +0000146 CharUnits GetArrayCookieSize(QualType ElementType);
147 llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
148 llvm::Value *NewPtr,
149 llvm::Value *NumElements,
150 QualType ElementType);
151 void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
152 QualType ElementType, llvm::Value *&NumElements,
153 llvm::Value *&AllocPtr, CharUnits &CookieSize);
John McCall5d865c322010-08-31 07:33:07 +0000154
155private:
156 /// \brief Returns true if the given instance method is one of the
157 /// kinds that the ARM ABI says returns 'this'.
158 static bool HasThisReturn(GlobalDecl GD) {
159 const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
160 return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) ||
161 (isa<CXXConstructorDecl>(MD)));
162 }
John McCall86353412010-08-21 22:46:04 +0000163};
Charles Davis4e786dd2010-05-25 19:52:27 +0000164}
165
Charles Davis53c59df2010-08-16 03:33:14 +0000166CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
Charles Davis4e786dd2010-05-25 19:52:27 +0000167 return new ItaniumCXXABI(CGM);
168}
169
John McCall86353412010-08-21 22:46:04 +0000170CodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) {
171 return new ARMCXXABI(CGM);
172}
173
John McCall7a9aac22010-08-23 01:21:21 +0000174const llvm::Type *
175ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
176 if (MPT->isMemberDataPointer())
177 return getPtrDiffTy();
178 else
179 return llvm::StructType::get(CGM.getLLVMContext(),
180 getPtrDiffTy(), getPtrDiffTy(), NULL);
John McCall1c456c82010-08-22 06:43:33 +0000181}
182
John McCalld9c6c0b2010-08-22 00:59:17 +0000183/// In the Itanium and ARM ABIs, method pointers have the form:
184/// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
185///
186/// In the Itanium ABI:
187/// - method pointers are virtual if (memptr.ptr & 1) is nonzero
188/// - the this-adjustment is (memptr.adj)
189/// - the virtual offset is (memptr.ptr - 1)
190///
191/// In the ARM ABI:
192/// - method pointers are virtual if (memptr.adj & 1) is nonzero
193/// - the this-adjustment is (memptr.adj >> 1)
194/// - the virtual offset is (memptr.ptr)
195/// ARM uses 'adj' for the virtual flag because Thumb functions
196/// may be only single-byte aligned.
197///
198/// If the member is virtual, the adjusted 'this' pointer points
199/// to a vtable pointer from which the virtual offset is applied.
200///
201/// If the member is non-virtual, memptr.ptr is the address of
202/// the function to call.
John McCall475999d2010-08-22 00:05:51 +0000203llvm::Value *
204ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
205 llvm::Value *&This,
206 llvm::Value *MemFnPtr,
207 const MemberPointerType *MPT) {
208 CGBuilderTy &Builder = CGF.Builder;
209
210 const FunctionProtoType *FPT =
211 MPT->getPointeeType()->getAs<FunctionProtoType>();
212 const CXXRecordDecl *RD =
213 cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
214
215 const llvm::FunctionType *FTy =
216 CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
217 FPT->isVariadic());
218
John McCall7a9aac22010-08-23 01:21:21 +0000219 const llvm::IntegerType *ptrdiff = getPtrDiffTy();
John McCalld9c6c0b2010-08-22 00:59:17 +0000220 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
John McCall475999d2010-08-22 00:05:51 +0000221
John McCalld9c6c0b2010-08-22 00:59:17 +0000222 llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
223 llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
224 llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
225
John McCalla1dee5302010-08-22 10:59:02 +0000226 // Extract memptr.adj, which is in the second field.
227 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
John McCalld9c6c0b2010-08-22 00:59:17 +0000228
229 // Compute the true adjustment.
230 llvm::Value *Adj = RawAdj;
231 if (IsARM)
232 Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
John McCall475999d2010-08-22 00:05:51 +0000233
234 // Apply the adjustment and cast back to the original struct type
235 // for consistency.
John McCalld9c6c0b2010-08-22 00:59:17 +0000236 llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
237 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
238 This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
John McCall475999d2010-08-22 00:05:51 +0000239
240 // Load the function pointer.
John McCalla1dee5302010-08-22 10:59:02 +0000241 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
John McCall475999d2010-08-22 00:05:51 +0000242
243 // If the LSB in the function pointer is 1, the function pointer points to
244 // a virtual function.
John McCalld9c6c0b2010-08-22 00:59:17 +0000245 llvm::Value *IsVirtual;
246 if (IsARM)
247 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
248 else
249 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
250 IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
John McCall475999d2010-08-22 00:05:51 +0000251 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
252
253 // In the virtual path, the adjustment left 'This' pointing to the
254 // vtable of the correct base subobject. The "function pointer" is an
John McCalld9c6c0b2010-08-22 00:59:17 +0000255 // offset within the vtable (+1 for the virtual flag on non-ARM).
John McCall475999d2010-08-22 00:05:51 +0000256 CGF.EmitBlock(FnVirtual);
257
258 // Cast the adjusted this to a pointer to vtable pointer and load.
259 const llvm::Type *VTableTy = Builder.getInt8PtrTy();
260 llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
John McCalld9c6c0b2010-08-22 00:59:17 +0000261 VTable = Builder.CreateLoad(VTable, "memptr.vtable");
John McCall475999d2010-08-22 00:05:51 +0000262
263 // Apply the offset.
John McCalld9c6c0b2010-08-22 00:59:17 +0000264 llvm::Value *VTableOffset = FnAsInt;
265 if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
266 VTable = Builder.CreateGEP(VTable, VTableOffset);
John McCall475999d2010-08-22 00:05:51 +0000267
268 // Load the virtual function to call.
269 VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
John McCalld9c6c0b2010-08-22 00:59:17 +0000270 llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
John McCall475999d2010-08-22 00:05:51 +0000271 CGF.EmitBranch(FnEnd);
272
273 // In the non-virtual path, the function pointer is actually a
274 // function pointer.
275 CGF.EmitBlock(FnNonVirtual);
276 llvm::Value *NonVirtualFn =
John McCalld9c6c0b2010-08-22 00:59:17 +0000277 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
John McCall475999d2010-08-22 00:05:51 +0000278
279 // We're done.
280 CGF.EmitBlock(FnEnd);
281 llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo());
282 Callee->reserveOperandSpace(2);
283 Callee->addIncoming(VirtualFn, FnVirtual);
284 Callee->addIncoming(NonVirtualFn, FnNonVirtual);
285 return Callee;
286}
John McCalla8bbb822010-08-22 03:04:22 +0000287
John McCallc134eb52010-08-31 21:07:20 +0000288/// Compute an l-value by applying the given pointer-to-member to a
289/// base object.
290llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
291 llvm::Value *Base,
292 llvm::Value *MemPtr,
293 const MemberPointerType *MPT) {
294 assert(MemPtr->getType() == getPtrDiffTy());
295
296 CGBuilderTy &Builder = CGF.Builder;
297
298 unsigned AS = cast<llvm::PointerType>(Base->getType())->getAddressSpace();
299
300 // Cast to char*.
301 Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
302
303 // Apply the offset, which we assume is non-null.
304 llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
305
306 // Cast the address to the appropriate pointer type, adopting the
307 // address space of the base pointer.
Douglas Gregore791a052010-09-02 15:00:29 +0000308 // FIXME: We seem to be losing the "volatile" qualifier on the base pointer.
309 QualType PtrType = CGF.getContext().getPointerType(MPT->getPointeeType());
310 Qualifiers Qs = MPT->getPointeeType().getQualifiers();
311 if (AS)
312 Qs.addAddressSpace(AS);
313 PtrType = CGF.getContext().getQualifiedType(PtrType, Qs);
314 const llvm::Type *PType = CGF.ConvertType(PtrType);
John McCallc134eb52010-08-31 21:07:20 +0000315 return Builder.CreateBitCast(Addr, PType);
316}
317
John McCalla8bbb822010-08-22 03:04:22 +0000318/// Perform a derived-to-base or base-to-derived member pointer conversion.
John McCall7a9aac22010-08-23 01:21:21 +0000319///
320/// Obligatory offset/adjustment diagram:
321/// <-- offset --> <-- adjustment -->
322/// |--------------------------|----------------------|--------------------|
323/// ^Derived address point ^Base address point ^Member address point
324///
325/// So when converting a base member pointer to a derived member pointer,
326/// we add the offset to the adjustment because the address point has
327/// decreased; and conversely, when converting a derived MP to a base MP
328/// we subtract the offset from the adjustment because the address point
329/// has increased.
330///
331/// The standard forbids (at compile time) conversion to and from
332/// virtual bases, which is why we don't have to consider them here.
333///
334/// The standard forbids (at run time) casting a derived MP to a base
335/// MP when the derived MP does not point to a member of the base.
336/// This is why -1 is a reasonable choice for null data member
337/// pointers.
John McCalla1dee5302010-08-22 10:59:02 +0000338llvm::Value *
John McCall7a9aac22010-08-23 01:21:21 +0000339ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
340 const CastExpr *E,
341 llvm::Value *Src) {
John McCalle3027922010-08-25 11:45:40 +0000342 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
343 E->getCastKind() == CK_BaseToDerivedMemberPointer);
John McCalla8bbb822010-08-22 03:04:22 +0000344
John McCalla1dee5302010-08-22 10:59:02 +0000345 if (isa<llvm::Constant>(Src))
John McCall7a9aac22010-08-23 01:21:21 +0000346 return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E);
John McCalla1dee5302010-08-22 10:59:02 +0000347
John McCalla8bbb822010-08-22 03:04:22 +0000348 CGBuilderTy &Builder = CGF.Builder;
349
350 const MemberPointerType *SrcTy =
351 E->getSubExpr()->getType()->getAs<MemberPointerType>();
352 const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
353
354 const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
355 const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
356
John McCalla8bbb822010-08-22 03:04:22 +0000357 bool DerivedToBase =
John McCalle3027922010-08-25 11:45:40 +0000358 E->getCastKind() == CK_DerivedToBaseMemberPointer;
John McCalla8bbb822010-08-22 03:04:22 +0000359
360 const CXXRecordDecl *BaseDecl, *DerivedDecl;
361 if (DerivedToBase)
362 DerivedDecl = SrcDecl, BaseDecl = DestDecl;
363 else
364 BaseDecl = SrcDecl, DerivedDecl = DestDecl;
365
John McCalla1dee5302010-08-22 10:59:02 +0000366 llvm::Constant *Adj =
367 CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
368 E->path_begin(),
369 E->path_end());
370 if (!Adj) return Src;
John McCall1c456c82010-08-22 06:43:33 +0000371
John McCall7a9aac22010-08-23 01:21:21 +0000372 // For member data pointers, this is just a matter of adding the
373 // offset if the source is non-null.
374 if (SrcTy->isMemberDataPointer()) {
375 llvm::Value *Dst;
376 if (DerivedToBase)
377 Dst = Builder.CreateNSWSub(Src, Adj, "adj");
378 else
379 Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
380
381 // Null check.
382 llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
383 llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
384 return Builder.CreateSelect(IsNull, Src, Dst);
385 }
386
John McCalla1dee5302010-08-22 10:59:02 +0000387 // The this-adjustment is left-shifted by 1 on ARM.
388 if (IsARM) {
389 uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
390 Offset <<= 1;
391 Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
392 }
393
John McCallc29eb8a2010-08-22 11:04:31 +0000394 llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
John McCalla1dee5302010-08-22 10:59:02 +0000395 llvm::Value *DstAdj;
396 if (DerivedToBase)
John McCall7a9aac22010-08-23 01:21:21 +0000397 DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
John McCalla1dee5302010-08-22 10:59:02 +0000398 else
John McCall7a9aac22010-08-23 01:21:21 +0000399 DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
John McCalla1dee5302010-08-22 10:59:02 +0000400
John McCallc29eb8a2010-08-22 11:04:31 +0000401 return Builder.CreateInsertValue(Src, DstAdj, 1);
John McCalla8bbb822010-08-22 03:04:22 +0000402}
John McCall84fa5102010-08-22 04:16:24 +0000403
404llvm::Constant *
John McCall7a9aac22010-08-23 01:21:21 +0000405ItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
406 const CastExpr *E) {
John McCall84fa5102010-08-22 04:16:24 +0000407 const MemberPointerType *SrcTy =
408 E->getSubExpr()->getType()->getAs<MemberPointerType>();
409 const MemberPointerType *DestTy =
410 E->getType()->getAs<MemberPointerType>();
411
412 bool DerivedToBase =
John McCalle3027922010-08-25 11:45:40 +0000413 E->getCastKind() == CK_DerivedToBaseMemberPointer;
John McCall84fa5102010-08-22 04:16:24 +0000414
415 const CXXRecordDecl *DerivedDecl;
416 if (DerivedToBase)
417 DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
418 else
419 DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
420
421 // Calculate the offset to the base class.
422 llvm::Constant *Offset =
423 CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
424 E->path_begin(),
425 E->path_end());
426 // If there's no offset, we're done.
427 if (!Offset) return C;
428
John McCall7a9aac22010-08-23 01:21:21 +0000429 // If the source is a member data pointer, we have to do a null
430 // check and then add the offset. In the common case, we can fold
431 // away the offset.
432 if (SrcTy->isMemberDataPointer()) {
433 assert(C->getType() == getPtrDiffTy());
434
435 // If it's a constant int, just create a new constant int.
436 if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
437 int64_t Src = CI->getSExtValue();
438
439 // Null converts to null.
440 if (Src == -1) return CI;
441
442 // Otherwise, just add the offset.
443 int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
444 int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV);
445 return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true);
446 }
447
448 // Otherwise, we have to form a constant select expression.
449 llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType());
450
451 llvm::Constant *IsNull =
452 llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null);
453
454 llvm::Constant *Dst;
455 if (DerivedToBase)
456 Dst = llvm::ConstantExpr::getNSWSub(C, Offset);
457 else
458 Dst = llvm::ConstantExpr::getNSWAdd(C, Offset);
459
460 return llvm::ConstantExpr::getSelect(IsNull, Null, Dst);
461 }
462
John McCall1c456c82010-08-22 06:43:33 +0000463 // The this-adjustment is left-shifted by 1 on ARM.
464 if (IsARM) {
John McCall7a9aac22010-08-23 01:21:21 +0000465 int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
John McCall1c456c82010-08-22 06:43:33 +0000466 OffsetV <<= 1;
467 Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV);
468 }
469
John McCall84fa5102010-08-22 04:16:24 +0000470 llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
471
John McCall7a9aac22010-08-23 01:21:21 +0000472 llvm::Constant *Values[2] = { CS->getOperand(0), 0 };
473 if (DerivedToBase)
474 Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset);
475 else
476 Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
477
John McCall84fa5102010-08-22 04:16:24 +0000478 return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
479 /*Packed=*/false);
480}
481
482
John McCall84fa5102010-08-22 04:16:24 +0000483llvm::Constant *
John McCall7a9aac22010-08-23 01:21:21 +0000484ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
485 const llvm::Type *ptrdiff_t = getPtrDiffTy();
486
487 // Itanium C++ ABI 2.3:
488 // A NULL pointer is represented as -1.
489 if (MPT->isMemberDataPointer())
490 return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
John McCalla1dee5302010-08-22 10:59:02 +0000491
492 llvm::Constant *Zero = llvm::ConstantInt::get(ptrdiff_t, 0);
493 llvm::Constant *Values[2] = { Zero, Zero };
494 return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
495 /*Packed=*/false);
John McCall84fa5102010-08-22 04:16:24 +0000496}
497
John McCall7a9aac22010-08-23 01:21:21 +0000498llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const FieldDecl *FD) {
499 // Itanium C++ ABI 2.3:
500 // A pointer to data member is an offset from the base address of
501 // the class object containing it, represented as a ptrdiff_t
502
John McCall9bca9232010-09-02 10:25:57 +0000503 QualType ClassType = getContext().getTypeDeclType(FD->getParent());
John McCall7a9aac22010-08-23 01:21:21 +0000504 const llvm::StructType *ClassLTy =
505 cast<llvm::StructType>(CGM.getTypes().ConvertType(ClassType));
506
507 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(FD->getParent());
508 unsigned FieldNo = RL.getLLVMFieldNo(FD);
509 uint64_t Offset =
510 CGM.getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
511
512 return llvm::ConstantInt::get(getPtrDiffTy(), Offset);
513}
514
515llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
John McCalla1dee5302010-08-22 10:59:02 +0000516 assert(MD->isInstance() && "Member function must not be static!");
517 MD = MD->getCanonicalDecl();
518
519 CodeGenTypes &Types = CGM.getTypes();
John McCall7a9aac22010-08-23 01:21:21 +0000520 const llvm::Type *ptrdiff_t = getPtrDiffTy();
John McCalla1dee5302010-08-22 10:59:02 +0000521
522 // Get the function pointer (or index if this is a virtual function).
523 llvm::Constant *MemPtr[2];
524 if (MD->isVirtual()) {
525 uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
526
527 // FIXME: We shouldn't use / 8 here.
528 uint64_t PointerWidthInBytes =
John McCall9bca9232010-09-02 10:25:57 +0000529 getContext().Target.getPointerWidth(0) / 8;
John McCalla1dee5302010-08-22 10:59:02 +0000530 uint64_t VTableOffset = (Index * PointerWidthInBytes);
531
532 if (IsARM) {
533 // ARM C++ ABI 3.2.1:
534 // This ABI specifies that adj contains twice the this
535 // adjustment, plus 1 if the member function is virtual. The
536 // least significant bit of adj then makes exactly the same
537 // discrimination as the least significant bit of ptr does for
538 // Itanium.
539 MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset);
540 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
541 } else {
542 // Itanium C++ ABI 2.3:
543 // For a virtual function, [the pointer field] is 1 plus the
544 // virtual table offset (in bytes) of the function,
545 // represented as a ptrdiff_t.
546 MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1);
547 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
548 }
549 } else {
550 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
551 const llvm::Type *Ty;
552 // Check whether the function has a computable LLVM signature.
553 if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) {
554 // The function has a computable LLVM signature; use the correct type.
555 Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), FPT->isVariadic());
556 } else {
557 // Use an arbitrary non-function type to tell GetAddrOfFunction that the
558 // function type is incomplete.
559 Ty = ptrdiff_t;
560 }
561
562 llvm::Constant *Addr = CGM.GetAddrOfFunction(MD, Ty);
563 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(Addr, ptrdiff_t);
564 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
565 }
John McCall1c456c82010-08-22 06:43:33 +0000566
567 return llvm::ConstantStruct::get(CGM.getLLVMContext(),
John McCalla1dee5302010-08-22 10:59:02 +0000568 MemPtr, 2, /*Packed=*/false);
John McCall1c456c82010-08-22 06:43:33 +0000569}
570
John McCall131d97d2010-08-22 08:30:07 +0000571/// The comparison algorithm is pretty easy: the member pointers are
572/// the same if they're either bitwise identical *or* both null.
573///
574/// ARM is different here only because null-ness is more complicated.
575llvm::Value *
John McCall7a9aac22010-08-23 01:21:21 +0000576ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
577 llvm::Value *L,
578 llvm::Value *R,
579 const MemberPointerType *MPT,
580 bool Inequality) {
John McCall131d97d2010-08-22 08:30:07 +0000581 CGBuilderTy &Builder = CGF.Builder;
582
John McCall131d97d2010-08-22 08:30:07 +0000583 llvm::ICmpInst::Predicate Eq;
584 llvm::Instruction::BinaryOps And, Or;
585 if (Inequality) {
586 Eq = llvm::ICmpInst::ICMP_NE;
587 And = llvm::Instruction::Or;
588 Or = llvm::Instruction::And;
589 } else {
590 Eq = llvm::ICmpInst::ICMP_EQ;
591 And = llvm::Instruction::And;
592 Or = llvm::Instruction::Or;
593 }
594
John McCall7a9aac22010-08-23 01:21:21 +0000595 // Member data pointers are easy because there's a unique null
596 // value, so it just comes down to bitwise equality.
597 if (MPT->isMemberDataPointer())
598 return Builder.CreateICmp(Eq, L, R);
599
600 // For member function pointers, the tautologies are more complex.
601 // The Itanium tautology is:
John McCall61a14882010-08-23 06:56:36 +0000602 // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
John McCall7a9aac22010-08-23 01:21:21 +0000603 // The ARM tautology is:
John McCall61a14882010-08-23 06:56:36 +0000604 // (L == R) <==> (L.ptr == R.ptr &&
605 // (L.adj == R.adj ||
606 // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
John McCall7a9aac22010-08-23 01:21:21 +0000607 // The inequality tautologies have exactly the same structure, except
608 // applying De Morgan's laws.
609
610 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
611 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
612
John McCall131d97d2010-08-22 08:30:07 +0000613 // This condition tests whether L.ptr == R.ptr. This must always be
614 // true for equality to hold.
615 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
616
617 // This condition, together with the assumption that L.ptr == R.ptr,
618 // tests whether the pointers are both null. ARM imposes an extra
619 // condition.
620 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
621 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
622
623 // This condition tests whether L.adj == R.adj. If this isn't
624 // true, the pointers are unequal unless they're both null.
John McCalla1dee5302010-08-22 10:59:02 +0000625 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
626 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
John McCall131d97d2010-08-22 08:30:07 +0000627 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
628
629 // Null member function pointers on ARM clear the low bit of Adj,
630 // so the zero condition has to check that neither low bit is set.
631 if (IsARM) {
632 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
633
634 // Compute (l.adj | r.adj) & 1 and test it against zero.
635 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
636 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
637 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
638 "cmp.or.adj");
639 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
640 }
641
642 // Tie together all our conditions.
643 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
644 Result = Builder.CreateBinOp(And, PtrEq, Result,
645 Inequality ? "memptr.ne" : "memptr.eq");
646 return Result;
647}
648
649llvm::Value *
John McCall7a9aac22010-08-23 01:21:21 +0000650ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
651 llvm::Value *MemPtr,
652 const MemberPointerType *MPT) {
John McCall131d97d2010-08-22 08:30:07 +0000653 CGBuilderTy &Builder = CGF.Builder;
John McCall7a9aac22010-08-23 01:21:21 +0000654
655 /// For member data pointers, this is just a check against -1.
656 if (MPT->isMemberDataPointer()) {
657 assert(MemPtr->getType() == getPtrDiffTy());
658 llvm::Value *NegativeOne =
659 llvm::Constant::getAllOnesValue(MemPtr->getType());
660 return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
661 }
John McCall131d97d2010-08-22 08:30:07 +0000662
663 // In Itanium, a member function pointer is null if 'ptr' is null.
John McCalla1dee5302010-08-22 10:59:02 +0000664 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
John McCall131d97d2010-08-22 08:30:07 +0000665
666 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
667 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
668
669 // In ARM, it's that, plus the low bit of 'adj' must be zero.
670 if (IsARM) {
671 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
John McCalla1dee5302010-08-22 10:59:02 +0000672 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
John McCall131d97d2010-08-22 08:30:07 +0000673 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
674 llvm::Value *IsNotVirtual = Builder.CreateICmpEQ(VirtualBit, Zero,
675 "memptr.notvirtual");
676 Result = Builder.CreateAnd(Result, IsNotVirtual);
677 }
678
679 return Result;
680}
John McCall1c456c82010-08-22 06:43:33 +0000681
John McCall614dbdc2010-08-22 21:01:12 +0000682/// The Itanium ABI requires non-zero initialization only for data
683/// member pointers, for which '0' is a valid offset.
684bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
685 return MPT->getPointeeType()->isFunctionType();
John McCall84fa5102010-08-22 04:16:24 +0000686}
John McCall5d865c322010-08-31 07:33:07 +0000687
688/// The generic ABI passes 'this', plus a VTT if it's initializing a
689/// base subobject.
690void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
691 CXXCtorType Type,
692 CanQualType &ResTy,
693 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
John McCall9bca9232010-09-02 10:25:57 +0000694 ASTContext &Context = getContext();
John McCall5d865c322010-08-31 07:33:07 +0000695
696 // 'this' is already there.
697
698 // Check if we need to add a VTT parameter (which has type void **).
699 if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
700 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
701}
702
703/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
704void ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
705 CXXCtorType Type,
706 CanQualType &ResTy,
707 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
708 ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
709 ResTy = ArgTys[0];
710}
711
712/// The generic ABI passes 'this', plus a VTT if it's destroying a
713/// base subobject.
714void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
715 CXXDtorType Type,
716 CanQualType &ResTy,
717 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
John McCall9bca9232010-09-02 10:25:57 +0000718 ASTContext &Context = getContext();
John McCall5d865c322010-08-31 07:33:07 +0000719
720 // 'this' is already there.
721
722 // Check if we need to add a VTT parameter (which has type void **).
723 if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
724 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
725}
726
727/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
728/// for non-deleting destructors.
729void ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
730 CXXDtorType Type,
731 CanQualType &ResTy,
732 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
733 ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
734
735 if (Type != Dtor_Deleting)
736 ResTy = ArgTys[0];
737}
738
739void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
740 QualType &ResTy,
741 FunctionArgList &Params) {
742 /// Create the 'this' variable.
743 BuildThisParam(CGF, Params);
744
745 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
746 assert(MD->isInstance());
747
748 // Check if we need a VTT parameter as well.
749 if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
John McCall9bca9232010-09-02 10:25:57 +0000750 ASTContext &Context = getContext();
John McCall5d865c322010-08-31 07:33:07 +0000751
752 // FIXME: avoid the fake decl
753 QualType T = Context.getPointerType(Context.VoidPtrTy);
754 ImplicitParamDecl *VTTDecl
755 = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
756 &Context.Idents.get("vtt"), T);
757 Params.push_back(std::make_pair(VTTDecl, VTTDecl->getType()));
758 getVTTDecl(CGF) = VTTDecl;
759 }
760}
761
762void ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
763 QualType &ResTy,
764 FunctionArgList &Params) {
765 ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
766
767 // Return 'this' from certain constructors and destructors.
768 if (HasThisReturn(CGF.CurGD))
769 ResTy = Params[0].second;
770}
771
772void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
773 /// Initialize the 'this' slot.
774 EmitThisParam(CGF);
775
776 /// Initialize the 'vtt' slot if needed.
777 if (getVTTDecl(CGF)) {
778 getVTTValue(CGF)
779 = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
780 "vtt");
781 }
782}
783
784void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
785 ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
786
787 /// Initialize the return slot to 'this' at the start of the
788 /// function.
789 if (HasThisReturn(CGF.CurGD))
790 CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue);
791}
792
793void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
794 RValue RV, QualType ResultType) {
795 if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
796 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
797
798 // Destructor thunks in the ARM ABI have indeterminate results.
799 const llvm::Type *T =
800 cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
801 RValue Undef = RValue::get(llvm::UndefValue::get(T));
802 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
803}
John McCall8ed55a52010-09-02 09:58:18 +0000804
805/************************** Array allocation cookies **************************/
806
807bool ItaniumCXXABI::NeedsArrayCookie(QualType ElementType) {
John McCall9bca9232010-09-02 10:25:57 +0000808 ElementType = getContext().getBaseElementType(ElementType);
John McCall8ed55a52010-09-02 09:58:18 +0000809 const RecordType *RT = ElementType->getAs<RecordType>();
810 if (!RT) return false;
811
812 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
813
814 // If the class has a non-trivial destructor, it always needs a cookie.
815 if (!RD->hasTrivialDestructor()) return true;
816
817 // If the class's usual deallocation function takes two arguments,
818 // it needs a cookie. Otherwise we don't need a cookie.
819 const CXXMethodDecl *UsualDeallocationFunction = 0;
820
821 // Usual deallocation functions of this form are always found on the
822 // class.
823 //
824 // FIXME: what exactly is this code supposed to do if there's an
825 // ambiguity? That's possible with using declarations.
826 DeclarationName OpName =
John McCall9bca9232010-09-02 10:25:57 +0000827 getContext().DeclarationNames.getCXXOperatorName(OO_Array_Delete);
John McCall8ed55a52010-09-02 09:58:18 +0000828 DeclContext::lookup_const_iterator Op, OpEnd;
829 for (llvm::tie(Op, OpEnd) = RD->lookup(OpName); Op != OpEnd; ++Op) {
830 const CXXMethodDecl *Delete =
831 cast<CXXMethodDecl>((*Op)->getUnderlyingDecl());
832
833 if (Delete->isUsualDeallocationFunction()) {
834 UsualDeallocationFunction = Delete;
835 break;
836 }
837 }
838
839 // No usual deallocation function, we don't need a cookie.
840 if (!UsualDeallocationFunction)
841 return false;
842
843 // The usual deallocation function doesn't take a size_t argument,
844 // so we don't need a cookie.
845 if (UsualDeallocationFunction->getNumParams() == 1)
846 return false;
847
848 assert(UsualDeallocationFunction->getNumParams() == 2 &&
849 "Unexpected deallocation function type!");
850 return true;
851}
852
853CharUnits ItaniumCXXABI::GetArrayCookieSize(QualType ElementType) {
854 if (!NeedsArrayCookie(ElementType))
855 return CharUnits::Zero();
856
857 // Padding is the maximum of sizeof(size_t) and alignof(ElementType)
John McCall9bca9232010-09-02 10:25:57 +0000858 ASTContext &Ctx = getContext();
John McCall8ed55a52010-09-02 09:58:18 +0000859 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
860 Ctx.getTypeAlignInChars(ElementType));
861}
862
863llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
864 llvm::Value *NewPtr,
865 llvm::Value *NumElements,
866 QualType ElementType) {
867 assert(NeedsArrayCookie(ElementType));
868
869 unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
870
John McCall9bca9232010-09-02 10:25:57 +0000871 ASTContext &Ctx = getContext();
John McCall8ed55a52010-09-02 09:58:18 +0000872 QualType SizeTy = Ctx.getSizeType();
873 CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
874
875 // The size of the cookie.
876 CharUnits CookieSize =
877 std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
878
879 // Compute an offset to the cookie.
880 llvm::Value *CookiePtr = NewPtr;
881 CharUnits CookieOffset = CookieSize - SizeSize;
882 if (!CookieOffset.isZero())
883 CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
884 CookieOffset.getQuantity());
885
886 // Write the number of elements into the appropriate slot.
887 llvm::Value *NumElementsPtr
888 = CGF.Builder.CreateBitCast(CookiePtr,
889 CGF.ConvertType(SizeTy)->getPointerTo(AS));
890 CGF.Builder.CreateStore(NumElements, NumElementsPtr);
891
892 // Finally, compute a pointer to the actual data buffer by skipping
893 // over the cookie completely.
894 return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
895 CookieSize.getQuantity());
896}
897
898void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
899 llvm::Value *Ptr,
900 QualType ElementType,
901 llvm::Value *&NumElements,
902 llvm::Value *&AllocPtr,
903 CharUnits &CookieSize) {
904 // Derive a char* in the same address space as the pointer.
905 unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
906 const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
907
908 // If we don't need an array cookie, bail out early.
909 if (!NeedsArrayCookie(ElementType)) {
910 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
911 NumElements = 0;
912 CookieSize = CharUnits::Zero();
913 return;
914 }
915
John McCall9bca9232010-09-02 10:25:57 +0000916 QualType SizeTy = getContext().getSizeType();
917 CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
John McCall8ed55a52010-09-02 09:58:18 +0000918 const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
919
920 CookieSize
John McCall9bca9232010-09-02 10:25:57 +0000921 = std::max(SizeSize, getContext().getTypeAlignInChars(ElementType));
John McCall8ed55a52010-09-02 09:58:18 +0000922
923 CharUnits NumElementsOffset = CookieSize - SizeSize;
924
925 // Compute the allocated pointer.
926 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
927 AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
928 -CookieSize.getQuantity());
929
930 llvm::Value *NumElementsPtr = AllocPtr;
931 if (!NumElementsOffset.isZero())
932 NumElementsPtr =
933 CGF.Builder.CreateConstInBoundsGEP1_64(NumElementsPtr,
934 NumElementsOffset.getQuantity());
935 NumElementsPtr =
936 CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
937 NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
938}
939
940CharUnits ARMCXXABI::GetArrayCookieSize(QualType ElementType) {
941 if (!NeedsArrayCookie(ElementType))
942 return CharUnits::Zero();
943
944 // On ARM, the cookie is always:
945 // struct array_cookie {
946 // std::size_t element_size; // element_size != 0
947 // std::size_t element_count;
948 // };
949 // TODO: what should we do if the allocated type actually wants
950 // greater alignment?
951 return getContext().getTypeSizeInChars(getContext().getSizeType()) * 2;
952}
953
954llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
955 llvm::Value *NewPtr,
956 llvm::Value *NumElements,
957 QualType ElementType) {
958 assert(NeedsArrayCookie(ElementType));
959
960 // NewPtr is a char*.
961
962 unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
963
John McCall9bca9232010-09-02 10:25:57 +0000964 ASTContext &Ctx = getContext();
John McCall8ed55a52010-09-02 09:58:18 +0000965 CharUnits SizeSize = Ctx.getTypeSizeInChars(Ctx.getSizeType());
966 const llvm::IntegerType *SizeTy =
967 cast<llvm::IntegerType>(CGF.ConvertType(Ctx.getSizeType()));
968
969 // The cookie is always at the start of the buffer.
970 llvm::Value *CookiePtr = NewPtr;
971
972 // The first element is the element size.
973 CookiePtr = CGF.Builder.CreateBitCast(CookiePtr, SizeTy->getPointerTo(AS));
974 llvm::Value *ElementSize = llvm::ConstantInt::get(SizeTy,
975 Ctx.getTypeSizeInChars(ElementType).getQuantity());
976 CGF.Builder.CreateStore(ElementSize, CookiePtr);
977
978 // The second element is the element count.
979 CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_32(CookiePtr, 1);
980 CGF.Builder.CreateStore(NumElements, CookiePtr);
981
982 // Finally, compute a pointer to the actual data buffer by skipping
983 // over the cookie completely.
984 CharUnits CookieSize = 2 * SizeSize;
985 return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
986 CookieSize.getQuantity());
987}
988
989void ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
990 llvm::Value *Ptr,
991 QualType ElementType,
992 llvm::Value *&NumElements,
993 llvm::Value *&AllocPtr,
994 CharUnits &CookieSize) {
995 // Derive a char* in the same address space as the pointer.
996 unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
997 const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
998
999 // If we don't need an array cookie, bail out early.
1000 if (!NeedsArrayCookie(ElementType)) {
1001 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
1002 NumElements = 0;
1003 CookieSize = CharUnits::Zero();
1004 return;
1005 }
1006
John McCall9bca9232010-09-02 10:25:57 +00001007 QualType SizeTy = getContext().getSizeType();
1008 CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
John McCall8ed55a52010-09-02 09:58:18 +00001009 const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
1010
1011 // The cookie size is always 2 * sizeof(size_t).
1012 CookieSize = 2 * SizeSize;
1013 CharUnits NumElementsOffset = CookieSize - SizeSize;
1014
1015 // The allocated pointer is the input ptr, minus that amount.
1016 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
1017 AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1018 -CookieSize.getQuantity());
1019
1020 // The number of elements is at offset sizeof(size_t) relative to that.
1021 llvm::Value *NumElementsPtr
1022 = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1023 SizeSize.getQuantity());
1024 NumElementsPtr =
1025 CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
1026 NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
1027}
1028