ItaniumCXXABI.cpp revision 249423
1208600Srdivacky//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
2208600Srdivacky//
3208600Srdivacky//                     The LLVM Compiler Infrastructure
4208600Srdivacky//
5208600Srdivacky// This file is distributed under the University of Illinois Open Source
6208600Srdivacky// License. See LICENSE.TXT for details.
7208600Srdivacky//
8208600Srdivacky//===----------------------------------------------------------------------===//
9208600Srdivacky//
10221345Sdim// This provides C++ code generation targeting the Itanium C++ ABI.  The class
11208600Srdivacky// in this file generates structures that follow the Itanium C++ ABI, which is
12208600Srdivacky// documented at:
13208600Srdivacky//  http://www.codesourcery.com/public/cxx-abi/abi.html
14208600Srdivacky//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
15212904Sdim//
16212904Sdim// It also supports the closely-related ARM ABI, documented at:
17212904Sdim// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
18212904Sdim//
19208600Srdivacky//===----------------------------------------------------------------------===//
20208600Srdivacky
21208600Srdivacky#include "CGCXXABI.h"
22212904Sdim#include "CGRecordLayout.h"
23239462Sdim#include "CGVTables.h"
24212904Sdim#include "CodeGenFunction.h"
25208600Srdivacky#include "CodeGenModule.h"
26243830Sdim#include "clang/AST/Mangle.h"
27243830Sdim#include "clang/AST/Type.h"
28249423Sdim#include "llvm/IR/DataLayout.h"
29249423Sdim#include "llvm/IR/Intrinsics.h"
30249423Sdim#include "llvm/IR/Value.h"
31208600Srdivacky
32208600Srdivackyusing namespace clang;
33212904Sdimusing namespace CodeGen;
34208600Srdivacky
35208600Srdivackynamespace {
36212904Sdimclass ItaniumCXXABI : public CodeGen::CGCXXABI {
37212904Sdimprotected:
38212904Sdim  bool IsARM;
39212904Sdim
40208600Srdivackypublic:
41212904Sdim  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
42249423Sdim    CGCXXABI(CGM), IsARM(IsARM) { }
43208600Srdivacky
44212904Sdim  bool isZeroInitializable(const MemberPointerType *MPT);
45212904Sdim
46224145Sdim  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
47212904Sdim
48212904Sdim  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
49212904Sdim                                               llvm::Value *&This,
50212904Sdim                                               llvm::Value *MemFnPtr,
51212904Sdim                                               const MemberPointerType *MPT);
52212904Sdim
53212904Sdim  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
54212904Sdim                                            llvm::Value *Base,
55212904Sdim                                            llvm::Value *MemPtr,
56212904Sdim                                            const MemberPointerType *MPT);
57212904Sdim
58212904Sdim  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
59212904Sdim                                           const CastExpr *E,
60212904Sdim                                           llvm::Value *Src);
61234353Sdim  llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
62234353Sdim                                              llvm::Constant *Src);
63212904Sdim
64212904Sdim  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
65212904Sdim
66212904Sdim  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
67218893Sdim  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
68218893Sdim                                        CharUnits offset);
69234353Sdim  llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
70234353Sdim  llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
71234353Sdim                                     CharUnits ThisAdjustment);
72212904Sdim
73212904Sdim  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
74212904Sdim                                           llvm::Value *L,
75212904Sdim                                           llvm::Value *R,
76212904Sdim                                           const MemberPointerType *MPT,
77212904Sdim                                           bool Inequality);
78212904Sdim
79212904Sdim  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
80212904Sdim                                          llvm::Value *Addr,
81212904Sdim                                          const MemberPointerType *MPT);
82212904Sdim
83243830Sdim  llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
84243830Sdim                                      llvm::Value *ptr,
85243830Sdim                                      QualType type);
86243830Sdim
87212904Sdim  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
88212904Sdim                                 CXXCtorType T,
89212904Sdim                                 CanQualType &ResTy,
90226633Sdim                                 SmallVectorImpl<CanQualType> &ArgTys);
91212904Sdim
92212904Sdim  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
93212904Sdim                                CXXDtorType T,
94212904Sdim                                CanQualType &ResTy,
95226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys);
96212904Sdim
97212904Sdim  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
98212904Sdim                                   QualType &ResTy,
99212904Sdim                                   FunctionArgList &Params);
100212904Sdim
101212904Sdim  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
102212904Sdim
103249423Sdim  llvm::Value *EmitConstructorCall(CodeGenFunction &CGF,
104249423Sdim                           const CXXConstructorDecl *D,
105249423Sdim                           CXXCtorType Type, bool ForVirtualBase,
106249423Sdim                           bool Delegating,
107249423Sdim                           llvm::Value *This,
108249423Sdim                           CallExpr::const_arg_iterator ArgBeg,
109249423Sdim                           CallExpr::const_arg_iterator ArgEnd);
110249423Sdim
111249423Sdim  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
112249423Sdim                                   const CXXDestructorDecl *Dtor,
113249423Sdim                                   CXXDtorType DtorType,
114249423Sdim                                   SourceLocation CallLoc,
115249423Sdim                                   ReturnValueSlot ReturnValue,
116249423Sdim                                   llvm::Value *This);
117249423Sdim
118239462Sdim  StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
119243830Sdim  StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
120239462Sdim
121239462Sdim  CharUnits getArrayCookieSizeImpl(QualType elementType);
122212904Sdim  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
123212904Sdim                                     llvm::Value *NewPtr,
124212904Sdim                                     llvm::Value *NumElements,
125218893Sdim                                     const CXXNewExpr *expr,
126212904Sdim                                     QualType ElementType);
127239462Sdim  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
128239462Sdim                                   llvm::Value *allocPtr,
129239462Sdim                                   CharUnits cookieSize);
130218893Sdim
131218893Sdim  void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
132234353Sdim                       llvm::GlobalVariable *DeclPtr, bool PerformInit);
133239462Sdim  void registerGlobalDtor(CodeGenFunction &CGF, llvm::Constant *dtor,
134239462Sdim                          llvm::Constant *addr);
135208600Srdivacky};
136212904Sdim
137212904Sdimclass ARMCXXABI : public ItaniumCXXABI {
138212904Sdimpublic:
139212904Sdim  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
140212904Sdim
141212904Sdim  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
142212904Sdim                                 CXXCtorType T,
143212904Sdim                                 CanQualType &ResTy,
144226633Sdim                                 SmallVectorImpl<CanQualType> &ArgTys);
145212904Sdim
146212904Sdim  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
147212904Sdim                                CXXDtorType T,
148212904Sdim                                CanQualType &ResTy,
149226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys);
150212904Sdim
151212904Sdim  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
152212904Sdim                                   QualType &ResTy,
153212904Sdim                                   FunctionArgList &Params);
154212904Sdim
155212904Sdim  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
156212904Sdim
157212904Sdim  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
158212904Sdim
159239462Sdim  CharUnits getArrayCookieSizeImpl(QualType elementType);
160212904Sdim  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
161212904Sdim                                     llvm::Value *NewPtr,
162212904Sdim                                     llvm::Value *NumElements,
163218893Sdim                                     const CXXNewExpr *expr,
164212904Sdim                                     QualType ElementType);
165239462Sdim  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,
166239462Sdim                                   CharUnits cookieSize);
167212904Sdim
168212904Sdim  /// \brief Returns true if the given instance method is one of the
169212904Sdim  /// kinds that the ARM ABI says returns 'this'.
170249423Sdim  bool HasThisReturn(GlobalDecl GD) const {
171249423Sdim    const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(GD.getDecl());
172249423Sdim    if (!MD) return false;
173212904Sdim    return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) ||
174212904Sdim            (isa<CXXConstructorDecl>(MD)));
175212904Sdim  }
176212904Sdim};
177208600Srdivacky}
178208600Srdivacky
179212904SdimCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
180249423Sdim  switch (CGM.getContext().getTargetInfo().getCXXABI().getKind()) {
181249423Sdim  // For IR-generation purposes, there's no significant difference
182249423Sdim  // between the ARM and iOS ABIs.
183249423Sdim  case TargetCXXABI::GenericARM:
184249423Sdim  case TargetCXXABI::iOS:
185249423Sdim    return new ARMCXXABI(CGM);
186208600Srdivacky
187249423Sdim  // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
188249423Sdim  // include the other 32-bit ARM oddities: constructor/destructor return values
189249423Sdim  // and array cookies.
190249423Sdim  case TargetCXXABI::GenericAArch64:
191249423Sdim    return  new ItaniumCXXABI(CGM, /*IsARM = */ true);
192249423Sdim
193249423Sdim  case TargetCXXABI::GenericItanium:
194249423Sdim    return new ItaniumCXXABI(CGM);
195249423Sdim
196249423Sdim  case TargetCXXABI::Microsoft:
197249423Sdim    llvm_unreachable("Microsoft ABI is not Itanium-based");
198249423Sdim  }
199249423Sdim  llvm_unreachable("bad ABI kind");
200212904Sdim}
201212904Sdim
202224145Sdimllvm::Type *
203212904SdimItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
204212904Sdim  if (MPT->isMemberDataPointer())
205249423Sdim    return CGM.PtrDiffTy;
206249423Sdim  return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, NULL);
207212904Sdim}
208212904Sdim
209212904Sdim/// In the Itanium and ARM ABIs, method pointers have the form:
210212904Sdim///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
211212904Sdim///
212212904Sdim/// In the Itanium ABI:
213212904Sdim///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
214212904Sdim///  - the this-adjustment is (memptr.adj)
215212904Sdim///  - the virtual offset is (memptr.ptr - 1)
216212904Sdim///
217212904Sdim/// In the ARM ABI:
218212904Sdim///  - method pointers are virtual if (memptr.adj & 1) is nonzero
219212904Sdim///  - the this-adjustment is (memptr.adj >> 1)
220212904Sdim///  - the virtual offset is (memptr.ptr)
221212904Sdim/// ARM uses 'adj' for the virtual flag because Thumb functions
222212904Sdim/// may be only single-byte aligned.
223212904Sdim///
224212904Sdim/// If the member is virtual, the adjusted 'this' pointer points
225212904Sdim/// to a vtable pointer from which the virtual offset is applied.
226212904Sdim///
227212904Sdim/// If the member is non-virtual, memptr.ptr is the address of
228212904Sdim/// the function to call.
229212904Sdimllvm::Value *
230212904SdimItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
231212904Sdim                                               llvm::Value *&This,
232212904Sdim                                               llvm::Value *MemFnPtr,
233212904Sdim                                               const MemberPointerType *MPT) {
234212904Sdim  CGBuilderTy &Builder = CGF.Builder;
235212904Sdim
236212904Sdim  const FunctionProtoType *FPT =
237212904Sdim    MPT->getPointeeType()->getAs<FunctionProtoType>();
238212904Sdim  const CXXRecordDecl *RD =
239212904Sdim    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
240212904Sdim
241226633Sdim  llvm::FunctionType *FTy =
242234353Sdim    CGM.getTypes().GetFunctionType(
243234353Sdim      CGM.getTypes().arrangeCXXMethodType(RD, FPT));
244212904Sdim
245249423Sdim  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
246212904Sdim
247212904Sdim  llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
248212904Sdim  llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
249212904Sdim  llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
250212904Sdim
251212904Sdim  // Extract memptr.adj, which is in the second field.
252212904Sdim  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
253212904Sdim
254212904Sdim  // Compute the true adjustment.
255212904Sdim  llvm::Value *Adj = RawAdj;
256212904Sdim  if (IsARM)
257212904Sdim    Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
258212904Sdim
259212904Sdim  // Apply the adjustment and cast back to the original struct type
260212904Sdim  // for consistency.
261212904Sdim  llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
262212904Sdim  Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
263212904Sdim  This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
264212904Sdim
265212904Sdim  // Load the function pointer.
266212904Sdim  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
267212904Sdim
268212904Sdim  // If the LSB in the function pointer is 1, the function pointer points to
269212904Sdim  // a virtual function.
270212904Sdim  llvm::Value *IsVirtual;
271212904Sdim  if (IsARM)
272212904Sdim    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
273212904Sdim  else
274212904Sdim    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
275212904Sdim  IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
276212904Sdim  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
277212904Sdim
278212904Sdim  // In the virtual path, the adjustment left 'This' pointing to the
279212904Sdim  // vtable of the correct base subobject.  The "function pointer" is an
280212904Sdim  // offset within the vtable (+1 for the virtual flag on non-ARM).
281212904Sdim  CGF.EmitBlock(FnVirtual);
282212904Sdim
283212904Sdim  // Cast the adjusted this to a pointer to vtable pointer and load.
284226633Sdim  llvm::Type *VTableTy = Builder.getInt8PtrTy();
285212904Sdim  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
286212904Sdim  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
287212904Sdim
288212904Sdim  // Apply the offset.
289212904Sdim  llvm::Value *VTableOffset = FnAsInt;
290212904Sdim  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
291212904Sdim  VTable = Builder.CreateGEP(VTable, VTableOffset);
292212904Sdim
293212904Sdim  // Load the virtual function to call.
294212904Sdim  VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
295212904Sdim  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
296212904Sdim  CGF.EmitBranch(FnEnd);
297212904Sdim
298212904Sdim  // In the non-virtual path, the function pointer is actually a
299212904Sdim  // function pointer.
300212904Sdim  CGF.EmitBlock(FnNonVirtual);
301212904Sdim  llvm::Value *NonVirtualFn =
302212904Sdim    Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
303212904Sdim
304212904Sdim  // We're done.
305212904Sdim  CGF.EmitBlock(FnEnd);
306221345Sdim  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
307212904Sdim  Callee->addIncoming(VirtualFn, FnVirtual);
308212904Sdim  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
309212904Sdim  return Callee;
310212904Sdim}
311212904Sdim
312212904Sdim/// Compute an l-value by applying the given pointer-to-member to a
313212904Sdim/// base object.
314212904Sdimllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
315212904Sdim                                                         llvm::Value *Base,
316212904Sdim                                                         llvm::Value *MemPtr,
317212904Sdim                                           const MemberPointerType *MPT) {
318249423Sdim  assert(MemPtr->getType() == CGM.PtrDiffTy);
319212904Sdim
320212904Sdim  CGBuilderTy &Builder = CGF.Builder;
321212904Sdim
322243830Sdim  unsigned AS = Base->getType()->getPointerAddressSpace();
323212904Sdim
324212904Sdim  // Cast to char*.
325212904Sdim  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
326212904Sdim
327212904Sdim  // Apply the offset, which we assume is non-null.
328212904Sdim  llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
329212904Sdim
330212904Sdim  // Cast the address to the appropriate pointer type, adopting the
331212904Sdim  // address space of the base pointer.
332226633Sdim  llvm::Type *PType
333212904Sdim    = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
334212904Sdim  return Builder.CreateBitCast(Addr, PType);
335212904Sdim}
336212904Sdim
337234353Sdim/// Perform a bitcast, derived-to-base, or base-to-derived member pointer
338234353Sdim/// conversion.
339212904Sdim///
340234353Sdim/// Bitcast conversions are always a no-op under Itanium.
341234353Sdim///
342212904Sdim/// Obligatory offset/adjustment diagram:
343212904Sdim///         <-- offset -->          <-- adjustment -->
344212904Sdim///   |--------------------------|----------------------|--------------------|
345212904Sdim///   ^Derived address point     ^Base address point    ^Member address point
346212904Sdim///
347212904Sdim/// So when converting a base member pointer to a derived member pointer,
348212904Sdim/// we add the offset to the adjustment because the address point has
349212904Sdim/// decreased;  and conversely, when converting a derived MP to a base MP
350212904Sdim/// we subtract the offset from the adjustment because the address point
351212904Sdim/// has increased.
352212904Sdim///
353212904Sdim/// The standard forbids (at compile time) conversion to and from
354212904Sdim/// virtual bases, which is why we don't have to consider them here.
355212904Sdim///
356212904Sdim/// The standard forbids (at run time) casting a derived MP to a base
357212904Sdim/// MP when the derived MP does not point to a member of the base.
358212904Sdim/// This is why -1 is a reasonable choice for null data member
359212904Sdim/// pointers.
360212904Sdimllvm::Value *
361212904SdimItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
362212904Sdim                                           const CastExpr *E,
363234353Sdim                                           llvm::Value *src) {
364212904Sdim  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
365234353Sdim         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
366234353Sdim         E->getCastKind() == CK_ReinterpretMemberPointer);
367212904Sdim
368234353Sdim  // Under Itanium, reinterprets don't require any additional processing.
369234353Sdim  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
370212904Sdim
371234353Sdim  // Use constant emission if we can.
372234353Sdim  if (isa<llvm::Constant>(src))
373234353Sdim    return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
374212904Sdim
375234353Sdim  llvm::Constant *adj = getMemberPointerAdjustment(E);
376234353Sdim  if (!adj) return src;
377212904Sdim
378234353Sdim  CGBuilderTy &Builder = CGF.Builder;
379234353Sdim  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
380212904Sdim
381234353Sdim  const MemberPointerType *destTy =
382234353Sdim    E->getType()->castAs<MemberPointerType>();
383212904Sdim
384212904Sdim  // For member data pointers, this is just a matter of adding the
385212904Sdim  // offset if the source is non-null.
386234353Sdim  if (destTy->isMemberDataPointer()) {
387234353Sdim    llvm::Value *dst;
388234353Sdim    if (isDerivedToBase)
389234353Sdim      dst = Builder.CreateNSWSub(src, adj, "adj");
390212904Sdim    else
391234353Sdim      dst = Builder.CreateNSWAdd(src, adj, "adj");
392212904Sdim
393212904Sdim    // Null check.
394234353Sdim    llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
395234353Sdim    llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
396234353Sdim    return Builder.CreateSelect(isNull, src, dst);
397212904Sdim  }
398212904Sdim
399212904Sdim  // The this-adjustment is left-shifted by 1 on ARM.
400212904Sdim  if (IsARM) {
401234353Sdim    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
402234353Sdim    offset <<= 1;
403234353Sdim    adj = llvm::ConstantInt::get(adj->getType(), offset);
404212904Sdim  }
405212904Sdim
406234353Sdim  llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
407234353Sdim  llvm::Value *dstAdj;
408234353Sdim  if (isDerivedToBase)
409234353Sdim    dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
410212904Sdim  else
411234353Sdim    dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
412212904Sdim
413234353Sdim  return Builder.CreateInsertValue(src, dstAdj, 1);
414212904Sdim}
415212904Sdim
416212904Sdimllvm::Constant *
417234353SdimItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
418234353Sdim                                           llvm::Constant *src) {
419234353Sdim  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
420234353Sdim         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
421234353Sdim         E->getCastKind() == CK_ReinterpretMemberPointer);
422212904Sdim
423234353Sdim  // Under Itanium, reinterprets don't require any additional processing.
424234353Sdim  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
425212904Sdim
426234353Sdim  // If the adjustment is trivial, we don't need to do anything.
427234353Sdim  llvm::Constant *adj = getMemberPointerAdjustment(E);
428234353Sdim  if (!adj) return src;
429212904Sdim
430234353Sdim  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
431212904Sdim
432234353Sdim  const MemberPointerType *destTy =
433234353Sdim    E->getType()->castAs<MemberPointerType>();
434212904Sdim
435234353Sdim  // For member data pointers, this is just a matter of adding the
436234353Sdim  // offset if the source is non-null.
437234353Sdim  if (destTy->isMemberDataPointer()) {
438234353Sdim    // null maps to null.
439234353Sdim    if (src->isAllOnesValue()) return src;
440212904Sdim
441234353Sdim    if (isDerivedToBase)
442234353Sdim      return llvm::ConstantExpr::getNSWSub(src, adj);
443212904Sdim    else
444234353Sdim      return llvm::ConstantExpr::getNSWAdd(src, adj);
445212904Sdim  }
446212904Sdim
447212904Sdim  // The this-adjustment is left-shifted by 1 on ARM.
448212904Sdim  if (IsARM) {
449234353Sdim    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
450234353Sdim    offset <<= 1;
451234353Sdim    adj = llvm::ConstantInt::get(adj->getType(), offset);
452212904Sdim  }
453212904Sdim
454234353Sdim  llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
455234353Sdim  llvm::Constant *dstAdj;
456234353Sdim  if (isDerivedToBase)
457234353Sdim    dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
458212904Sdim  else
459234353Sdim    dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
460212904Sdim
461234353Sdim  return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
462234353Sdim}
463212904Sdim
464212904Sdimllvm::Constant *
465212904SdimItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
466212904Sdim  // Itanium C++ ABI 2.3:
467212904Sdim  //   A NULL pointer is represented as -1.
468212904Sdim  if (MPT->isMemberDataPointer())
469249423Sdim    return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);
470212904Sdim
471249423Sdim  llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
472212904Sdim  llvm::Constant *Values[2] = { Zero, Zero };
473224145Sdim  return llvm::ConstantStruct::getAnon(Values);
474212904Sdim}
475212904Sdim
476218893Sdimllvm::Constant *
477218893SdimItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
478218893Sdim                                     CharUnits offset) {
479212904Sdim  // Itanium C++ ABI 2.3:
480212904Sdim  //   A pointer to data member is an offset from the base address of
481212904Sdim  //   the class object containing it, represented as a ptrdiff_t
482249423Sdim  return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
483212904Sdim}
484212904Sdim
485212904Sdimllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
486234353Sdim  return BuildMemberPointer(MD, CharUnits::Zero());
487234353Sdim}
488234353Sdim
489234353Sdimllvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
490234353Sdim                                                  CharUnits ThisAdjustment) {
491212904Sdim  assert(MD->isInstance() && "Member function must not be static!");
492212904Sdim  MD = MD->getCanonicalDecl();
493212904Sdim
494212904Sdim  CodeGenTypes &Types = CGM.getTypes();
495212904Sdim
496212904Sdim  // Get the function pointer (or index if this is a virtual function).
497212904Sdim  llvm::Constant *MemPtr[2];
498212904Sdim  if (MD->isVirtual()) {
499226633Sdim    uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
500212904Sdim
501221345Sdim    const ASTContext &Context = getContext();
502221345Sdim    CharUnits PointerWidth =
503226633Sdim      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
504221345Sdim    uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
505212904Sdim
506212904Sdim    if (IsARM) {
507212904Sdim      // ARM C++ ABI 3.2.1:
508212904Sdim      //   This ABI specifies that adj contains twice the this
509212904Sdim      //   adjustment, plus 1 if the member function is virtual. The
510212904Sdim      //   least significant bit of adj then makes exactly the same
511212904Sdim      //   discrimination as the least significant bit of ptr does for
512212904Sdim      //   Itanium.
513249423Sdim      MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
514249423Sdim      MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
515234353Sdim                                         2 * ThisAdjustment.getQuantity() + 1);
516212904Sdim    } else {
517212904Sdim      // Itanium C++ ABI 2.3:
518212904Sdim      //   For a virtual function, [the pointer field] is 1 plus the
519212904Sdim      //   virtual table offset (in bytes) of the function,
520212904Sdim      //   represented as a ptrdiff_t.
521249423Sdim      MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
522249423Sdim      MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
523234353Sdim                                         ThisAdjustment.getQuantity());
524212904Sdim    }
525212904Sdim  } else {
526221345Sdim    const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
527226633Sdim    llvm::Type *Ty;
528212904Sdim    // Check whether the function has a computable LLVM signature.
529224145Sdim    if (Types.isFuncTypeConvertible(FPT)) {
530212904Sdim      // The function has a computable LLVM signature; use the correct type.
531234353Sdim      Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
532212904Sdim    } else {
533212904Sdim      // Use an arbitrary non-function type to tell GetAddrOfFunction that the
534212904Sdim      // function type is incomplete.
535249423Sdim      Ty = CGM.PtrDiffTy;
536212904Sdim    }
537221345Sdim    llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
538212904Sdim
539249423Sdim    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
540249423Sdim    MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, (IsARM ? 2 : 1) *
541234353Sdim                                       ThisAdjustment.getQuantity());
542212904Sdim  }
543212904Sdim
544224145Sdim  return llvm::ConstantStruct::getAnon(MemPtr);
545212904Sdim}
546212904Sdim
547234353Sdimllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
548234353Sdim                                                 QualType MPType) {
549234353Sdim  const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();
550234353Sdim  const ValueDecl *MPD = MP.getMemberPointerDecl();
551234353Sdim  if (!MPD)
552234353Sdim    return EmitNullMemberPointer(MPT);
553234353Sdim
554234353Sdim  // Compute the this-adjustment.
555234353Sdim  CharUnits ThisAdjustment = CharUnits::Zero();
556234353Sdim  ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
557234353Sdim  bool DerivedMember = MP.isMemberPointerToDerivedMember();
558234353Sdim  const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
559234353Sdim  for (unsigned I = 0, N = Path.size(); I != N; ++I) {
560234353Sdim    const CXXRecordDecl *Base = RD;
561234353Sdim    const CXXRecordDecl *Derived = Path[I];
562234353Sdim    if (DerivedMember)
563234353Sdim      std::swap(Base, Derived);
564234353Sdim    ThisAdjustment +=
565234353Sdim      getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
566234353Sdim    RD = Path[I];
567234353Sdim  }
568234353Sdim  if (DerivedMember)
569234353Sdim    ThisAdjustment = -ThisAdjustment;
570234353Sdim
571234353Sdim  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
572234353Sdim    return BuildMemberPointer(MD, ThisAdjustment);
573234353Sdim
574234353Sdim  CharUnits FieldOffset =
575234353Sdim    getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
576234353Sdim  return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
577234353Sdim}
578234353Sdim
579212904Sdim/// The comparison algorithm is pretty easy: the member pointers are
580212904Sdim/// the same if they're either bitwise identical *or* both null.
581212904Sdim///
582212904Sdim/// ARM is different here only because null-ness is more complicated.
583212904Sdimllvm::Value *
584212904SdimItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
585212904Sdim                                           llvm::Value *L,
586212904Sdim                                           llvm::Value *R,
587212904Sdim                                           const MemberPointerType *MPT,
588212904Sdim                                           bool Inequality) {
589212904Sdim  CGBuilderTy &Builder = CGF.Builder;
590212904Sdim
591212904Sdim  llvm::ICmpInst::Predicate Eq;
592212904Sdim  llvm::Instruction::BinaryOps And, Or;
593212904Sdim  if (Inequality) {
594212904Sdim    Eq = llvm::ICmpInst::ICMP_NE;
595212904Sdim    And = llvm::Instruction::Or;
596212904Sdim    Or = llvm::Instruction::And;
597212904Sdim  } else {
598212904Sdim    Eq = llvm::ICmpInst::ICMP_EQ;
599212904Sdim    And = llvm::Instruction::And;
600212904Sdim    Or = llvm::Instruction::Or;
601212904Sdim  }
602212904Sdim
603212904Sdim  // Member data pointers are easy because there's a unique null
604212904Sdim  // value, so it just comes down to bitwise equality.
605212904Sdim  if (MPT->isMemberDataPointer())
606212904Sdim    return Builder.CreateICmp(Eq, L, R);
607212904Sdim
608212904Sdim  // For member function pointers, the tautologies are more complex.
609212904Sdim  // The Itanium tautology is:
610212904Sdim  //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
611212904Sdim  // The ARM tautology is:
612212904Sdim  //   (L == R) <==> (L.ptr == R.ptr &&
613212904Sdim  //                  (L.adj == R.adj ||
614212904Sdim  //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
615212904Sdim  // The inequality tautologies have exactly the same structure, except
616212904Sdim  // applying De Morgan's laws.
617212904Sdim
618212904Sdim  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
619212904Sdim  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
620212904Sdim
621212904Sdim  // This condition tests whether L.ptr == R.ptr.  This must always be
622212904Sdim  // true for equality to hold.
623212904Sdim  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
624212904Sdim
625212904Sdim  // This condition, together with the assumption that L.ptr == R.ptr,
626212904Sdim  // tests whether the pointers are both null.  ARM imposes an extra
627212904Sdim  // condition.
628212904Sdim  llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
629212904Sdim  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
630212904Sdim
631212904Sdim  // This condition tests whether L.adj == R.adj.  If this isn't
632212904Sdim  // true, the pointers are unequal unless they're both null.
633212904Sdim  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
634212904Sdim  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
635212904Sdim  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
636212904Sdim
637212904Sdim  // Null member function pointers on ARM clear the low bit of Adj,
638212904Sdim  // so the zero condition has to check that neither low bit is set.
639212904Sdim  if (IsARM) {
640212904Sdim    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
641212904Sdim
642212904Sdim    // Compute (l.adj | r.adj) & 1 and test it against zero.
643212904Sdim    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
644212904Sdim    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
645212904Sdim    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
646212904Sdim                                                      "cmp.or.adj");
647212904Sdim    EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
648212904Sdim  }
649212904Sdim
650212904Sdim  // Tie together all our conditions.
651212904Sdim  llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
652212904Sdim  Result = Builder.CreateBinOp(And, PtrEq, Result,
653212904Sdim                               Inequality ? "memptr.ne" : "memptr.eq");
654212904Sdim  return Result;
655212904Sdim}
656212904Sdim
657212904Sdimllvm::Value *
658212904SdimItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
659212904Sdim                                          llvm::Value *MemPtr,
660212904Sdim                                          const MemberPointerType *MPT) {
661212904Sdim  CGBuilderTy &Builder = CGF.Builder;
662212904Sdim
663212904Sdim  /// For member data pointers, this is just a check against -1.
664212904Sdim  if (MPT->isMemberDataPointer()) {
665249423Sdim    assert(MemPtr->getType() == CGM.PtrDiffTy);
666212904Sdim    llvm::Value *NegativeOne =
667212904Sdim      llvm::Constant::getAllOnesValue(MemPtr->getType());
668212904Sdim    return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
669212904Sdim  }
670212904Sdim
671221345Sdim  // In Itanium, a member function pointer is not null if 'ptr' is not null.
672212904Sdim  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
673212904Sdim
674212904Sdim  llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
675212904Sdim  llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
676212904Sdim
677221345Sdim  // On ARM, a member function pointer is also non-null if the low bit of 'adj'
678221345Sdim  // (the virtual bit) is set.
679212904Sdim  if (IsARM) {
680212904Sdim    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
681212904Sdim    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
682212904Sdim    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
683221345Sdim    llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
684221345Sdim                                                  "memptr.isvirtual");
685221345Sdim    Result = Builder.CreateOr(Result, IsVirtual);
686212904Sdim  }
687212904Sdim
688212904Sdim  return Result;
689212904Sdim}
690212904Sdim
691212904Sdim/// The Itanium ABI requires non-zero initialization only for data
692212904Sdim/// member pointers, for which '0' is a valid offset.
693212904Sdimbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
694212904Sdim  return MPT->getPointeeType()->isFunctionType();
695212904Sdim}
696212904Sdim
697243830Sdim/// The Itanium ABI always places an offset to the complete object
698243830Sdim/// at entry -2 in the vtable.
699243830Sdimllvm::Value *ItaniumCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
700243830Sdim                                                   llvm::Value *ptr,
701243830Sdim                                                   QualType type) {
702243830Sdim  // Grab the vtable pointer as an intptr_t*.
703243830Sdim  llvm::Value *vtable = CGF.GetVTablePtr(ptr, CGF.IntPtrTy->getPointerTo());
704243830Sdim
705243830Sdim  // Track back to entry -2 and pull out the offset there.
706243830Sdim  llvm::Value *offsetPtr =
707243830Sdim    CGF.Builder.CreateConstInBoundsGEP1_64(vtable, -2, "complete-offset.ptr");
708243830Sdim  llvm::LoadInst *offset = CGF.Builder.CreateLoad(offsetPtr);
709243830Sdim  offset->setAlignment(CGF.PointerAlignInBytes);
710243830Sdim
711243830Sdim  // Apply the offset.
712243830Sdim  ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy);
713243830Sdim  return CGF.Builder.CreateInBoundsGEP(ptr, offset);
714243830Sdim}
715243830Sdim
716212904Sdim/// The generic ABI passes 'this', plus a VTT if it's initializing a
717212904Sdim/// base subobject.
718212904Sdimvoid ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
719212904Sdim                                              CXXCtorType Type,
720212904Sdim                                              CanQualType &ResTy,
721226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
722212904Sdim  ASTContext &Context = getContext();
723212904Sdim
724212904Sdim  // 'this' is already there.
725212904Sdim
726212904Sdim  // Check if we need to add a VTT parameter (which has type void **).
727212904Sdim  if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
728212904Sdim    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
729212904Sdim}
730212904Sdim
731212904Sdim/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
732212904Sdimvoid ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
733212904Sdim                                          CXXCtorType Type,
734212904Sdim                                          CanQualType &ResTy,
735226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
736212904Sdim  ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
737212904Sdim  ResTy = ArgTys[0];
738212904Sdim}
739212904Sdim
740212904Sdim/// The generic ABI passes 'this', plus a VTT if it's destroying a
741212904Sdim/// base subobject.
742212904Sdimvoid ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
743212904Sdim                                             CXXDtorType Type,
744212904Sdim                                             CanQualType &ResTy,
745226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
746212904Sdim  ASTContext &Context = getContext();
747212904Sdim
748212904Sdim  // 'this' is already there.
749212904Sdim
750212904Sdim  // Check if we need to add a VTT parameter (which has type void **).
751212904Sdim  if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
752212904Sdim    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
753212904Sdim}
754212904Sdim
755212904Sdim/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
756212904Sdim/// for non-deleting destructors.
757212904Sdimvoid ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
758212904Sdim                                         CXXDtorType Type,
759212904Sdim                                         CanQualType &ResTy,
760226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
761212904Sdim  ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
762212904Sdim
763212904Sdim  if (Type != Dtor_Deleting)
764212904Sdim    ResTy = ArgTys[0];
765212904Sdim}
766212904Sdim
767212904Sdimvoid ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
768212904Sdim                                                QualType &ResTy,
769212904Sdim                                                FunctionArgList &Params) {
770212904Sdim  /// Create the 'this' variable.
771212904Sdim  BuildThisParam(CGF, Params);
772212904Sdim
773212904Sdim  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
774212904Sdim  assert(MD->isInstance());
775212904Sdim
776212904Sdim  // Check if we need a VTT parameter as well.
777212904Sdim  if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
778212904Sdim    ASTContext &Context = getContext();
779212904Sdim
780212904Sdim    // FIXME: avoid the fake decl
781212904Sdim    QualType T = Context.getPointerType(Context.VoidPtrTy);
782212904Sdim    ImplicitParamDecl *VTTDecl
783212904Sdim      = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
784212904Sdim                                  &Context.Idents.get("vtt"), T);
785221345Sdim    Params.push_back(VTTDecl);
786212904Sdim    getVTTDecl(CGF) = VTTDecl;
787212904Sdim  }
788212904Sdim}
789212904Sdim
790212904Sdimvoid ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
791212904Sdim                                            QualType &ResTy,
792212904Sdim                                            FunctionArgList &Params) {
793212904Sdim  ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
794212904Sdim
795212904Sdim  // Return 'this' from certain constructors and destructors.
796212904Sdim  if (HasThisReturn(CGF.CurGD))
797221345Sdim    ResTy = Params[0]->getType();
798212904Sdim}
799212904Sdim
800212904Sdimvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
801212904Sdim  /// Initialize the 'this' slot.
802212904Sdim  EmitThisParam(CGF);
803212904Sdim
804212904Sdim  /// Initialize the 'vtt' slot if needed.
805212904Sdim  if (getVTTDecl(CGF)) {
806212904Sdim    getVTTValue(CGF)
807212904Sdim      = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
808212904Sdim                               "vtt");
809212904Sdim  }
810212904Sdim}
811212904Sdim
812212904Sdimvoid ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
813212904Sdim  ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
814212904Sdim
815212904Sdim  /// Initialize the return slot to 'this' at the start of the
816212904Sdim  /// function.
817212904Sdim  if (HasThisReturn(CGF.CurGD))
818234353Sdim    CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
819212904Sdim}
820212904Sdim
821249423Sdimllvm::Value *ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
822249423Sdim                                        const CXXConstructorDecl *D,
823249423Sdim                                        CXXCtorType Type, bool ForVirtualBase,
824249423Sdim                                        bool Delegating,
825249423Sdim                                        llvm::Value *This,
826249423Sdim                                        CallExpr::const_arg_iterator ArgBeg,
827249423Sdim                                        CallExpr::const_arg_iterator ArgEnd) {
828249423Sdim  llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase,
829249423Sdim                                         Delegating);
830249423Sdim  QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
831249423Sdim  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
832249423Sdim
833249423Sdim  // FIXME: Provide a source location here.
834249423Sdim  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
835249423Sdim                        VTT, VTTTy, ArgBeg, ArgEnd);
836249423Sdim  return Callee;
837249423Sdim}
838249423Sdim
839249423SdimRValue ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
840249423Sdim                                                const CXXDestructorDecl *Dtor,
841249423Sdim                                                CXXDtorType DtorType,
842249423Sdim                                                SourceLocation CallLoc,
843249423Sdim                                                ReturnValueSlot ReturnValue,
844249423Sdim                                                llvm::Value *This) {
845249423Sdim  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
846249423Sdim
847249423Sdim  const CGFunctionInfo *FInfo
848249423Sdim    = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType);
849249423Sdim  llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
850249423Sdim  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, DtorType, This, Ty);
851249423Sdim
852249423Sdim  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
853249423Sdim                               /*ImplicitParam=*/0, QualType(), 0, 0);
854249423Sdim}
855249423Sdim
856212904Sdimvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
857212904Sdim                                    RValue RV, QualType ResultType) {
858212904Sdim  if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
859212904Sdim    return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
860212904Sdim
861212904Sdim  // Destructor thunks in the ARM ABI have indeterminate results.
862226633Sdim  llvm::Type *T =
863212904Sdim    cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
864212904Sdim  RValue Undef = RValue::get(llvm::UndefValue::get(T));
865212904Sdim  return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
866212904Sdim}
867212904Sdim
868212904Sdim/************************** Array allocation cookies **************************/
869212904Sdim
870239462SdimCharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
871239462Sdim  // The array cookie is a size_t; pad that up to the element alignment.
872239462Sdim  // The cookie is actually right-justified in that space.
873239462Sdim  return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
874239462Sdim                  CGM.getContext().getTypeAlignInChars(elementType));
875218893Sdim}
876212904Sdim
877212904Sdimllvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
878212904Sdim                                                  llvm::Value *NewPtr,
879212904Sdim                                                  llvm::Value *NumElements,
880218893Sdim                                                  const CXXNewExpr *expr,
881212904Sdim                                                  QualType ElementType) {
882239462Sdim  assert(requiresArrayCookie(expr));
883212904Sdim
884243830Sdim  unsigned AS = NewPtr->getType()->getPointerAddressSpace();
885212904Sdim
886212904Sdim  ASTContext &Ctx = getContext();
887212904Sdim  QualType SizeTy = Ctx.getSizeType();
888212904Sdim  CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
889212904Sdim
890212904Sdim  // The size of the cookie.
891212904Sdim  CharUnits CookieSize =
892212904Sdim    std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
893239462Sdim  assert(CookieSize == getArrayCookieSizeImpl(ElementType));
894212904Sdim
895212904Sdim  // Compute an offset to the cookie.
896212904Sdim  llvm::Value *CookiePtr = NewPtr;
897212904Sdim  CharUnits CookieOffset = CookieSize - SizeSize;
898212904Sdim  if (!CookieOffset.isZero())
899212904Sdim    CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
900212904Sdim                                                 CookieOffset.getQuantity());
901212904Sdim
902212904Sdim  // Write the number of elements into the appropriate slot.
903212904Sdim  llvm::Value *NumElementsPtr
904212904Sdim    = CGF.Builder.CreateBitCast(CookiePtr,
905212904Sdim                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
906212904Sdim  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
907212904Sdim
908212904Sdim  // Finally, compute a pointer to the actual data buffer by skipping
909212904Sdim  // over the cookie completely.
910212904Sdim  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
911212904Sdim                                                CookieSize.getQuantity());
912212904Sdim}
913212904Sdim
914239462Sdimllvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
915239462Sdim                                                llvm::Value *allocPtr,
916239462Sdim                                                CharUnits cookieSize) {
917239462Sdim  // The element size is right-justified in the cookie.
918239462Sdim  llvm::Value *numElementsPtr = allocPtr;
919239462Sdim  CharUnits numElementsOffset =
920239462Sdim    cookieSize - CharUnits::fromQuantity(CGF.SizeSizeInBytes);
921239462Sdim  if (!numElementsOffset.isZero())
922239462Sdim    numElementsPtr =
923239462Sdim      CGF.Builder.CreateConstInBoundsGEP1_64(numElementsPtr,
924239462Sdim                                             numElementsOffset.getQuantity());
925212904Sdim
926243830Sdim  unsigned AS = allocPtr->getType()->getPointerAddressSpace();
927239462Sdim  numElementsPtr =
928239462Sdim    CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
929239462Sdim  return CGF.Builder.CreateLoad(numElementsPtr);
930212904Sdim}
931212904Sdim
932239462SdimCharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
933249423Sdim  // ARM says that the cookie is always:
934212904Sdim  //   struct array_cookie {
935212904Sdim  //     std::size_t element_size; // element_size != 0
936212904Sdim  //     std::size_t element_count;
937212904Sdim  //   };
938249423Sdim  // But the base ABI doesn't give anything an alignment greater than
939249423Sdim  // 8, so we can dismiss this as typical ABI-author blindness to
940249423Sdim  // actual language complexity and round up to the element alignment.
941249423Sdim  return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),
942249423Sdim                  CGM.getContext().getTypeAlignInChars(elementType));
943212904Sdim}
944212904Sdim
945212904Sdimllvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
946249423Sdim                                              llvm::Value *newPtr,
947249423Sdim                                              llvm::Value *numElements,
948218893Sdim                                              const CXXNewExpr *expr,
949249423Sdim                                              QualType elementType) {
950239462Sdim  assert(requiresArrayCookie(expr));
951212904Sdim
952249423Sdim  // NewPtr is a char*, but we generalize to arbitrary addrspaces.
953249423Sdim  unsigned AS = newPtr->getType()->getPointerAddressSpace();
954212904Sdim
955212904Sdim  // The cookie is always at the start of the buffer.
956249423Sdim  llvm::Value *cookie = newPtr;
957212904Sdim
958212904Sdim  // The first element is the element size.
959249423Sdim  cookie = CGF.Builder.CreateBitCast(cookie, CGF.SizeTy->getPointerTo(AS));
960249423Sdim  llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,
961249423Sdim                 getContext().getTypeSizeInChars(elementType).getQuantity());
962249423Sdim  CGF.Builder.CreateStore(elementSize, cookie);
963212904Sdim
964212904Sdim  // The second element is the element count.
965249423Sdim  cookie = CGF.Builder.CreateConstInBoundsGEP1_32(cookie, 1);
966249423Sdim  CGF.Builder.CreateStore(numElements, cookie);
967212904Sdim
968212904Sdim  // Finally, compute a pointer to the actual data buffer by skipping
969212904Sdim  // over the cookie completely.
970249423Sdim  CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
971249423Sdim  return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
972249423Sdim                                                cookieSize.getQuantity());
973212904Sdim}
974212904Sdim
975239462Sdimllvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
976239462Sdim                                            llvm::Value *allocPtr,
977239462Sdim                                            CharUnits cookieSize) {
978239462Sdim  // The number of elements is at offset sizeof(size_t) relative to
979239462Sdim  // the allocated pointer.
980239462Sdim  llvm::Value *numElementsPtr
981239462Sdim    = CGF.Builder.CreateConstInBoundsGEP1_64(allocPtr, CGF.SizeSizeInBytes);
982212904Sdim
983243830Sdim  unsigned AS = allocPtr->getType()->getPointerAddressSpace();
984239462Sdim  numElementsPtr =
985239462Sdim    CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
986239462Sdim  return CGF.Builder.CreateLoad(numElementsPtr);
987212904Sdim}
988212904Sdim
989218893Sdim/*********************** Static local initialization **************************/
990218893Sdim
991218893Sdimstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
992224145Sdim                                         llvm::PointerType *GuardPtrTy) {
993218893Sdim  // int __cxa_guard_acquire(__guard *guard_object);
994226633Sdim  llvm::FunctionType *FTy =
995218893Sdim    llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
996226633Sdim                            GuardPtrTy, /*isVarArg=*/false);
997234353Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire",
998249423Sdim                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
999249423Sdim                                              llvm::AttributeSet::FunctionIndex,
1000249423Sdim                                                 llvm::Attribute::NoUnwind));
1001218893Sdim}
1002218893Sdim
1003218893Sdimstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
1004224145Sdim                                         llvm::PointerType *GuardPtrTy) {
1005218893Sdim  // void __cxa_guard_release(__guard *guard_object);
1006226633Sdim  llvm::FunctionType *FTy =
1007234353Sdim    llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
1008234353Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release",
1009249423Sdim                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
1010249423Sdim                                              llvm::AttributeSet::FunctionIndex,
1011249423Sdim                                                 llvm::Attribute::NoUnwind));
1012218893Sdim}
1013218893Sdim
1014218893Sdimstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
1015224145Sdim                                       llvm::PointerType *GuardPtrTy) {
1016218893Sdim  // void __cxa_guard_abort(__guard *guard_object);
1017226633Sdim  llvm::FunctionType *FTy =
1018234353Sdim    llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
1019234353Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort",
1020249423Sdim                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
1021249423Sdim                                              llvm::AttributeSet::FunctionIndex,
1022249423Sdim                                                 llvm::Attribute::NoUnwind));
1023218893Sdim}
1024218893Sdim
1025218893Sdimnamespace {
1026218893Sdim  struct CallGuardAbort : EHScopeStack::Cleanup {
1027218893Sdim    llvm::GlobalVariable *Guard;
1028218893Sdim    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1029218893Sdim
1030224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
1031249423Sdim      CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
1032249423Sdim                                  Guard);
1033218893Sdim    }
1034218893Sdim  };
1035218893Sdim}
1036218893Sdim
1037218893Sdim/// The ARM code here follows the Itanium code closely enough that we
1038218893Sdim/// just special-case it at particular places.
1039218893Sdimvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
1040218893Sdim                                    const VarDecl &D,
1041234353Sdim                                    llvm::GlobalVariable *var,
1042234353Sdim                                    bool shouldPerformInit) {
1043218893Sdim  CGBuilderTy &Builder = CGF.Builder;
1044218893Sdim
1045218893Sdim  // We only need to use thread-safe statics for local variables;
1046218893Sdim  // global initialization is always single-threaded.
1047224145Sdim  bool threadsafe =
1048234353Sdim    (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
1049221345Sdim
1050221345Sdim  // If we have a global variable with internal linkage and thread-safe statics
1051221345Sdim  // are disabled, we can just let the guard variable be of type i8.
1052234353Sdim  bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1053234353Sdim
1054234353Sdim  llvm::IntegerType *guardTy;
1055224145Sdim  if (useInt8GuardVariable) {
1056234353Sdim    guardTy = CGF.Int8Ty;
1057224145Sdim  } else {
1058249423Sdim    // Guard variables are 64 bits in the generic ABI and size width on ARM
1059249423Sdim    // (i.e. 32-bit on AArch32, 64-bit on AArch64).
1060249423Sdim    guardTy = (IsARM ? CGF.SizeTy : CGF.Int64Ty);
1061221345Sdim  }
1062234353Sdim  llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1063218893Sdim
1064234353Sdim  // Create the guard variable if we don't already have it (as we
1065234353Sdim  // might if we're double-emitting this function body).
1066234353Sdim  llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1067234353Sdim  if (!guard) {
1068234353Sdim    // Mangle the name for the guard.
1069234353Sdim    SmallString<256> guardName;
1070234353Sdim    {
1071234353Sdim      llvm::raw_svector_ostream out(guardName);
1072234353Sdim      getMangleContext().mangleItaniumGuardVariable(&D, out);
1073234353Sdim      out.flush();
1074234353Sdim    }
1075218893Sdim
1076234353Sdim    // Create the guard variable with a zero-initializer.
1077234353Sdim    // Just absorb linkage and visibility from the guarded variable.
1078234353Sdim    guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
1079234353Sdim                                     false, var->getLinkage(),
1080234353Sdim                                     llvm::ConstantInt::get(guardTy, 0),
1081234353Sdim                                     guardName.str());
1082234353Sdim    guard->setVisibility(var->getVisibility());
1083218893Sdim
1084234353Sdim    CGM.setStaticLocalDeclGuardAddress(&D, guard);
1085234353Sdim  }
1086234353Sdim
1087218893Sdim  // Test whether the variable has completed initialization.
1088234353Sdim  llvm::Value *isInitialized;
1089218893Sdim
1090218893Sdim  // ARM C++ ABI 3.2.3.1:
1091218893Sdim  //   To support the potential use of initialization guard variables
1092218893Sdim  //   as semaphores that are the target of ARM SWP and LDREX/STREX
1093218893Sdim  //   synchronizing instructions we define a static initialization
1094218893Sdim  //   guard variable to be a 4-byte aligned, 4- byte word with the
1095218893Sdim  //   following inline access protocol.
1096218893Sdim  //     #define INITIALIZED 1
1097218893Sdim  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
1098218893Sdim  //       if (__cxa_guard_acquire(&obj_guard))
1099218893Sdim  //         ...
1100218893Sdim  //     }
1101224145Sdim  if (IsARM && !useInt8GuardVariable) {
1102234353Sdim    llvm::Value *V = Builder.CreateLoad(guard);
1103249423Sdim    llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1);
1104249423Sdim    V = Builder.CreateAnd(V, Test1);
1105234353Sdim    isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
1106218893Sdim
1107218893Sdim  // Itanium C++ ABI 3.3.2:
1108218893Sdim  //   The following is pseudo-code showing how these functions can be used:
1109218893Sdim  //     if (obj_guard.first_byte == 0) {
1110218893Sdim  //       if ( __cxa_guard_acquire (&obj_guard) ) {
1111218893Sdim  //         try {
1112218893Sdim  //           ... initialize the object ...;
1113218893Sdim  //         } catch (...) {
1114218893Sdim  //            __cxa_guard_abort (&obj_guard);
1115218893Sdim  //            throw;
1116218893Sdim  //         }
1117218893Sdim  //         ... queue object destructor with __cxa_atexit() ...;
1118218893Sdim  //         __cxa_guard_release (&obj_guard);
1119218893Sdim  //       }
1120218893Sdim  //     }
1121218893Sdim  } else {
1122218893Sdim    // Load the first byte of the guard variable.
1123226633Sdim    llvm::LoadInst *LI =
1124234353Sdim      Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
1125226633Sdim    LI->setAlignment(1);
1126218893Sdim
1127226633Sdim    // Itanium ABI:
1128226633Sdim    //   An implementation supporting thread-safety on multiprocessor
1129226633Sdim    //   systems must also guarantee that references to the initialized
1130226633Sdim    //   object do not occur before the load of the initialization flag.
1131226633Sdim    //
1132226633Sdim    // In LLVM, we do this by marking the load Acquire.
1133226633Sdim    if (threadsafe)
1134226633Sdim      LI->setAtomic(llvm::Acquire);
1135226633Sdim
1136234353Sdim    isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
1137218893Sdim  }
1138218893Sdim
1139218893Sdim  llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
1140218893Sdim  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
1141218893Sdim
1142218893Sdim  // Check if the first byte of the guard variable is zero.
1143234353Sdim  Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
1144218893Sdim
1145218893Sdim  CGF.EmitBlock(InitCheckBlock);
1146218893Sdim
1147218893Sdim  // Variables used when coping with thread-safe statics and exceptions.
1148224145Sdim  if (threadsafe) {
1149218893Sdim    // Call __cxa_guard_acquire.
1150218893Sdim    llvm::Value *V
1151249423Sdim      = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
1152218893Sdim
1153218893Sdim    llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
1154218893Sdim
1155218893Sdim    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
1156218893Sdim                         InitBlock, EndBlock);
1157218893Sdim
1158218893Sdim    // Call __cxa_guard_abort along the exceptional edge.
1159234353Sdim    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
1160218893Sdim
1161218893Sdim    CGF.EmitBlock(InitBlock);
1162218893Sdim  }
1163218893Sdim
1164218893Sdim  // Emit the initializer and add a global destructor if appropriate.
1165234353Sdim  CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
1166218893Sdim
1167224145Sdim  if (threadsafe) {
1168218893Sdim    // Pop the guard-abort cleanup if we pushed one.
1169218893Sdim    CGF.PopCleanupBlock();
1170218893Sdim
1171218893Sdim    // Call __cxa_guard_release.  This cannot throw.
1172249423Sdim    CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
1173218893Sdim  } else {
1174234353Sdim    Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
1175218893Sdim  }
1176218893Sdim
1177218893Sdim  CGF.EmitBlock(EndBlock);
1178218893Sdim}
1179239462Sdim
1180239462Sdim/// Register a global destructor using __cxa_atexit.
1181239462Sdimstatic void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
1182239462Sdim                                        llvm::Constant *dtor,
1183239462Sdim                                        llvm::Constant *addr) {
1184239462Sdim  // We're assuming that the destructor function is something we can
1185239462Sdim  // reasonably call with the default CC.  Go ahead and cast it to the
1186239462Sdim  // right prototype.
1187239462Sdim  llvm::Type *dtorTy =
1188239462Sdim    llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
1189239462Sdim
1190239462Sdim  // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
1191239462Sdim  llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
1192239462Sdim  llvm::FunctionType *atexitTy =
1193239462Sdim    llvm::FunctionType::get(CGF.IntTy, paramTys, false);
1194239462Sdim
1195239462Sdim  // Fetch the actual function.
1196239462Sdim  llvm::Constant *atexit =
1197239462Sdim    CGF.CGM.CreateRuntimeFunction(atexitTy, "__cxa_atexit");
1198239462Sdim  if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
1199239462Sdim    fn->setDoesNotThrow();
1200239462Sdim
1201239462Sdim  // Create a variable that binds the atexit to this shared object.
1202239462Sdim  llvm::Constant *handle =
1203239462Sdim    CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
1204239462Sdim
1205239462Sdim  llvm::Value *args[] = {
1206239462Sdim    llvm::ConstantExpr::getBitCast(dtor, dtorTy),
1207239462Sdim    llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
1208239462Sdim    handle
1209239462Sdim  };
1210249423Sdim  CGF.EmitNounwindRuntimeCall(atexit, args);
1211239462Sdim}
1212239462Sdim
1213239462Sdim/// Register a global destructor as best as we know how.
1214239462Sdimvoid ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
1215239462Sdim                                       llvm::Constant *dtor,
1216239462Sdim                                       llvm::Constant *addr) {
1217239462Sdim  // Use __cxa_atexit if available.
1218239462Sdim  if (CGM.getCodeGenOpts().CXAAtExit) {
1219239462Sdim    return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr);
1220239462Sdim  }
1221239462Sdim
1222239462Sdim  // In Apple kexts, we want to add a global destructor entry.
1223239462Sdim  // FIXME: shouldn't this be guarded by some variable?
1224243830Sdim  if (CGM.getLangOpts().AppleKext) {
1225239462Sdim    // Generate a global destructor entry.
1226239462Sdim    return CGM.AddCXXDtorEntry(dtor, addr);
1227239462Sdim  }
1228239462Sdim
1229239462Sdim  CGF.registerGlobalDtorWithAtExit(dtor, addr);
1230239462Sdim}
1231