ItaniumCXXABI.cpp revision 226633
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"
23212904Sdim#include "CodeGenFunction.h"
24208600Srdivacky#include "CodeGenModule.h"
25218893Sdim#include <clang/AST/Mangle.h>
26212904Sdim#include <clang/AST/Type.h>
27224145Sdim#include <llvm/Intrinsics.h>
28212904Sdim#include <llvm/Target/TargetData.h>
29212904Sdim#include <llvm/Value.h>
30208600Srdivacky
31208600Srdivackyusing namespace clang;
32212904Sdimusing namespace CodeGen;
33208600Srdivacky
34208600Srdivackynamespace {
35212904Sdimclass ItaniumCXXABI : public CodeGen::CGCXXABI {
36212904Sdimprivate:
37224145Sdim  llvm::IntegerType *PtrDiffTy;
38212904Sdimprotected:
39212904Sdim  bool IsARM;
40212904Sdim
41212904Sdim  // It's a little silly for us to cache this.
42224145Sdim  llvm::IntegerType *getPtrDiffTy() {
43212904Sdim    if (!PtrDiffTy) {
44212904Sdim      QualType T = getContext().getPointerDiffType();
45224145Sdim      llvm::Type *Ty = CGM.getTypes().ConvertType(T);
46212904Sdim      PtrDiffTy = cast<llvm::IntegerType>(Ty);
47212904Sdim    }
48212904Sdim    return PtrDiffTy;
49212904Sdim  }
50212904Sdim
51218893Sdim  bool NeedsArrayCookie(const CXXNewExpr *expr);
52218893Sdim  bool NeedsArrayCookie(const CXXDeleteExpr *expr,
53218893Sdim                        QualType elementType);
54212904Sdim
55208600Srdivackypublic:
56212904Sdim  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
57218893Sdim    CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { }
58208600Srdivacky
59212904Sdim  bool isZeroInitializable(const MemberPointerType *MPT);
60212904Sdim
61224145Sdim  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
62212904Sdim
63212904Sdim  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
64212904Sdim                                               llvm::Value *&This,
65212904Sdim                                               llvm::Value *MemFnPtr,
66212904Sdim                                               const MemberPointerType *MPT);
67212904Sdim
68212904Sdim  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
69212904Sdim                                            llvm::Value *Base,
70212904Sdim                                            llvm::Value *MemPtr,
71212904Sdim                                            const MemberPointerType *MPT);
72212904Sdim
73212904Sdim  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
74212904Sdim                                           const CastExpr *E,
75212904Sdim                                           llvm::Value *Src);
76212904Sdim
77212904Sdim  llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
78212904Sdim                                              const CastExpr *E);
79212904Sdim
80212904Sdim  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
81212904Sdim
82212904Sdim  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
83218893Sdim  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
84218893Sdim                                        CharUnits offset);
85212904Sdim
86212904Sdim  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
87212904Sdim                                           llvm::Value *L,
88212904Sdim                                           llvm::Value *R,
89212904Sdim                                           const MemberPointerType *MPT,
90212904Sdim                                           bool Inequality);
91212904Sdim
92212904Sdim  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
93212904Sdim                                          llvm::Value *Addr,
94212904Sdim                                          const MemberPointerType *MPT);
95212904Sdim
96212904Sdim  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
97212904Sdim                                 CXXCtorType T,
98212904Sdim                                 CanQualType &ResTy,
99226633Sdim                                 SmallVectorImpl<CanQualType> &ArgTys);
100212904Sdim
101212904Sdim  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
102212904Sdim                                CXXDtorType T,
103212904Sdim                                CanQualType &ResTy,
104226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys);
105212904Sdim
106212904Sdim  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
107212904Sdim                                   QualType &ResTy,
108212904Sdim                                   FunctionArgList &Params);
109212904Sdim
110212904Sdim  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
111212904Sdim
112218893Sdim  CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
113212904Sdim  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
114212904Sdim                                     llvm::Value *NewPtr,
115212904Sdim                                     llvm::Value *NumElements,
116218893Sdim                                     const CXXNewExpr *expr,
117212904Sdim                                     QualType ElementType);
118212904Sdim  void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
119218893Sdim                       const CXXDeleteExpr *expr,
120212904Sdim                       QualType ElementType, llvm::Value *&NumElements,
121212904Sdim                       llvm::Value *&AllocPtr, CharUnits &CookieSize);
122218893Sdim
123218893Sdim  void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
124218893Sdim                       llvm::GlobalVariable *DeclPtr);
125208600Srdivacky};
126212904Sdim
127212904Sdimclass ARMCXXABI : public ItaniumCXXABI {
128212904Sdimpublic:
129212904Sdim  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
130212904Sdim
131212904Sdim  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
132212904Sdim                                 CXXCtorType T,
133212904Sdim                                 CanQualType &ResTy,
134226633Sdim                                 SmallVectorImpl<CanQualType> &ArgTys);
135212904Sdim
136212904Sdim  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
137212904Sdim                                CXXDtorType T,
138212904Sdim                                CanQualType &ResTy,
139226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys);
140212904Sdim
141212904Sdim  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
142212904Sdim                                   QualType &ResTy,
143212904Sdim                                   FunctionArgList &Params);
144212904Sdim
145212904Sdim  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
146212904Sdim
147212904Sdim  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
148212904Sdim
149218893Sdim  CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
150212904Sdim  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
151212904Sdim                                     llvm::Value *NewPtr,
152212904Sdim                                     llvm::Value *NumElements,
153218893Sdim                                     const CXXNewExpr *expr,
154212904Sdim                                     QualType ElementType);
155212904Sdim  void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
156218893Sdim                       const CXXDeleteExpr *expr,
157212904Sdim                       QualType ElementType, llvm::Value *&NumElements,
158212904Sdim                       llvm::Value *&AllocPtr, CharUnits &CookieSize);
159212904Sdim
160212904Sdimprivate:
161212904Sdim  /// \brief Returns true if the given instance method is one of the
162212904Sdim  /// kinds that the ARM ABI says returns 'this'.
163212904Sdim  static bool HasThisReturn(GlobalDecl GD) {
164212904Sdim    const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
165212904Sdim    return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) ||
166212904Sdim            (isa<CXXConstructorDecl>(MD)));
167212904Sdim  }
168212904Sdim};
169208600Srdivacky}
170208600Srdivacky
171212904SdimCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
172208600Srdivacky  return new ItaniumCXXABI(CGM);
173208600Srdivacky}
174208600Srdivacky
175212904SdimCodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) {
176212904Sdim  return new ARMCXXABI(CGM);
177212904Sdim}
178212904Sdim
179224145Sdimllvm::Type *
180212904SdimItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
181212904Sdim  if (MPT->isMemberDataPointer())
182212904Sdim    return getPtrDiffTy();
183224145Sdim  return llvm::StructType::get(getPtrDiffTy(), getPtrDiffTy(), NULL);
184212904Sdim}
185212904Sdim
186212904Sdim/// In the Itanium and ARM ABIs, method pointers have the form:
187212904Sdim///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
188212904Sdim///
189212904Sdim/// In the Itanium ABI:
190212904Sdim///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
191212904Sdim///  - the this-adjustment is (memptr.adj)
192212904Sdim///  - the virtual offset is (memptr.ptr - 1)
193212904Sdim///
194212904Sdim/// In the ARM ABI:
195212904Sdim///  - method pointers are virtual if (memptr.adj & 1) is nonzero
196212904Sdim///  - the this-adjustment is (memptr.adj >> 1)
197212904Sdim///  - the virtual offset is (memptr.ptr)
198212904Sdim/// ARM uses 'adj' for the virtual flag because Thumb functions
199212904Sdim/// may be only single-byte aligned.
200212904Sdim///
201212904Sdim/// If the member is virtual, the adjusted 'this' pointer points
202212904Sdim/// to a vtable pointer from which the virtual offset is applied.
203212904Sdim///
204212904Sdim/// If the member is non-virtual, memptr.ptr is the address of
205212904Sdim/// the function to call.
206212904Sdimllvm::Value *
207212904SdimItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
208212904Sdim                                               llvm::Value *&This,
209212904Sdim                                               llvm::Value *MemFnPtr,
210212904Sdim                                               const MemberPointerType *MPT) {
211212904Sdim  CGBuilderTy &Builder = CGF.Builder;
212212904Sdim
213212904Sdim  const FunctionProtoType *FPT =
214212904Sdim    MPT->getPointeeType()->getAs<FunctionProtoType>();
215212904Sdim  const CXXRecordDecl *RD =
216212904Sdim    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
217212904Sdim
218226633Sdim  llvm::FunctionType *FTy =
219212904Sdim    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
220212904Sdim                                   FPT->isVariadic());
221212904Sdim
222226633Sdim  llvm::IntegerType *ptrdiff = getPtrDiffTy();
223212904Sdim  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
224212904Sdim
225212904Sdim  llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
226212904Sdim  llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
227212904Sdim  llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
228212904Sdim
229212904Sdim  // Extract memptr.adj, which is in the second field.
230212904Sdim  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
231212904Sdim
232212904Sdim  // Compute the true adjustment.
233212904Sdim  llvm::Value *Adj = RawAdj;
234212904Sdim  if (IsARM)
235212904Sdim    Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
236212904Sdim
237212904Sdim  // Apply the adjustment and cast back to the original struct type
238212904Sdim  // for consistency.
239212904Sdim  llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
240212904Sdim  Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
241212904Sdim  This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
242212904Sdim
243212904Sdim  // Load the function pointer.
244212904Sdim  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
245212904Sdim
246212904Sdim  // If the LSB in the function pointer is 1, the function pointer points to
247212904Sdim  // a virtual function.
248212904Sdim  llvm::Value *IsVirtual;
249212904Sdim  if (IsARM)
250212904Sdim    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
251212904Sdim  else
252212904Sdim    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
253212904Sdim  IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
254212904Sdim  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
255212904Sdim
256212904Sdim  // In the virtual path, the adjustment left 'This' pointing to the
257212904Sdim  // vtable of the correct base subobject.  The "function pointer" is an
258212904Sdim  // offset within the vtable (+1 for the virtual flag on non-ARM).
259212904Sdim  CGF.EmitBlock(FnVirtual);
260212904Sdim
261212904Sdim  // Cast the adjusted this to a pointer to vtable pointer and load.
262226633Sdim  llvm::Type *VTableTy = Builder.getInt8PtrTy();
263212904Sdim  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
264212904Sdim  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
265212904Sdim
266212904Sdim  // Apply the offset.
267212904Sdim  llvm::Value *VTableOffset = FnAsInt;
268212904Sdim  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
269212904Sdim  VTable = Builder.CreateGEP(VTable, VTableOffset);
270212904Sdim
271212904Sdim  // Load the virtual function to call.
272212904Sdim  VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
273212904Sdim  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
274212904Sdim  CGF.EmitBranch(FnEnd);
275212904Sdim
276212904Sdim  // In the non-virtual path, the function pointer is actually a
277212904Sdim  // function pointer.
278212904Sdim  CGF.EmitBlock(FnNonVirtual);
279212904Sdim  llvm::Value *NonVirtualFn =
280212904Sdim    Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
281212904Sdim
282212904Sdim  // We're done.
283212904Sdim  CGF.EmitBlock(FnEnd);
284221345Sdim  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
285212904Sdim  Callee->addIncoming(VirtualFn, FnVirtual);
286212904Sdim  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
287212904Sdim  return Callee;
288212904Sdim}
289212904Sdim
290212904Sdim/// Compute an l-value by applying the given pointer-to-member to a
291212904Sdim/// base object.
292212904Sdimllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
293212904Sdim                                                         llvm::Value *Base,
294212904Sdim                                                         llvm::Value *MemPtr,
295212904Sdim                                           const MemberPointerType *MPT) {
296212904Sdim  assert(MemPtr->getType() == getPtrDiffTy());
297212904Sdim
298212904Sdim  CGBuilderTy &Builder = CGF.Builder;
299212904Sdim
300212904Sdim  unsigned AS = cast<llvm::PointerType>(Base->getType())->getAddressSpace();
301212904Sdim
302212904Sdim  // Cast to char*.
303212904Sdim  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
304212904Sdim
305212904Sdim  // Apply the offset, which we assume is non-null.
306212904Sdim  llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
307212904Sdim
308212904Sdim  // Cast the address to the appropriate pointer type, adopting the
309212904Sdim  // address space of the base pointer.
310226633Sdim  llvm::Type *PType
311212904Sdim    = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
312212904Sdim  return Builder.CreateBitCast(Addr, PType);
313212904Sdim}
314212904Sdim
315212904Sdim/// Perform a derived-to-base or base-to-derived member pointer conversion.
316212904Sdim///
317212904Sdim/// Obligatory offset/adjustment diagram:
318212904Sdim///         <-- offset -->          <-- adjustment -->
319212904Sdim///   |--------------------------|----------------------|--------------------|
320212904Sdim///   ^Derived address point     ^Base address point    ^Member address point
321212904Sdim///
322212904Sdim/// So when converting a base member pointer to a derived member pointer,
323212904Sdim/// we add the offset to the adjustment because the address point has
324212904Sdim/// decreased;  and conversely, when converting a derived MP to a base MP
325212904Sdim/// we subtract the offset from the adjustment because the address point
326212904Sdim/// has increased.
327212904Sdim///
328212904Sdim/// The standard forbids (at compile time) conversion to and from
329212904Sdim/// virtual bases, which is why we don't have to consider them here.
330212904Sdim///
331212904Sdim/// The standard forbids (at run time) casting a derived MP to a base
332212904Sdim/// MP when the derived MP does not point to a member of the base.
333212904Sdim/// This is why -1 is a reasonable choice for null data member
334212904Sdim/// pointers.
335212904Sdimllvm::Value *
336212904SdimItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
337212904Sdim                                           const CastExpr *E,
338212904Sdim                                           llvm::Value *Src) {
339212904Sdim  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
340212904Sdim         E->getCastKind() == CK_BaseToDerivedMemberPointer);
341212904Sdim
342212904Sdim  if (isa<llvm::Constant>(Src))
343212904Sdim    return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E);
344212904Sdim
345212904Sdim  CGBuilderTy &Builder = CGF.Builder;
346212904Sdim
347212904Sdim  const MemberPointerType *SrcTy =
348212904Sdim    E->getSubExpr()->getType()->getAs<MemberPointerType>();
349212904Sdim  const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
350212904Sdim
351212904Sdim  const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
352212904Sdim  const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
353212904Sdim
354212904Sdim  bool DerivedToBase =
355212904Sdim    E->getCastKind() == CK_DerivedToBaseMemberPointer;
356212904Sdim
357218893Sdim  const CXXRecordDecl *DerivedDecl;
358212904Sdim  if (DerivedToBase)
359218893Sdim    DerivedDecl = SrcDecl;
360212904Sdim  else
361218893Sdim    DerivedDecl = DestDecl;
362212904Sdim
363212904Sdim  llvm::Constant *Adj =
364212904Sdim    CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
365212904Sdim                                         E->path_begin(),
366212904Sdim                                         E->path_end());
367212904Sdim  if (!Adj) return Src;
368212904Sdim
369212904Sdim  // For member data pointers, this is just a matter of adding the
370212904Sdim  // offset if the source is non-null.
371212904Sdim  if (SrcTy->isMemberDataPointer()) {
372212904Sdim    llvm::Value *Dst;
373212904Sdim    if (DerivedToBase)
374212904Sdim      Dst = Builder.CreateNSWSub(Src, Adj, "adj");
375212904Sdim    else
376212904Sdim      Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
377212904Sdim
378212904Sdim    // Null check.
379212904Sdim    llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
380212904Sdim    llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
381212904Sdim    return Builder.CreateSelect(IsNull, Src, Dst);
382212904Sdim  }
383212904Sdim
384212904Sdim  // The this-adjustment is left-shifted by 1 on ARM.
385212904Sdim  if (IsARM) {
386212904Sdim    uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
387212904Sdim    Offset <<= 1;
388212904Sdim    Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
389212904Sdim  }
390212904Sdim
391212904Sdim  llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
392212904Sdim  llvm::Value *DstAdj;
393212904Sdim  if (DerivedToBase)
394212904Sdim    DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
395212904Sdim  else
396212904Sdim    DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
397212904Sdim
398212904Sdim  return Builder.CreateInsertValue(Src, DstAdj, 1);
399212904Sdim}
400212904Sdim
401212904Sdimllvm::Constant *
402212904SdimItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
403212904Sdim                                           const CastExpr *E) {
404212904Sdim  const MemberPointerType *SrcTy =
405212904Sdim    E->getSubExpr()->getType()->getAs<MemberPointerType>();
406212904Sdim  const MemberPointerType *DestTy =
407212904Sdim    E->getType()->getAs<MemberPointerType>();
408212904Sdim
409212904Sdim  bool DerivedToBase =
410212904Sdim    E->getCastKind() == CK_DerivedToBaseMemberPointer;
411212904Sdim
412212904Sdim  const CXXRecordDecl *DerivedDecl;
413212904Sdim  if (DerivedToBase)
414212904Sdim    DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
415212904Sdim  else
416212904Sdim    DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
417212904Sdim
418212904Sdim  // Calculate the offset to the base class.
419212904Sdim  llvm::Constant *Offset =
420212904Sdim    CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
421212904Sdim                                     E->path_begin(),
422212904Sdim                                     E->path_end());
423212904Sdim  // If there's no offset, we're done.
424212904Sdim  if (!Offset) return C;
425212904Sdim
426212904Sdim  // If the source is a member data pointer, we have to do a null
427212904Sdim  // check and then add the offset.  In the common case, we can fold
428212904Sdim  // away the offset.
429212904Sdim  if (SrcTy->isMemberDataPointer()) {
430212904Sdim    assert(C->getType() == getPtrDiffTy());
431212904Sdim
432212904Sdim    // If it's a constant int, just create a new constant int.
433212904Sdim    if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
434212904Sdim      int64_t Src = CI->getSExtValue();
435212904Sdim
436212904Sdim      // Null converts to null.
437212904Sdim      if (Src == -1) return CI;
438212904Sdim
439212904Sdim      // Otherwise, just add the offset.
440212904Sdim      int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
441212904Sdim      int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV);
442212904Sdim      return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true);
443212904Sdim    }
444212904Sdim
445212904Sdim    // Otherwise, we have to form a constant select expression.
446212904Sdim    llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType());
447212904Sdim
448212904Sdim    llvm::Constant *IsNull =
449212904Sdim      llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null);
450212904Sdim
451212904Sdim    llvm::Constant *Dst;
452212904Sdim    if (DerivedToBase)
453212904Sdim      Dst = llvm::ConstantExpr::getNSWSub(C, Offset);
454212904Sdim    else
455212904Sdim      Dst = llvm::ConstantExpr::getNSWAdd(C, Offset);
456212904Sdim
457212904Sdim    return llvm::ConstantExpr::getSelect(IsNull, Null, Dst);
458212904Sdim  }
459212904Sdim
460212904Sdim  // The this-adjustment is left-shifted by 1 on ARM.
461212904Sdim  if (IsARM) {
462212904Sdim    int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
463212904Sdim    OffsetV <<= 1;
464212904Sdim    Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV);
465212904Sdim  }
466212904Sdim
467212904Sdim  llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
468212904Sdim
469212904Sdim  llvm::Constant *Values[2] = { CS->getOperand(0), 0 };
470212904Sdim  if (DerivedToBase)
471212904Sdim    Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset);
472212904Sdim  else
473212904Sdim    Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
474212904Sdim
475224145Sdim  return llvm::ConstantStruct::get(CS->getType(), Values);
476212904Sdim}
477212904Sdim
478212904Sdim
479212904Sdimllvm::Constant *
480212904SdimItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
481226633Sdim  llvm::Type *ptrdiff_t = getPtrDiffTy();
482212904Sdim
483212904Sdim  // Itanium C++ ABI 2.3:
484212904Sdim  //   A NULL pointer is represented as -1.
485212904Sdim  if (MPT->isMemberDataPointer())
486212904Sdim    return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
487212904Sdim
488212904Sdim  llvm::Constant *Zero = llvm::ConstantInt::get(ptrdiff_t, 0);
489212904Sdim  llvm::Constant *Values[2] = { Zero, Zero };
490224145Sdim  return llvm::ConstantStruct::getAnon(Values);
491212904Sdim}
492212904Sdim
493218893Sdimllvm::Constant *
494218893SdimItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
495218893Sdim                                     CharUnits offset) {
496212904Sdim  // Itanium C++ ABI 2.3:
497212904Sdim  //   A pointer to data member is an offset from the base address of
498212904Sdim  //   the class object containing it, represented as a ptrdiff_t
499218893Sdim  return llvm::ConstantInt::get(getPtrDiffTy(), offset.getQuantity());
500212904Sdim}
501212904Sdim
502212904Sdimllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
503212904Sdim  assert(MD->isInstance() && "Member function must not be static!");
504212904Sdim  MD = MD->getCanonicalDecl();
505212904Sdim
506212904Sdim  CodeGenTypes &Types = CGM.getTypes();
507226633Sdim  llvm::Type *ptrdiff_t = getPtrDiffTy();
508212904Sdim
509212904Sdim  // Get the function pointer (or index if this is a virtual function).
510212904Sdim  llvm::Constant *MemPtr[2];
511212904Sdim  if (MD->isVirtual()) {
512226633Sdim    uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
513212904Sdim
514221345Sdim    const ASTContext &Context = getContext();
515221345Sdim    CharUnits PointerWidth =
516226633Sdim      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
517221345Sdim    uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
518212904Sdim
519212904Sdim    if (IsARM) {
520212904Sdim      // ARM C++ ABI 3.2.1:
521212904Sdim      //   This ABI specifies that adj contains twice the this
522212904Sdim      //   adjustment, plus 1 if the member function is virtual. The
523212904Sdim      //   least significant bit of adj then makes exactly the same
524212904Sdim      //   discrimination as the least significant bit of ptr does for
525212904Sdim      //   Itanium.
526212904Sdim      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset);
527212904Sdim      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
528212904Sdim    } else {
529212904Sdim      // Itanium C++ ABI 2.3:
530212904Sdim      //   For a virtual function, [the pointer field] is 1 plus the
531212904Sdim      //   virtual table offset (in bytes) of the function,
532212904Sdim      //   represented as a ptrdiff_t.
533212904Sdim      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1);
534212904Sdim      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
535212904Sdim    }
536212904Sdim  } else {
537221345Sdim    const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
538226633Sdim    llvm::Type *Ty;
539212904Sdim    // Check whether the function has a computable LLVM signature.
540224145Sdim    if (Types.isFuncTypeConvertible(FPT)) {
541212904Sdim      // The function has a computable LLVM signature; use the correct type.
542221345Sdim      Ty = Types.GetFunctionType(Types.getFunctionInfo(MD),
543221345Sdim                                 FPT->isVariadic());
544212904Sdim    } else {
545212904Sdim      // Use an arbitrary non-function type to tell GetAddrOfFunction that the
546212904Sdim      // function type is incomplete.
547212904Sdim      Ty = ptrdiff_t;
548212904Sdim    }
549221345Sdim    llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
550212904Sdim
551221345Sdim    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, ptrdiff_t);
552212904Sdim    MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
553212904Sdim  }
554212904Sdim
555224145Sdim  return llvm::ConstantStruct::getAnon(MemPtr);
556212904Sdim}
557212904Sdim
558212904Sdim/// The comparison algorithm is pretty easy: the member pointers are
559212904Sdim/// the same if they're either bitwise identical *or* both null.
560212904Sdim///
561212904Sdim/// ARM is different here only because null-ness is more complicated.
562212904Sdimllvm::Value *
563212904SdimItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
564212904Sdim                                           llvm::Value *L,
565212904Sdim                                           llvm::Value *R,
566212904Sdim                                           const MemberPointerType *MPT,
567212904Sdim                                           bool Inequality) {
568212904Sdim  CGBuilderTy &Builder = CGF.Builder;
569212904Sdim
570212904Sdim  llvm::ICmpInst::Predicate Eq;
571212904Sdim  llvm::Instruction::BinaryOps And, Or;
572212904Sdim  if (Inequality) {
573212904Sdim    Eq = llvm::ICmpInst::ICMP_NE;
574212904Sdim    And = llvm::Instruction::Or;
575212904Sdim    Or = llvm::Instruction::And;
576212904Sdim  } else {
577212904Sdim    Eq = llvm::ICmpInst::ICMP_EQ;
578212904Sdim    And = llvm::Instruction::And;
579212904Sdim    Or = llvm::Instruction::Or;
580212904Sdim  }
581212904Sdim
582212904Sdim  // Member data pointers are easy because there's a unique null
583212904Sdim  // value, so it just comes down to bitwise equality.
584212904Sdim  if (MPT->isMemberDataPointer())
585212904Sdim    return Builder.CreateICmp(Eq, L, R);
586212904Sdim
587212904Sdim  // For member function pointers, the tautologies are more complex.
588212904Sdim  // The Itanium tautology is:
589212904Sdim  //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
590212904Sdim  // The ARM tautology is:
591212904Sdim  //   (L == R) <==> (L.ptr == R.ptr &&
592212904Sdim  //                  (L.adj == R.adj ||
593212904Sdim  //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
594212904Sdim  // The inequality tautologies have exactly the same structure, except
595212904Sdim  // applying De Morgan's laws.
596212904Sdim
597212904Sdim  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
598212904Sdim  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
599212904Sdim
600212904Sdim  // This condition tests whether L.ptr == R.ptr.  This must always be
601212904Sdim  // true for equality to hold.
602212904Sdim  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
603212904Sdim
604212904Sdim  // This condition, together with the assumption that L.ptr == R.ptr,
605212904Sdim  // tests whether the pointers are both null.  ARM imposes an extra
606212904Sdim  // condition.
607212904Sdim  llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
608212904Sdim  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
609212904Sdim
610212904Sdim  // This condition tests whether L.adj == R.adj.  If this isn't
611212904Sdim  // true, the pointers are unequal unless they're both null.
612212904Sdim  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
613212904Sdim  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
614212904Sdim  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
615212904Sdim
616212904Sdim  // Null member function pointers on ARM clear the low bit of Adj,
617212904Sdim  // so the zero condition has to check that neither low bit is set.
618212904Sdim  if (IsARM) {
619212904Sdim    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
620212904Sdim
621212904Sdim    // Compute (l.adj | r.adj) & 1 and test it against zero.
622212904Sdim    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
623212904Sdim    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
624212904Sdim    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
625212904Sdim                                                      "cmp.or.adj");
626212904Sdim    EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
627212904Sdim  }
628212904Sdim
629212904Sdim  // Tie together all our conditions.
630212904Sdim  llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
631212904Sdim  Result = Builder.CreateBinOp(And, PtrEq, Result,
632212904Sdim                               Inequality ? "memptr.ne" : "memptr.eq");
633212904Sdim  return Result;
634212904Sdim}
635212904Sdim
636212904Sdimllvm::Value *
637212904SdimItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
638212904Sdim                                          llvm::Value *MemPtr,
639212904Sdim                                          const MemberPointerType *MPT) {
640212904Sdim  CGBuilderTy &Builder = CGF.Builder;
641212904Sdim
642212904Sdim  /// For member data pointers, this is just a check against -1.
643212904Sdim  if (MPT->isMemberDataPointer()) {
644212904Sdim    assert(MemPtr->getType() == getPtrDiffTy());
645212904Sdim    llvm::Value *NegativeOne =
646212904Sdim      llvm::Constant::getAllOnesValue(MemPtr->getType());
647212904Sdim    return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
648212904Sdim  }
649212904Sdim
650221345Sdim  // In Itanium, a member function pointer is not null if 'ptr' is not null.
651212904Sdim  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
652212904Sdim
653212904Sdim  llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
654212904Sdim  llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
655212904Sdim
656221345Sdim  // On ARM, a member function pointer is also non-null if the low bit of 'adj'
657221345Sdim  // (the virtual bit) is set.
658212904Sdim  if (IsARM) {
659212904Sdim    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
660212904Sdim    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
661212904Sdim    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
662221345Sdim    llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
663221345Sdim                                                  "memptr.isvirtual");
664221345Sdim    Result = Builder.CreateOr(Result, IsVirtual);
665212904Sdim  }
666212904Sdim
667212904Sdim  return Result;
668212904Sdim}
669212904Sdim
670212904Sdim/// The Itanium ABI requires non-zero initialization only for data
671212904Sdim/// member pointers, for which '0' is a valid offset.
672212904Sdimbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
673212904Sdim  return MPT->getPointeeType()->isFunctionType();
674212904Sdim}
675212904Sdim
676212904Sdim/// The generic ABI passes 'this', plus a VTT if it's initializing a
677212904Sdim/// base subobject.
678212904Sdimvoid ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
679212904Sdim                                              CXXCtorType Type,
680212904Sdim                                              CanQualType &ResTy,
681226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
682212904Sdim  ASTContext &Context = getContext();
683212904Sdim
684212904Sdim  // 'this' is already there.
685212904Sdim
686212904Sdim  // Check if we need to add a VTT parameter (which has type void **).
687212904Sdim  if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
688212904Sdim    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
689212904Sdim}
690212904Sdim
691212904Sdim/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
692212904Sdimvoid ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
693212904Sdim                                          CXXCtorType Type,
694212904Sdim                                          CanQualType &ResTy,
695226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
696212904Sdim  ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
697212904Sdim  ResTy = ArgTys[0];
698212904Sdim}
699212904Sdim
700212904Sdim/// The generic ABI passes 'this', plus a VTT if it's destroying a
701212904Sdim/// base subobject.
702212904Sdimvoid ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
703212904Sdim                                             CXXDtorType Type,
704212904Sdim                                             CanQualType &ResTy,
705226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
706212904Sdim  ASTContext &Context = getContext();
707212904Sdim
708212904Sdim  // 'this' is already there.
709212904Sdim
710212904Sdim  // Check if we need to add a VTT parameter (which has type void **).
711212904Sdim  if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
712212904Sdim    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
713212904Sdim}
714212904Sdim
715212904Sdim/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
716212904Sdim/// for non-deleting destructors.
717212904Sdimvoid ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
718212904Sdim                                         CXXDtorType Type,
719212904Sdim                                         CanQualType &ResTy,
720226633Sdim                                SmallVectorImpl<CanQualType> &ArgTys) {
721212904Sdim  ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
722212904Sdim
723212904Sdim  if (Type != Dtor_Deleting)
724212904Sdim    ResTy = ArgTys[0];
725212904Sdim}
726212904Sdim
727212904Sdimvoid ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
728212904Sdim                                                QualType &ResTy,
729212904Sdim                                                FunctionArgList &Params) {
730212904Sdim  /// Create the 'this' variable.
731212904Sdim  BuildThisParam(CGF, Params);
732212904Sdim
733212904Sdim  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
734212904Sdim  assert(MD->isInstance());
735212904Sdim
736212904Sdim  // Check if we need a VTT parameter as well.
737212904Sdim  if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
738212904Sdim    ASTContext &Context = getContext();
739212904Sdim
740212904Sdim    // FIXME: avoid the fake decl
741212904Sdim    QualType T = Context.getPointerType(Context.VoidPtrTy);
742212904Sdim    ImplicitParamDecl *VTTDecl
743212904Sdim      = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
744212904Sdim                                  &Context.Idents.get("vtt"), T);
745221345Sdim    Params.push_back(VTTDecl);
746212904Sdim    getVTTDecl(CGF) = VTTDecl;
747212904Sdim  }
748212904Sdim}
749212904Sdim
750212904Sdimvoid ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
751212904Sdim                                            QualType &ResTy,
752212904Sdim                                            FunctionArgList &Params) {
753212904Sdim  ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
754212904Sdim
755212904Sdim  // Return 'this' from certain constructors and destructors.
756212904Sdim  if (HasThisReturn(CGF.CurGD))
757221345Sdim    ResTy = Params[0]->getType();
758212904Sdim}
759212904Sdim
760212904Sdimvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
761212904Sdim  /// Initialize the 'this' slot.
762212904Sdim  EmitThisParam(CGF);
763212904Sdim
764212904Sdim  /// Initialize the 'vtt' slot if needed.
765212904Sdim  if (getVTTDecl(CGF)) {
766212904Sdim    getVTTValue(CGF)
767212904Sdim      = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
768212904Sdim                               "vtt");
769212904Sdim  }
770212904Sdim}
771212904Sdim
772212904Sdimvoid ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
773212904Sdim  ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
774212904Sdim
775212904Sdim  /// Initialize the return slot to 'this' at the start of the
776212904Sdim  /// function.
777212904Sdim  if (HasThisReturn(CGF.CurGD))
778212904Sdim    CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue);
779212904Sdim}
780212904Sdim
781212904Sdimvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
782212904Sdim                                    RValue RV, QualType ResultType) {
783212904Sdim  if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
784212904Sdim    return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
785212904Sdim
786212904Sdim  // Destructor thunks in the ARM ABI have indeterminate results.
787226633Sdim  llvm::Type *T =
788212904Sdim    cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
789212904Sdim  RValue Undef = RValue::get(llvm::UndefValue::get(T));
790212904Sdim  return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
791212904Sdim}
792212904Sdim
793212904Sdim/************************** Array allocation cookies **************************/
794212904Sdim
795218893Sdimbool ItaniumCXXABI::NeedsArrayCookie(const CXXNewExpr *expr) {
796218893Sdim  // If the class's usual deallocation function takes two arguments,
797218893Sdim  // it needs a cookie.
798218893Sdim  if (expr->doesUsualArrayDeleteWantSize())
799218893Sdim    return true;
800212904Sdim
801224145Sdim  // Automatic Reference Counting:
802224145Sdim  //   We need an array cookie for pointers with strong or weak lifetime.
803224145Sdim  QualType AllocatedType = expr->getAllocatedType();
804224145Sdim  if (getContext().getLangOptions().ObjCAutoRefCount &&
805224145Sdim      AllocatedType->isObjCLifetimeType()) {
806224145Sdim    switch (AllocatedType.getObjCLifetime()) {
807224145Sdim    case Qualifiers::OCL_None:
808224145Sdim    case Qualifiers::OCL_ExplicitNone:
809224145Sdim    case Qualifiers::OCL_Autoreleasing:
810224145Sdim      return false;
811224145Sdim
812224145Sdim    case Qualifiers::OCL_Strong:
813224145Sdim    case Qualifiers::OCL_Weak:
814224145Sdim      return true;
815224145Sdim    }
816224145Sdim  }
817224145Sdim
818218893Sdim  // Otherwise, if the class has a non-trivial destructor, it always
819218893Sdim  // needs a cookie.
820218893Sdim  const CXXRecordDecl *record =
821224145Sdim    AllocatedType->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
822218893Sdim  return (record && !record->hasTrivialDestructor());
823218893Sdim}
824212904Sdim
825218893Sdimbool ItaniumCXXABI::NeedsArrayCookie(const CXXDeleteExpr *expr,
826218893Sdim                                     QualType elementType) {
827212904Sdim  // If the class's usual deallocation function takes two arguments,
828218893Sdim  // it needs a cookie.
829218893Sdim  if (expr->doesUsualArrayDeleteWantSize())
830218893Sdim    return true;
831212904Sdim
832226633Sdim  return elementType.isDestructedType();
833212904Sdim}
834212904Sdim
835218893SdimCharUnits ItaniumCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
836218893Sdim  if (!NeedsArrayCookie(expr))
837212904Sdim    return CharUnits::Zero();
838212904Sdim
839218893Sdim  // Padding is the maximum of sizeof(size_t) and alignof(elementType)
840212904Sdim  ASTContext &Ctx = getContext();
841212904Sdim  return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
842218893Sdim                  Ctx.getTypeAlignInChars(expr->getAllocatedType()));
843212904Sdim}
844212904Sdim
845212904Sdimllvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
846212904Sdim                                                  llvm::Value *NewPtr,
847212904Sdim                                                  llvm::Value *NumElements,
848218893Sdim                                                  const CXXNewExpr *expr,
849212904Sdim                                                  QualType ElementType) {
850218893Sdim  assert(NeedsArrayCookie(expr));
851212904Sdim
852212904Sdim  unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
853212904Sdim
854212904Sdim  ASTContext &Ctx = getContext();
855212904Sdim  QualType SizeTy = Ctx.getSizeType();
856212904Sdim  CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
857212904Sdim
858212904Sdim  // The size of the cookie.
859212904Sdim  CharUnits CookieSize =
860212904Sdim    std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
861212904Sdim
862212904Sdim  // Compute an offset to the cookie.
863212904Sdim  llvm::Value *CookiePtr = NewPtr;
864212904Sdim  CharUnits CookieOffset = CookieSize - SizeSize;
865212904Sdim  if (!CookieOffset.isZero())
866212904Sdim    CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
867212904Sdim                                                 CookieOffset.getQuantity());
868212904Sdim
869212904Sdim  // Write the number of elements into the appropriate slot.
870212904Sdim  llvm::Value *NumElementsPtr
871212904Sdim    = CGF.Builder.CreateBitCast(CookiePtr,
872212904Sdim                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
873212904Sdim  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
874212904Sdim
875212904Sdim  // Finally, compute a pointer to the actual data buffer by skipping
876212904Sdim  // over the cookie completely.
877212904Sdim  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
878212904Sdim                                                CookieSize.getQuantity());
879212904Sdim}
880212904Sdim
881212904Sdimvoid ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
882212904Sdim                                    llvm::Value *Ptr,
883218893Sdim                                    const CXXDeleteExpr *expr,
884212904Sdim                                    QualType ElementType,
885212904Sdim                                    llvm::Value *&NumElements,
886212904Sdim                                    llvm::Value *&AllocPtr,
887212904Sdim                                    CharUnits &CookieSize) {
888212904Sdim  // Derive a char* in the same address space as the pointer.
889212904Sdim  unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
890226633Sdim  llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
891212904Sdim
892212904Sdim  // If we don't need an array cookie, bail out early.
893218893Sdim  if (!NeedsArrayCookie(expr, ElementType)) {
894212904Sdim    AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
895212904Sdim    NumElements = 0;
896212904Sdim    CookieSize = CharUnits::Zero();
897212904Sdim    return;
898212904Sdim  }
899212904Sdim
900212904Sdim  QualType SizeTy = getContext().getSizeType();
901212904Sdim  CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
902226633Sdim  llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
903212904Sdim
904212904Sdim  CookieSize
905212904Sdim    = std::max(SizeSize, getContext().getTypeAlignInChars(ElementType));
906212904Sdim
907212904Sdim  CharUnits NumElementsOffset = CookieSize - SizeSize;
908212904Sdim
909212904Sdim  // Compute the allocated pointer.
910212904Sdim  AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
911212904Sdim  AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
912212904Sdim                                                    -CookieSize.getQuantity());
913212904Sdim
914212904Sdim  llvm::Value *NumElementsPtr = AllocPtr;
915212904Sdim  if (!NumElementsOffset.isZero())
916212904Sdim    NumElementsPtr =
917212904Sdim      CGF.Builder.CreateConstInBoundsGEP1_64(NumElementsPtr,
918212904Sdim                                             NumElementsOffset.getQuantity());
919212904Sdim  NumElementsPtr =
920212904Sdim    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
921212904Sdim  NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
922212904Sdim}
923212904Sdim
924218893SdimCharUnits ARMCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
925218893Sdim  if (!NeedsArrayCookie(expr))
926212904Sdim    return CharUnits::Zero();
927212904Sdim
928212904Sdim  // On ARM, the cookie is always:
929212904Sdim  //   struct array_cookie {
930212904Sdim  //     std::size_t element_size; // element_size != 0
931212904Sdim  //     std::size_t element_count;
932212904Sdim  //   };
933212904Sdim  // TODO: what should we do if the allocated type actually wants
934212904Sdim  // greater alignment?
935212904Sdim  return getContext().getTypeSizeInChars(getContext().getSizeType()) * 2;
936212904Sdim}
937212904Sdim
938212904Sdimllvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
939212904Sdim                                              llvm::Value *NewPtr,
940212904Sdim                                              llvm::Value *NumElements,
941218893Sdim                                              const CXXNewExpr *expr,
942212904Sdim                                              QualType ElementType) {
943218893Sdim  assert(NeedsArrayCookie(expr));
944212904Sdim
945212904Sdim  // NewPtr is a char*.
946212904Sdim
947212904Sdim  unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
948212904Sdim
949212904Sdim  ASTContext &Ctx = getContext();
950212904Sdim  CharUnits SizeSize = Ctx.getTypeSizeInChars(Ctx.getSizeType());
951226633Sdim  llvm::IntegerType *SizeTy =
952212904Sdim    cast<llvm::IntegerType>(CGF.ConvertType(Ctx.getSizeType()));
953212904Sdim
954212904Sdim  // The cookie is always at the start of the buffer.
955212904Sdim  llvm::Value *CookiePtr = NewPtr;
956212904Sdim
957212904Sdim  // The first element is the element size.
958212904Sdim  CookiePtr = CGF.Builder.CreateBitCast(CookiePtr, SizeTy->getPointerTo(AS));
959212904Sdim  llvm::Value *ElementSize = llvm::ConstantInt::get(SizeTy,
960212904Sdim                          Ctx.getTypeSizeInChars(ElementType).getQuantity());
961212904Sdim  CGF.Builder.CreateStore(ElementSize, CookiePtr);
962212904Sdim
963212904Sdim  // The second element is the element count.
964212904Sdim  CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_32(CookiePtr, 1);
965212904Sdim  CGF.Builder.CreateStore(NumElements, CookiePtr);
966212904Sdim
967212904Sdim  // Finally, compute a pointer to the actual data buffer by skipping
968212904Sdim  // over the cookie completely.
969212904Sdim  CharUnits CookieSize = 2 * SizeSize;
970212904Sdim  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
971212904Sdim                                                CookieSize.getQuantity());
972212904Sdim}
973212904Sdim
974212904Sdimvoid ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
975212904Sdim                                llvm::Value *Ptr,
976218893Sdim                                const CXXDeleteExpr *expr,
977212904Sdim                                QualType ElementType,
978212904Sdim                                llvm::Value *&NumElements,
979212904Sdim                                llvm::Value *&AllocPtr,
980212904Sdim                                CharUnits &CookieSize) {
981212904Sdim  // Derive a char* in the same address space as the pointer.
982212904Sdim  unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
983226633Sdim  llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
984212904Sdim
985212904Sdim  // If we don't need an array cookie, bail out early.
986218893Sdim  if (!NeedsArrayCookie(expr, ElementType)) {
987212904Sdim    AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
988212904Sdim    NumElements = 0;
989212904Sdim    CookieSize = CharUnits::Zero();
990212904Sdim    return;
991212904Sdim  }
992212904Sdim
993212904Sdim  QualType SizeTy = getContext().getSizeType();
994212904Sdim  CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
995226633Sdim  llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
996212904Sdim
997212904Sdim  // The cookie size is always 2 * sizeof(size_t).
998212904Sdim  CookieSize = 2 * SizeSize;
999212904Sdim
1000212904Sdim  // The allocated pointer is the input ptr, minus that amount.
1001212904Sdim  AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
1002212904Sdim  AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1003212904Sdim                                               -CookieSize.getQuantity());
1004212904Sdim
1005212904Sdim  // The number of elements is at offset sizeof(size_t) relative to that.
1006212904Sdim  llvm::Value *NumElementsPtr
1007212904Sdim    = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
1008212904Sdim                                             SizeSize.getQuantity());
1009212904Sdim  NumElementsPtr =
1010212904Sdim    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
1011212904Sdim  NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
1012212904Sdim}
1013212904Sdim
1014218893Sdim/*********************** Static local initialization **************************/
1015218893Sdim
1016218893Sdimstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
1017224145Sdim                                         llvm::PointerType *GuardPtrTy) {
1018218893Sdim  // int __cxa_guard_acquire(__guard *guard_object);
1019226633Sdim  llvm::FunctionType *FTy =
1020218893Sdim    llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
1021226633Sdim                            GuardPtrTy, /*isVarArg=*/false);
1022218893Sdim
1023218893Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
1024218893Sdim}
1025218893Sdim
1026218893Sdimstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
1027224145Sdim                                         llvm::PointerType *GuardPtrTy) {
1028218893Sdim  // void __cxa_guard_release(__guard *guard_object);
1029226633Sdim  llvm::FunctionType *FTy =
1030218893Sdim    llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
1031226633Sdim                            GuardPtrTy, /*isVarArg=*/false);
1032218893Sdim
1033218893Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
1034218893Sdim}
1035218893Sdim
1036218893Sdimstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
1037224145Sdim                                       llvm::PointerType *GuardPtrTy) {
1038218893Sdim  // void __cxa_guard_abort(__guard *guard_object);
1039226633Sdim  llvm::FunctionType *FTy =
1040218893Sdim    llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
1041226633Sdim                            GuardPtrTy, /*isVarArg=*/false);
1042218893Sdim
1043218893Sdim  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
1044218893Sdim}
1045218893Sdim
1046218893Sdimnamespace {
1047218893Sdim  struct CallGuardAbort : EHScopeStack::Cleanup {
1048218893Sdim    llvm::GlobalVariable *Guard;
1049218893Sdim    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1050218893Sdim
1051224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
1052218893Sdim      CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
1053218893Sdim        ->setDoesNotThrow();
1054218893Sdim    }
1055218893Sdim  };
1056218893Sdim}
1057218893Sdim
1058218893Sdim/// The ARM code here follows the Itanium code closely enough that we
1059218893Sdim/// just special-case it at particular places.
1060218893Sdimvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
1061218893Sdim                                    const VarDecl &D,
1062218893Sdim                                    llvm::GlobalVariable *GV) {
1063218893Sdim  CGBuilderTy &Builder = CGF.Builder;
1064218893Sdim
1065218893Sdim  // We only need to use thread-safe statics for local variables;
1066218893Sdim  // global initialization is always single-threaded.
1067224145Sdim  bool threadsafe =
1068224145Sdim    (getContext().getLangOptions().ThreadsafeStatics && D.isLocalVarDecl());
1069221345Sdim
1070226633Sdim  llvm::IntegerType *GuardTy;
1071221345Sdim
1072221345Sdim  // If we have a global variable with internal linkage and thread-safe statics
1073221345Sdim  // are disabled, we can just let the guard variable be of type i8.
1074224145Sdim  bool useInt8GuardVariable = !threadsafe && GV->hasInternalLinkage();
1075224145Sdim  if (useInt8GuardVariable) {
1076224145Sdim    GuardTy = CGF.Int8Ty;
1077224145Sdim  } else {
1078221345Sdim    // Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
1079224145Sdim    GuardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
1080221345Sdim  }
1081224145Sdim  llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo();
1082218893Sdim
1083218893Sdim  // Create the guard variable.
1084218893Sdim  llvm::SmallString<256> GuardVName;
1085218893Sdim  llvm::raw_svector_ostream Out(GuardVName);
1086218893Sdim  getMangleContext().mangleItaniumGuardVariable(&D, Out);
1087218893Sdim  Out.flush();
1088218893Sdim
1089218893Sdim  // Just absorb linkage and visibility from the variable.
1090218893Sdim  llvm::GlobalVariable *GuardVariable =
1091218893Sdim    new llvm::GlobalVariable(CGM.getModule(), GuardTy,
1092218893Sdim                             false, GV->getLinkage(),
1093218893Sdim                             llvm::ConstantInt::get(GuardTy, 0),
1094218893Sdim                             GuardVName.str());
1095218893Sdim  GuardVariable->setVisibility(GV->getVisibility());
1096218893Sdim
1097218893Sdim  // Test whether the variable has completed initialization.
1098218893Sdim  llvm::Value *IsInitialized;
1099218893Sdim
1100218893Sdim  // ARM C++ ABI 3.2.3.1:
1101218893Sdim  //   To support the potential use of initialization guard variables
1102218893Sdim  //   as semaphores that are the target of ARM SWP and LDREX/STREX
1103218893Sdim  //   synchronizing instructions we define a static initialization
1104218893Sdim  //   guard variable to be a 4-byte aligned, 4- byte word with the
1105218893Sdim  //   following inline access protocol.
1106218893Sdim  //     #define INITIALIZED 1
1107218893Sdim  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
1108218893Sdim  //       if (__cxa_guard_acquire(&obj_guard))
1109218893Sdim  //         ...
1110218893Sdim  //     }
1111224145Sdim  if (IsARM && !useInt8GuardVariable) {
1112218893Sdim    llvm::Value *V = Builder.CreateLoad(GuardVariable);
1113218893Sdim    V = Builder.CreateAnd(V, Builder.getInt32(1));
1114218893Sdim    IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
1115218893Sdim
1116218893Sdim  // Itanium C++ ABI 3.3.2:
1117218893Sdim  //   The following is pseudo-code showing how these functions can be used:
1118218893Sdim  //     if (obj_guard.first_byte == 0) {
1119218893Sdim  //       if ( __cxa_guard_acquire (&obj_guard) ) {
1120218893Sdim  //         try {
1121218893Sdim  //           ... initialize the object ...;
1122218893Sdim  //         } catch (...) {
1123218893Sdim  //            __cxa_guard_abort (&obj_guard);
1124218893Sdim  //            throw;
1125218893Sdim  //         }
1126218893Sdim  //         ... queue object destructor with __cxa_atexit() ...;
1127218893Sdim  //         __cxa_guard_release (&obj_guard);
1128218893Sdim  //       }
1129218893Sdim  //     }
1130218893Sdim  } else {
1131218893Sdim    // Load the first byte of the guard variable.
1132226633Sdim    llvm::Type *PtrTy = Builder.getInt8PtrTy();
1133226633Sdim    llvm::LoadInst *LI =
1134226633Sdim      Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy));
1135226633Sdim    LI->setAlignment(1);
1136218893Sdim
1137226633Sdim    // Itanium ABI:
1138226633Sdim    //   An implementation supporting thread-safety on multiprocessor
1139226633Sdim    //   systems must also guarantee that references to the initialized
1140226633Sdim    //   object do not occur before the load of the initialization flag.
1141226633Sdim    //
1142226633Sdim    // In LLVM, we do this by marking the load Acquire.
1143226633Sdim    if (threadsafe)
1144226633Sdim      LI->setAtomic(llvm::Acquire);
1145226633Sdim
1146226633Sdim    IsInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
1147218893Sdim  }
1148218893Sdim
1149218893Sdim  llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
1150218893Sdim  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
1151218893Sdim
1152218893Sdim  // Check if the first byte of the guard variable is zero.
1153226633Sdim  Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock);
1154218893Sdim
1155218893Sdim  CGF.EmitBlock(InitCheckBlock);
1156218893Sdim
1157218893Sdim  // Variables used when coping with thread-safe statics and exceptions.
1158224145Sdim  if (threadsafe) {
1159218893Sdim    // Call __cxa_guard_acquire.
1160218893Sdim    llvm::Value *V
1161218893Sdim      = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable);
1162218893Sdim
1163218893Sdim    llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
1164218893Sdim
1165218893Sdim    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
1166218893Sdim                         InitBlock, EndBlock);
1167218893Sdim
1168218893Sdim    // Call __cxa_guard_abort along the exceptional edge.
1169218893Sdim    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
1170218893Sdim
1171218893Sdim    CGF.EmitBlock(InitBlock);
1172218893Sdim  }
1173218893Sdim
1174218893Sdim  // Emit the initializer and add a global destructor if appropriate.
1175218893Sdim  CGF.EmitCXXGlobalVarDeclInit(D, GV);
1176218893Sdim
1177224145Sdim  if (threadsafe) {
1178218893Sdim    // Pop the guard-abort cleanup if we pushed one.
1179218893Sdim    CGF.PopCleanupBlock();
1180218893Sdim
1181218893Sdim    // Call __cxa_guard_release.  This cannot throw.
1182218893Sdim    Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable);
1183218893Sdim  } else {
1184218893Sdim    Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable);
1185218893Sdim  }
1186218893Sdim
1187218893Sdim  CGF.EmitBlock(EndBlock);
1188218893Sdim}
1189