blob: 85a67a437d51b3dce8d2c079c3561c6223e9ce32 [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//
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 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"
John McCall93d557b2010-08-22 00:05:51 +000023#include "CodeGenFunction.h"
Charles Davis3a811f12010-05-25 19:52:27 +000024#include "CodeGenModule.h"
25#include "Mangle.h"
John McCall93d557b2010-08-22 00:05:51 +000026#include <clang/AST/Type.h>
John McCall0bab0cd2010-08-23 01:21:21 +000027#include <llvm/Target/TargetData.h>
John McCall93d557b2010-08-22 00:05:51 +000028#include <llvm/Value.h>
Charles Davis3a811f12010-05-25 19:52:27 +000029
30using namespace clang;
John McCall93d557b2010-08-22 00:05:51 +000031using namespace CodeGen;
Charles Davis3a811f12010-05-25 19:52:27 +000032
33namespace {
Charles Davis071cc7d2010-08-16 03:33:14 +000034class ItaniumCXXABI : public CodeGen::CGCXXABI {
John McCall0bab0cd2010-08-23 01:21:21 +000035private:
36 const llvm::IntegerType *PtrDiffTy;
John McCall93d557b2010-08-22 00:05:51 +000037protected:
Charles Davis3a811f12010-05-25 19:52:27 +000038 CodeGen::MangleContext MangleCtx;
John McCallbabc9a92010-08-22 00:59:17 +000039 bool IsARM;
John McCall0bab0cd2010-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) {
44 QualType T = CGM.getContext().getPointerDiffType();
45 const llvm::Type *Ty = CGM.getTypes().ConvertTypeRecursive(T);
46 PtrDiffTy = cast<llvm::IntegerType>(Ty);
47 }
48 return PtrDiffTy;
49 }
50
John McCall1e7fe752010-09-02 09:58:18 +000051 bool NeedsArrayCookie(QualType ElementType);
52
Charles Davis3a811f12010-05-25 19:52:27 +000053public:
John McCallbabc9a92010-08-22 00:59:17 +000054 ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
John McCall0bab0cd2010-08-23 01:21:21 +000055 CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(CGM.getContext(), CGM.getDiags()),
56 IsARM(IsARM) { }
Charles Davis3a811f12010-05-25 19:52:27 +000057
58 CodeGen::MangleContext &getMangleContext() {
59 return MangleCtx;
60 }
John McCall93d557b2010-08-22 00:05:51 +000061
John McCallf16aa102010-08-22 21:01:12 +000062 bool isZeroInitializable(const MemberPointerType *MPT);
John McCallcf2c85e2010-08-22 04:16:24 +000063
John McCall0bab0cd2010-08-23 01:21:21 +000064 const llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
65
John McCall93d557b2010-08-22 00:05:51 +000066 llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
67 llvm::Value *&This,
68 llvm::Value *MemFnPtr,
69 const MemberPointerType *MPT);
John McCall3023def2010-08-22 03:04:22 +000070
John McCall6c2ab1d2010-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 McCall0bab0cd2010-08-23 01:21:21 +000076 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
77 const CastExpr *E,
78 llvm::Value *Src);
John McCallcf2c85e2010-08-22 04:16:24 +000079
John McCall0bab0cd2010-08-23 01:21:21 +000080 llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
81 const CastExpr *E);
John McCallcf2c85e2010-08-22 04:16:24 +000082
John McCall0bab0cd2010-08-23 01:21:21 +000083 llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
John McCallcf2c85e2010-08-22 04:16:24 +000084
John McCall0bab0cd2010-08-23 01:21:21 +000085 llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
86 llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
John McCall875ab102010-08-22 06:43:33 +000087
John McCall0bab0cd2010-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 McCalle9fd7eb2010-08-22 08:30:07 +000093
John McCall0bab0cd2010-08-23 01:21:21 +000094 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
95 llvm::Value *Addr,
96 const MemberPointerType *MPT);
John McCall4c40d982010-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 McCall1e7fe752010-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 Davis3a811f12010-05-25 19:52:27 +0000122};
John McCallee79a4c2010-08-21 22:46:04 +0000123
124class ARMCXXABI : public ItaniumCXXABI {
125public:
John McCallbabc9a92010-08-22 00:59:17 +0000126 ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
John McCall4c40d982010-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 McCall1e7fe752010-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 McCall4c40d982010-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 McCallee79a4c2010-08-21 22:46:04 +0000163};
Charles Davis3a811f12010-05-25 19:52:27 +0000164}
165
Charles Davis071cc7d2010-08-16 03:33:14 +0000166CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
Charles Davis3a811f12010-05-25 19:52:27 +0000167 return new ItaniumCXXABI(CGM);
168}
169
John McCallee79a4c2010-08-21 22:46:04 +0000170CodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) {
171 return new ARMCXXABI(CGM);
172}
173
John McCall0bab0cd2010-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 McCall875ab102010-08-22 06:43:33 +0000181}
182
John McCallbabc9a92010-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 McCall93d557b2010-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 McCall0bab0cd2010-08-23 01:21:21 +0000219 const llvm::IntegerType *ptrdiff = getPtrDiffTy();
John McCallbabc9a92010-08-22 00:59:17 +0000220 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
John McCall93d557b2010-08-22 00:05:51 +0000221
John McCallbabc9a92010-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 McCalld608cdb2010-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 McCallbabc9a92010-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 McCall93d557b2010-08-22 00:05:51 +0000233
234 // Apply the adjustment and cast back to the original struct type
235 // for consistency.
John McCallbabc9a92010-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 McCall93d557b2010-08-22 00:05:51 +0000239
240 // Load the function pointer.
John McCalld608cdb2010-08-22 10:59:02 +0000241 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
John McCall93d557b2010-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 McCallbabc9a92010-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 McCall93d557b2010-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 McCallbabc9a92010-08-22 00:59:17 +0000255 // offset within the vtable (+1 for the virtual flag on non-ARM).
John McCall93d557b2010-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 McCallbabc9a92010-08-22 00:59:17 +0000261 VTable = Builder.CreateLoad(VTable, "memptr.vtable");
John McCall93d557b2010-08-22 00:05:51 +0000262
263 // Apply the offset.
John McCallbabc9a92010-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 McCall93d557b2010-08-22 00:05:51 +0000267
268 // Load the virtual function to call.
269 VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
John McCallbabc9a92010-08-22 00:59:17 +0000270 llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
John McCall93d557b2010-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 McCallbabc9a92010-08-22 00:59:17 +0000277 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
John McCall93d557b2010-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 McCall3023def2010-08-22 03:04:22 +0000287
John McCall6c2ab1d2010-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.
308 const llvm::Type *PType
309 = CGF.ConvertType(MPT->getPointeeType())->getPointerTo(AS);
310 return Builder.CreateBitCast(Addr, PType);
311}
312
John McCall3023def2010-08-22 03:04:22 +0000313/// Perform a derived-to-base or base-to-derived member pointer conversion.
John McCall0bab0cd2010-08-23 01:21:21 +0000314///
315/// Obligatory offset/adjustment diagram:
316/// <-- offset --> <-- adjustment -->
317/// |--------------------------|----------------------|--------------------|
318/// ^Derived address point ^Base address point ^Member address point
319///
320/// So when converting a base member pointer to a derived member pointer,
321/// we add the offset to the adjustment because the address point has
322/// decreased; and conversely, when converting a derived MP to a base MP
323/// we subtract the offset from the adjustment because the address point
324/// has increased.
325///
326/// The standard forbids (at compile time) conversion to and from
327/// virtual bases, which is why we don't have to consider them here.
328///
329/// The standard forbids (at run time) casting a derived MP to a base
330/// MP when the derived MP does not point to a member of the base.
331/// This is why -1 is a reasonable choice for null data member
332/// pointers.
John McCalld608cdb2010-08-22 10:59:02 +0000333llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000334ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
335 const CastExpr *E,
336 llvm::Value *Src) {
John McCall2de56d12010-08-25 11:45:40 +0000337 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
338 E->getCastKind() == CK_BaseToDerivedMemberPointer);
John McCall3023def2010-08-22 03:04:22 +0000339
John McCalld608cdb2010-08-22 10:59:02 +0000340 if (isa<llvm::Constant>(Src))
John McCall0bab0cd2010-08-23 01:21:21 +0000341 return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E);
John McCalld608cdb2010-08-22 10:59:02 +0000342
John McCall3023def2010-08-22 03:04:22 +0000343 CGBuilderTy &Builder = CGF.Builder;
344
345 const MemberPointerType *SrcTy =
346 E->getSubExpr()->getType()->getAs<MemberPointerType>();
347 const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
348
349 const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
350 const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
351
John McCall3023def2010-08-22 03:04:22 +0000352 bool DerivedToBase =
John McCall2de56d12010-08-25 11:45:40 +0000353 E->getCastKind() == CK_DerivedToBaseMemberPointer;
John McCall3023def2010-08-22 03:04:22 +0000354
355 const CXXRecordDecl *BaseDecl, *DerivedDecl;
356 if (DerivedToBase)
357 DerivedDecl = SrcDecl, BaseDecl = DestDecl;
358 else
359 BaseDecl = SrcDecl, DerivedDecl = DestDecl;
360
John McCalld608cdb2010-08-22 10:59:02 +0000361 llvm::Constant *Adj =
362 CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
363 E->path_begin(),
364 E->path_end());
365 if (!Adj) return Src;
John McCall875ab102010-08-22 06:43:33 +0000366
John McCall0bab0cd2010-08-23 01:21:21 +0000367 // For member data pointers, this is just a matter of adding the
368 // offset if the source is non-null.
369 if (SrcTy->isMemberDataPointer()) {
370 llvm::Value *Dst;
371 if (DerivedToBase)
372 Dst = Builder.CreateNSWSub(Src, Adj, "adj");
373 else
374 Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
375
376 // Null check.
377 llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
378 llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
379 return Builder.CreateSelect(IsNull, Src, Dst);
380 }
381
John McCalld608cdb2010-08-22 10:59:02 +0000382 // The this-adjustment is left-shifted by 1 on ARM.
383 if (IsARM) {
384 uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
385 Offset <<= 1;
386 Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
387 }
388
John McCalle14add42010-08-22 11:04:31 +0000389 llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
John McCalld608cdb2010-08-22 10:59:02 +0000390 llvm::Value *DstAdj;
391 if (DerivedToBase)
John McCall0bab0cd2010-08-23 01:21:21 +0000392 DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
John McCalld608cdb2010-08-22 10:59:02 +0000393 else
John McCall0bab0cd2010-08-23 01:21:21 +0000394 DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
John McCalld608cdb2010-08-22 10:59:02 +0000395
John McCalle14add42010-08-22 11:04:31 +0000396 return Builder.CreateInsertValue(Src, DstAdj, 1);
John McCall3023def2010-08-22 03:04:22 +0000397}
John McCallcf2c85e2010-08-22 04:16:24 +0000398
399llvm::Constant *
John McCall0bab0cd2010-08-23 01:21:21 +0000400ItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
401 const CastExpr *E) {
John McCallcf2c85e2010-08-22 04:16:24 +0000402 const MemberPointerType *SrcTy =
403 E->getSubExpr()->getType()->getAs<MemberPointerType>();
404 const MemberPointerType *DestTy =
405 E->getType()->getAs<MemberPointerType>();
406
407 bool DerivedToBase =
John McCall2de56d12010-08-25 11:45:40 +0000408 E->getCastKind() == CK_DerivedToBaseMemberPointer;
John McCallcf2c85e2010-08-22 04:16:24 +0000409
410 const CXXRecordDecl *DerivedDecl;
411 if (DerivedToBase)
412 DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
413 else
414 DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
415
416 // Calculate the offset to the base class.
417 llvm::Constant *Offset =
418 CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
419 E->path_begin(),
420 E->path_end());
421 // If there's no offset, we're done.
422 if (!Offset) return C;
423
John McCall0bab0cd2010-08-23 01:21:21 +0000424 // If the source is a member data pointer, we have to do a null
425 // check and then add the offset. In the common case, we can fold
426 // away the offset.
427 if (SrcTy->isMemberDataPointer()) {
428 assert(C->getType() == getPtrDiffTy());
429
430 // If it's a constant int, just create a new constant int.
431 if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
432 int64_t Src = CI->getSExtValue();
433
434 // Null converts to null.
435 if (Src == -1) return CI;
436
437 // Otherwise, just add the offset.
438 int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
439 int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV);
440 return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true);
441 }
442
443 // Otherwise, we have to form a constant select expression.
444 llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType());
445
446 llvm::Constant *IsNull =
447 llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null);
448
449 llvm::Constant *Dst;
450 if (DerivedToBase)
451 Dst = llvm::ConstantExpr::getNSWSub(C, Offset);
452 else
453 Dst = llvm::ConstantExpr::getNSWAdd(C, Offset);
454
455 return llvm::ConstantExpr::getSelect(IsNull, Null, Dst);
456 }
457
John McCall875ab102010-08-22 06:43:33 +0000458 // The this-adjustment is left-shifted by 1 on ARM.
459 if (IsARM) {
John McCall0bab0cd2010-08-23 01:21:21 +0000460 int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
John McCall875ab102010-08-22 06:43:33 +0000461 OffsetV <<= 1;
462 Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV);
463 }
464
John McCallcf2c85e2010-08-22 04:16:24 +0000465 llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
466
John McCall0bab0cd2010-08-23 01:21:21 +0000467 llvm::Constant *Values[2] = { CS->getOperand(0), 0 };
468 if (DerivedToBase)
469 Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset);
470 else
471 Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
472
John McCallcf2c85e2010-08-22 04:16:24 +0000473 return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
474 /*Packed=*/false);
475}
476
477
John McCallcf2c85e2010-08-22 04:16:24 +0000478llvm::Constant *
John McCall0bab0cd2010-08-23 01:21:21 +0000479ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
480 const llvm::Type *ptrdiff_t = getPtrDiffTy();
481
482 // Itanium C++ ABI 2.3:
483 // A NULL pointer is represented as -1.
484 if (MPT->isMemberDataPointer())
485 return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
John McCalld608cdb2010-08-22 10:59:02 +0000486
487 llvm::Constant *Zero = llvm::ConstantInt::get(ptrdiff_t, 0);
488 llvm::Constant *Values[2] = { Zero, Zero };
489 return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
490 /*Packed=*/false);
John McCallcf2c85e2010-08-22 04:16:24 +0000491}
492
John McCall0bab0cd2010-08-23 01:21:21 +0000493llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const FieldDecl *FD) {
494 // Itanium C++ ABI 2.3:
495 // A pointer to data member is an offset from the base address of
496 // the class object containing it, represented as a ptrdiff_t
497
498 QualType ClassType = CGM.getContext().getTypeDeclType(FD->getParent());
499 const llvm::StructType *ClassLTy =
500 cast<llvm::StructType>(CGM.getTypes().ConvertType(ClassType));
501
502 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(FD->getParent());
503 unsigned FieldNo = RL.getLLVMFieldNo(FD);
504 uint64_t Offset =
505 CGM.getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
506
507 return llvm::ConstantInt::get(getPtrDiffTy(), Offset);
508}
509
510llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
John McCalld608cdb2010-08-22 10:59:02 +0000511 assert(MD->isInstance() && "Member function must not be static!");
512 MD = MD->getCanonicalDecl();
513
514 CodeGenTypes &Types = CGM.getTypes();
John McCall0bab0cd2010-08-23 01:21:21 +0000515 const llvm::Type *ptrdiff_t = getPtrDiffTy();
John McCalld608cdb2010-08-22 10:59:02 +0000516
517 // Get the function pointer (or index if this is a virtual function).
518 llvm::Constant *MemPtr[2];
519 if (MD->isVirtual()) {
520 uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
521
522 // FIXME: We shouldn't use / 8 here.
523 uint64_t PointerWidthInBytes =
524 CGM.getContext().Target.getPointerWidth(0) / 8;
525 uint64_t VTableOffset = (Index * PointerWidthInBytes);
526
527 if (IsARM) {
528 // ARM C++ ABI 3.2.1:
529 // This ABI specifies that adj contains twice the this
530 // adjustment, plus 1 if the member function is virtual. The
531 // least significant bit of adj then makes exactly the same
532 // discrimination as the least significant bit of ptr does for
533 // Itanium.
534 MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset);
535 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
536 } else {
537 // Itanium C++ ABI 2.3:
538 // For a virtual function, [the pointer field] is 1 plus the
539 // virtual table offset (in bytes) of the function,
540 // represented as a ptrdiff_t.
541 MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1);
542 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
543 }
544 } else {
545 const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
546 const llvm::Type *Ty;
547 // Check whether the function has a computable LLVM signature.
548 if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) {
549 // The function has a computable LLVM signature; use the correct type.
550 Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), FPT->isVariadic());
551 } else {
552 // Use an arbitrary non-function type to tell GetAddrOfFunction that the
553 // function type is incomplete.
554 Ty = ptrdiff_t;
555 }
556
557 llvm::Constant *Addr = CGM.GetAddrOfFunction(MD, Ty);
558 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(Addr, ptrdiff_t);
559 MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
560 }
John McCall875ab102010-08-22 06:43:33 +0000561
562 return llvm::ConstantStruct::get(CGM.getLLVMContext(),
John McCalld608cdb2010-08-22 10:59:02 +0000563 MemPtr, 2, /*Packed=*/false);
John McCall875ab102010-08-22 06:43:33 +0000564}
565
John McCalle9fd7eb2010-08-22 08:30:07 +0000566/// The comparison algorithm is pretty easy: the member pointers are
567/// the same if they're either bitwise identical *or* both null.
568///
569/// ARM is different here only because null-ness is more complicated.
570llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000571ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
572 llvm::Value *L,
573 llvm::Value *R,
574 const MemberPointerType *MPT,
575 bool Inequality) {
John McCalle9fd7eb2010-08-22 08:30:07 +0000576 CGBuilderTy &Builder = CGF.Builder;
577
John McCalle9fd7eb2010-08-22 08:30:07 +0000578 llvm::ICmpInst::Predicate Eq;
579 llvm::Instruction::BinaryOps And, Or;
580 if (Inequality) {
581 Eq = llvm::ICmpInst::ICMP_NE;
582 And = llvm::Instruction::Or;
583 Or = llvm::Instruction::And;
584 } else {
585 Eq = llvm::ICmpInst::ICMP_EQ;
586 And = llvm::Instruction::And;
587 Or = llvm::Instruction::Or;
588 }
589
John McCall0bab0cd2010-08-23 01:21:21 +0000590 // Member data pointers are easy because there's a unique null
591 // value, so it just comes down to bitwise equality.
592 if (MPT->isMemberDataPointer())
593 return Builder.CreateICmp(Eq, L, R);
594
595 // For member function pointers, the tautologies are more complex.
596 // The Itanium tautology is:
John McCallde719f72010-08-23 06:56:36 +0000597 // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
John McCall0bab0cd2010-08-23 01:21:21 +0000598 // The ARM tautology is:
John McCallde719f72010-08-23 06:56:36 +0000599 // (L == R) <==> (L.ptr == R.ptr &&
600 // (L.adj == R.adj ||
601 // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
John McCall0bab0cd2010-08-23 01:21:21 +0000602 // The inequality tautologies have exactly the same structure, except
603 // applying De Morgan's laws.
604
605 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
606 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
607
John McCalle9fd7eb2010-08-22 08:30:07 +0000608 // This condition tests whether L.ptr == R.ptr. This must always be
609 // true for equality to hold.
610 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
611
612 // This condition, together with the assumption that L.ptr == R.ptr,
613 // tests whether the pointers are both null. ARM imposes an extra
614 // condition.
615 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
616 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
617
618 // This condition tests whether L.adj == R.adj. If this isn't
619 // true, the pointers are unequal unless they're both null.
John McCalld608cdb2010-08-22 10:59:02 +0000620 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
621 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
John McCalle9fd7eb2010-08-22 08:30:07 +0000622 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
623
624 // Null member function pointers on ARM clear the low bit of Adj,
625 // so the zero condition has to check that neither low bit is set.
626 if (IsARM) {
627 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
628
629 // Compute (l.adj | r.adj) & 1 and test it against zero.
630 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
631 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
632 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
633 "cmp.or.adj");
634 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
635 }
636
637 // Tie together all our conditions.
638 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
639 Result = Builder.CreateBinOp(And, PtrEq, Result,
640 Inequality ? "memptr.ne" : "memptr.eq");
641 return Result;
642}
643
644llvm::Value *
John McCall0bab0cd2010-08-23 01:21:21 +0000645ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
646 llvm::Value *MemPtr,
647 const MemberPointerType *MPT) {
John McCalle9fd7eb2010-08-22 08:30:07 +0000648 CGBuilderTy &Builder = CGF.Builder;
John McCall0bab0cd2010-08-23 01:21:21 +0000649
650 /// For member data pointers, this is just a check against -1.
651 if (MPT->isMemberDataPointer()) {
652 assert(MemPtr->getType() == getPtrDiffTy());
653 llvm::Value *NegativeOne =
654 llvm::Constant::getAllOnesValue(MemPtr->getType());
655 return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
656 }
John McCalle9fd7eb2010-08-22 08:30:07 +0000657
658 // In Itanium, a member function pointer is null if 'ptr' is null.
John McCalld608cdb2010-08-22 10:59:02 +0000659 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
John McCalle9fd7eb2010-08-22 08:30:07 +0000660
661 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
662 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
663
664 // In ARM, it's that, plus the low bit of 'adj' must be zero.
665 if (IsARM) {
666 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
John McCalld608cdb2010-08-22 10:59:02 +0000667 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
John McCalle9fd7eb2010-08-22 08:30:07 +0000668 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
669 llvm::Value *IsNotVirtual = Builder.CreateICmpEQ(VirtualBit, Zero,
670 "memptr.notvirtual");
671 Result = Builder.CreateAnd(Result, IsNotVirtual);
672 }
673
674 return Result;
675}
John McCall875ab102010-08-22 06:43:33 +0000676
John McCallf16aa102010-08-22 21:01:12 +0000677/// The Itanium ABI requires non-zero initialization only for data
678/// member pointers, for which '0' is a valid offset.
679bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
680 return MPT->getPointeeType()->isFunctionType();
John McCallcf2c85e2010-08-22 04:16:24 +0000681}
John McCall4c40d982010-08-31 07:33:07 +0000682
683/// The generic ABI passes 'this', plus a VTT if it's initializing a
684/// base subobject.
685void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
686 CXXCtorType Type,
687 CanQualType &ResTy,
688 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
689 ASTContext &Context = CGM.getContext();
690
691 // 'this' is already there.
692
693 // Check if we need to add a VTT parameter (which has type void **).
694 if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
695 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
696}
697
698/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
699void ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
700 CXXCtorType Type,
701 CanQualType &ResTy,
702 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
703 ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
704 ResTy = ArgTys[0];
705}
706
707/// The generic ABI passes 'this', plus a VTT if it's destroying a
708/// base subobject.
709void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
710 CXXDtorType Type,
711 CanQualType &ResTy,
712 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
713 ASTContext &Context = CGM.getContext();
714
715 // 'this' is already there.
716
717 // Check if we need to add a VTT parameter (which has type void **).
718 if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
719 ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
720}
721
722/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
723/// for non-deleting destructors.
724void ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
725 CXXDtorType Type,
726 CanQualType &ResTy,
727 llvm::SmallVectorImpl<CanQualType> &ArgTys) {
728 ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
729
730 if (Type != Dtor_Deleting)
731 ResTy = ArgTys[0];
732}
733
734void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
735 QualType &ResTy,
736 FunctionArgList &Params) {
737 /// Create the 'this' variable.
738 BuildThisParam(CGF, Params);
739
740 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
741 assert(MD->isInstance());
742
743 // Check if we need a VTT parameter as well.
744 if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
745 ASTContext &Context = CGF.getContext();
746
747 // FIXME: avoid the fake decl
748 QualType T = Context.getPointerType(Context.VoidPtrTy);
749 ImplicitParamDecl *VTTDecl
750 = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
751 &Context.Idents.get("vtt"), T);
752 Params.push_back(std::make_pair(VTTDecl, VTTDecl->getType()));
753 getVTTDecl(CGF) = VTTDecl;
754 }
755}
756
757void ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
758 QualType &ResTy,
759 FunctionArgList &Params) {
760 ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
761
762 // Return 'this' from certain constructors and destructors.
763 if (HasThisReturn(CGF.CurGD))
764 ResTy = Params[0].second;
765}
766
767void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
768 /// Initialize the 'this' slot.
769 EmitThisParam(CGF);
770
771 /// Initialize the 'vtt' slot if needed.
772 if (getVTTDecl(CGF)) {
773 getVTTValue(CGF)
774 = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
775 "vtt");
776 }
777}
778
779void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
780 ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
781
782 /// Initialize the return slot to 'this' at the start of the
783 /// function.
784 if (HasThisReturn(CGF.CurGD))
785 CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue);
786}
787
788void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
789 RValue RV, QualType ResultType) {
790 if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
791 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
792
793 // Destructor thunks in the ARM ABI have indeterminate results.
794 const llvm::Type *T =
795 cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
796 RValue Undef = RValue::get(llvm::UndefValue::get(T));
797 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
798}
John McCall1e7fe752010-09-02 09:58:18 +0000799
800/************************** Array allocation cookies **************************/
801
802bool ItaniumCXXABI::NeedsArrayCookie(QualType ElementType) {
803 ElementType = CGM.getContext().getBaseElementType(ElementType);
804 const RecordType *RT = ElementType->getAs<RecordType>();
805 if (!RT) return false;
806
807 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
808
809 // If the class has a non-trivial destructor, it always needs a cookie.
810 if (!RD->hasTrivialDestructor()) return true;
811
812 // If the class's usual deallocation function takes two arguments,
813 // it needs a cookie. Otherwise we don't need a cookie.
814 const CXXMethodDecl *UsualDeallocationFunction = 0;
815
816 // Usual deallocation functions of this form are always found on the
817 // class.
818 //
819 // FIXME: what exactly is this code supposed to do if there's an
820 // ambiguity? That's possible with using declarations.
821 DeclarationName OpName =
822 CGM.getContext().DeclarationNames.getCXXOperatorName(OO_Array_Delete);
823 DeclContext::lookup_const_iterator Op, OpEnd;
824 for (llvm::tie(Op, OpEnd) = RD->lookup(OpName); Op != OpEnd; ++Op) {
825 const CXXMethodDecl *Delete =
826 cast<CXXMethodDecl>((*Op)->getUnderlyingDecl());
827
828 if (Delete->isUsualDeallocationFunction()) {
829 UsualDeallocationFunction = Delete;
830 break;
831 }
832 }
833
834 // No usual deallocation function, we don't need a cookie.
835 if (!UsualDeallocationFunction)
836 return false;
837
838 // The usual deallocation function doesn't take a size_t argument,
839 // so we don't need a cookie.
840 if (UsualDeallocationFunction->getNumParams() == 1)
841 return false;
842
843 assert(UsualDeallocationFunction->getNumParams() == 2 &&
844 "Unexpected deallocation function type!");
845 return true;
846}
847
848CharUnits ItaniumCXXABI::GetArrayCookieSize(QualType ElementType) {
849 if (!NeedsArrayCookie(ElementType))
850 return CharUnits::Zero();
851
852 // Padding is the maximum of sizeof(size_t) and alignof(ElementType)
853 ASTContext &Ctx = CGM.getContext();
854 return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
855 Ctx.getTypeAlignInChars(ElementType));
856}
857
858llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
859 llvm::Value *NewPtr,
860 llvm::Value *NumElements,
861 QualType ElementType) {
862 assert(NeedsArrayCookie(ElementType));
863
864 unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
865
866 ASTContext &Ctx = CGM.getContext();
867 QualType SizeTy = Ctx.getSizeType();
868 CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
869
870 // The size of the cookie.
871 CharUnits CookieSize =
872 std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
873
874 // Compute an offset to the cookie.
875 llvm::Value *CookiePtr = NewPtr;
876 CharUnits CookieOffset = CookieSize - SizeSize;
877 if (!CookieOffset.isZero())
878 CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
879 CookieOffset.getQuantity());
880
881 // Write the number of elements into the appropriate slot.
882 llvm::Value *NumElementsPtr
883 = CGF.Builder.CreateBitCast(CookiePtr,
884 CGF.ConvertType(SizeTy)->getPointerTo(AS));
885 CGF.Builder.CreateStore(NumElements, NumElementsPtr);
886
887 // Finally, compute a pointer to the actual data buffer by skipping
888 // over the cookie completely.
889 return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
890 CookieSize.getQuantity());
891}
892
893void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
894 llvm::Value *Ptr,
895 QualType ElementType,
896 llvm::Value *&NumElements,
897 llvm::Value *&AllocPtr,
898 CharUnits &CookieSize) {
899 // Derive a char* in the same address space as the pointer.
900 unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
901 const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
902
903 // If we don't need an array cookie, bail out early.
904 if (!NeedsArrayCookie(ElementType)) {
905 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
906 NumElements = 0;
907 CookieSize = CharUnits::Zero();
908 return;
909 }
910
911 QualType SizeTy = CGF.getContext().getSizeType();
912 CharUnits SizeSize = CGF.getContext().getTypeSizeInChars(SizeTy);
913 const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
914
915 CookieSize
916 = std::max(SizeSize, CGF.getContext().getTypeAlignInChars(ElementType));
917
918 CharUnits NumElementsOffset = CookieSize - SizeSize;
919
920 // Compute the allocated pointer.
921 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
922 AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
923 -CookieSize.getQuantity());
924
925 llvm::Value *NumElementsPtr = AllocPtr;
926 if (!NumElementsOffset.isZero())
927 NumElementsPtr =
928 CGF.Builder.CreateConstInBoundsGEP1_64(NumElementsPtr,
929 NumElementsOffset.getQuantity());
930 NumElementsPtr =
931 CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
932 NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
933}
934
935CharUnits ARMCXXABI::GetArrayCookieSize(QualType ElementType) {
936 if (!NeedsArrayCookie(ElementType))
937 return CharUnits::Zero();
938
939 // On ARM, the cookie is always:
940 // struct array_cookie {
941 // std::size_t element_size; // element_size != 0
942 // std::size_t element_count;
943 // };
944 // TODO: what should we do if the allocated type actually wants
945 // greater alignment?
946 return getContext().getTypeSizeInChars(getContext().getSizeType()) * 2;
947}
948
949llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
950 llvm::Value *NewPtr,
951 llvm::Value *NumElements,
952 QualType ElementType) {
953 assert(NeedsArrayCookie(ElementType));
954
955 // NewPtr is a char*.
956
957 unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
958
959 ASTContext &Ctx = CGM.getContext();
960 CharUnits SizeSize = Ctx.getTypeSizeInChars(Ctx.getSizeType());
961 const llvm::IntegerType *SizeTy =
962 cast<llvm::IntegerType>(CGF.ConvertType(Ctx.getSizeType()));
963
964 // The cookie is always at the start of the buffer.
965 llvm::Value *CookiePtr = NewPtr;
966
967 // The first element is the element size.
968 CookiePtr = CGF.Builder.CreateBitCast(CookiePtr, SizeTy->getPointerTo(AS));
969 llvm::Value *ElementSize = llvm::ConstantInt::get(SizeTy,
970 Ctx.getTypeSizeInChars(ElementType).getQuantity());
971 CGF.Builder.CreateStore(ElementSize, CookiePtr);
972
973 // The second element is the element count.
974 CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_32(CookiePtr, 1);
975 CGF.Builder.CreateStore(NumElements, CookiePtr);
976
977 // Finally, compute a pointer to the actual data buffer by skipping
978 // over the cookie completely.
979 CharUnits CookieSize = 2 * SizeSize;
980 return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
981 CookieSize.getQuantity());
982}
983
984void ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
985 llvm::Value *Ptr,
986 QualType ElementType,
987 llvm::Value *&NumElements,
988 llvm::Value *&AllocPtr,
989 CharUnits &CookieSize) {
990 // Derive a char* in the same address space as the pointer.
991 unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
992 const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
993
994 // If we don't need an array cookie, bail out early.
995 if (!NeedsArrayCookie(ElementType)) {
996 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
997 NumElements = 0;
998 CookieSize = CharUnits::Zero();
999 return;
1000 }
1001
1002 QualType SizeTy = CGF.getContext().getSizeType();
1003 CharUnits SizeSize = CGF.getContext().getTypeSizeInChars(SizeTy);
1004 const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
1005
1006 // The cookie size is always 2 * sizeof(size_t).
1007 CookieSize = 2 * SizeSize;
1008 CharUnits NumElementsOffset = CookieSize - SizeSize;
1009
1010 // The allocated pointer is the input ptr, minus that amount.
1011 AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
1012 AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1013 -CookieSize.getQuantity());
1014
1015 // The number of elements is at offset sizeof(size_t) relative to that.
1016 llvm::Value *NumElementsPtr
1017 = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1018 SizeSize.getQuantity());
1019 NumElementsPtr =
1020 CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
1021 NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
1022}
1023