ItaniumCXXABI.cpp revision 221345
198944Sobrien//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
298944Sobrien//
398944Sobrien//                     The LLVM Compiler Infrastructure
498944Sobrien//
598944Sobrien// This file is distributed under the University of Illinois Open Source
698944Sobrien// License. See LICENSE.TXT for details.
798944Sobrien//
898944Sobrien//===----------------------------------------------------------------------===//
998944Sobrien//
1098944Sobrien// This provides C++ code generation targeting the Itanium C++ ABI.  The class
1198944Sobrien// in this file generates structures that follow the Itanium C++ ABI, which is
1298944Sobrien// documented at:
1398944Sobrien//  http://www.codesourcery.com/public/cxx-abi/abi.html
1498944Sobrien//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
1598944Sobrien//
1698944Sobrien// It also supports the closely-related ARM ABI, documented at:
1798944Sobrien// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
1898944Sobrien//
1998944Sobrien//===----------------------------------------------------------------------===//
2098944Sobrien
2198944Sobrien#include "CGCXXABI.h"
2298944Sobrien#include "CGRecordLayout.h"
2398944Sobrien#include "CodeGenFunction.h"
2498944Sobrien#include "CodeGenModule.h"
2598944Sobrien#include <clang/AST/Mangle.h>
2698944Sobrien#include <clang/AST/Type.h>
2798944Sobrien#include <llvm/Target/TargetData.h>
2898944Sobrien#include <llvm/Value.h>
2998944Sobrien
3098944Sobrienusing namespace clang;
3198944Sobrienusing namespace CodeGen;
3298944Sobrien
3398944Sobriennamespace {
3498944Sobrienclass ItaniumCXXABI : public CodeGen::CGCXXABI {
3598944Sobrienprivate:
3698944Sobrien  const llvm::IntegerType *PtrDiffTy;
3798944Sobrienprotected:
3898944Sobrien  bool IsARM;
3998944Sobrien
40130803Smarcel  // It's a little silly for us to cache this.
4198944Sobrien  const llvm::IntegerType *getPtrDiffTy() {
4298944Sobrien    if (!PtrDiffTy) {
4398944Sobrien      QualType T = getContext().getPointerDiffType();
4498944Sobrien      const llvm::Type *Ty = CGM.getTypes().ConvertTypeRecursive(T);
4598944Sobrien      PtrDiffTy = cast<llvm::IntegerType>(Ty);
4698944Sobrien    }
4798944Sobrien    return PtrDiffTy;
4898944Sobrien  }
4998944Sobrien
5098944Sobrien  bool NeedsArrayCookie(const CXXNewExpr *expr);
5198944Sobrien  bool NeedsArrayCookie(const CXXDeleteExpr *expr,
5298944Sobrien                        QualType elementType);
5398944Sobrien
5498944Sobrienpublic:
5598944Sobrien  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
5698944Sobrien    CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { }
5798944Sobrien
5898944Sobrien  bool isZeroInitializable(const MemberPointerType *MPT);
59130803Smarcel
6098944Sobrien  const llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
6198944Sobrien
6298944Sobrien  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
6398944Sobrien                                               llvm::Value *&This,
6498944Sobrien                                               llvm::Value *MemFnPtr,
6598944Sobrien                                               const MemberPointerType *MPT);
6698944Sobrien
6798944Sobrien  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
6898944Sobrien                                            llvm::Value *Base,
6998944Sobrien                                            llvm::Value *MemPtr,
7098944Sobrien                                            const MemberPointerType *MPT);
7198944Sobrien
7298944Sobrien  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
7398944Sobrien                                           const CastExpr *E,
7498944Sobrien                                           llvm::Value *Src);
7598944Sobrien
7698944Sobrien  llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
7798944Sobrien                                              const CastExpr *E);
7898944Sobrien
7998944Sobrien  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
8098944Sobrien
8198944Sobrien  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
8298944Sobrien  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
8398944Sobrien                                        CharUnits offset);
8498944Sobrien
8598944Sobrien  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
8698944Sobrien                                           llvm::Value *L,
8798944Sobrien                                           llvm::Value *R,
8898944Sobrien                                           const MemberPointerType *MPT,
8998944Sobrien                                           bool Inequality);
9098944Sobrien
9198944Sobrien  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
9298944Sobrien                                          llvm::Value *Addr,
9398944Sobrien                                          const MemberPointerType *MPT);
9498944Sobrien
9598944Sobrien  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
9698944Sobrien                                 CXXCtorType T,
97130803Smarcel                                 CanQualType &ResTy,
98130803Smarcel                                 llvm::SmallVectorImpl<CanQualType> &ArgTys);
9998944Sobrien
10098944Sobrien  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
10198944Sobrien                                CXXDtorType T,
10298944Sobrien                                CanQualType &ResTy,
10398944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys);
10498944Sobrien
10598944Sobrien  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
10698944Sobrien                                   QualType &ResTy,
10798944Sobrien                                   FunctionArgList &Params);
10898944Sobrien
10998944Sobrien  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
110130803Smarcel
11198944Sobrien  CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
11298944Sobrien  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
113130803Smarcel                                     llvm::Value *NewPtr,
114130803Smarcel                                     llvm::Value *NumElements,
11598944Sobrien                                     const CXXNewExpr *expr,
11698944Sobrien                                     QualType ElementType);
11798944Sobrien  void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
11898944Sobrien                       const CXXDeleteExpr *expr,
11998944Sobrien                       QualType ElementType, llvm::Value *&NumElements,
12098944Sobrien                       llvm::Value *&AllocPtr, CharUnits &CookieSize);
12198944Sobrien
12298944Sobrien  void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
12398944Sobrien                       llvm::GlobalVariable *DeclPtr);
12498944Sobrien};
12598944Sobrien
12698944Sobrienclass ARMCXXABI : public ItaniumCXXABI {
12798944Sobrienpublic:
12898944Sobrien  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
12998944Sobrien
13098944Sobrien  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
13198944Sobrien                                 CXXCtorType T,
13298944Sobrien                                 CanQualType &ResTy,
13398944Sobrien                                 llvm::SmallVectorImpl<CanQualType> &ArgTys);
13498944Sobrien
13598944Sobrien  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
13698944Sobrien                                CXXDtorType T,
13798944Sobrien                                CanQualType &ResTy,
13898944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys);
13998944Sobrien
14098944Sobrien  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
14198944Sobrien                                   QualType &ResTy,
14298944Sobrien                                   FunctionArgList &Params);
14398944Sobrien
14498944Sobrien  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
14598944Sobrien
14698944Sobrien  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
14798944Sobrien
14898944Sobrien  CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
14998944Sobrien  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
15098944Sobrien                                     llvm::Value *NewPtr,
15198944Sobrien                                     llvm::Value *NumElements,
15298944Sobrien                                     const CXXNewExpr *expr,
15398944Sobrien                                     QualType ElementType);
15498944Sobrien  void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
15598944Sobrien                       const CXXDeleteExpr *expr,
15698944Sobrien                       QualType ElementType, llvm::Value *&NumElements,
15798944Sobrien                       llvm::Value *&AllocPtr, CharUnits &CookieSize);
158130803Smarcel
159130803Smarcelprivate:
160130803Smarcel  /// \brief Returns true if the given instance method is one of the
161130803Smarcel  /// kinds that the ARM ABI says returns 'this'.
162130803Smarcel  static bool HasThisReturn(GlobalDecl GD) {
163130803Smarcel    const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
16498944Sobrien    return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) ||
16598944Sobrien            (isa<CXXConstructorDecl>(MD)));
166130803Smarcel  }
16798944Sobrien};
16898944Sobrien}
16998944Sobrien
17098944SobrienCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
17198944Sobrien  return new ItaniumCXXABI(CGM);
17298944Sobrien}
17398944Sobrien
17498944SobrienCodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) {
17598944Sobrien  return new ARMCXXABI(CGM);
17698944Sobrien}
17798944Sobrien
17898944Sobrienconst llvm::Type *
17998944SobrienItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
18098944Sobrien  if (MPT->isMemberDataPointer())
18198944Sobrien    return getPtrDiffTy();
18298944Sobrien  else
18398944Sobrien    return llvm::StructType::get(CGM.getLLVMContext(),
184130803Smarcel                                 getPtrDiffTy(), getPtrDiffTy(), NULL);
185130803Smarcel}
18698944Sobrien
18798944Sobrien/// In the Itanium and ARM ABIs, method pointers have the form:
18898944Sobrien///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
18998944Sobrien///
19098944Sobrien/// In the Itanium ABI:
19198944Sobrien///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
19298944Sobrien///  - the this-adjustment is (memptr.adj)
19398944Sobrien///  - the virtual offset is (memptr.ptr - 1)
19498944Sobrien///
19598944Sobrien/// In the ARM ABI:
19698944Sobrien///  - method pointers are virtual if (memptr.adj & 1) is nonzero
19798944Sobrien///  - the this-adjustment is (memptr.adj >> 1)
19898944Sobrien///  - the virtual offset is (memptr.ptr)
19998944Sobrien/// ARM uses 'adj' for the virtual flag because Thumb functions
20098944Sobrien/// may be only single-byte aligned.
20198944Sobrien///
20298944Sobrien/// If the member is virtual, the adjusted 'this' pointer points
20398944Sobrien/// to a vtable pointer from which the virtual offset is applied.
20498944Sobrien///
20598944Sobrien/// If the member is non-virtual, memptr.ptr is the address of
20698944Sobrien/// the function to call.
20798944Sobrienllvm::Value *
20898944SobrienItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
209130803Smarcel                                               llvm::Value *&This,
21098944Sobrien                                               llvm::Value *MemFnPtr,
21198944Sobrien                                               const MemberPointerType *MPT) {
21298944Sobrien  CGBuilderTy &Builder = CGF.Builder;
21398944Sobrien
21498944Sobrien  const FunctionProtoType *FPT =
21598944Sobrien    MPT->getPointeeType()->getAs<FunctionProtoType>();
21698944Sobrien  const CXXRecordDecl *RD =
21798944Sobrien    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
21898944Sobrien
21998944Sobrien  const llvm::FunctionType *FTy =
22098944Sobrien    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
22198944Sobrien                                   FPT->isVariadic());
22298944Sobrien
22398944Sobrien  const llvm::IntegerType *ptrdiff = getPtrDiffTy();
22498944Sobrien  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(ptrdiff, 1);
22598944Sobrien
226130803Smarcel  llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
22798944Sobrien  llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
22898944Sobrien  llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
22998944Sobrien
23098944Sobrien  // Extract memptr.adj, which is in the second field.
23198944Sobrien  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
23298944Sobrien
23398944Sobrien  // Compute the true adjustment.
234130803Smarcel  llvm::Value *Adj = RawAdj;
235130803Smarcel  if (IsARM)
236130803Smarcel    Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
237130803Smarcel
238130803Smarcel  // Apply the adjustment and cast back to the original struct type
239130803Smarcel  // for consistency.
240130803Smarcel  llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
241130803Smarcel  Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
24298944Sobrien  This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
24398944Sobrien
24498944Sobrien  // Load the function pointer.
24598944Sobrien  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
24698944Sobrien
24798944Sobrien  // If the LSB in the function pointer is 1, the function pointer points to
248130803Smarcel  // a virtual function.
249130803Smarcel  llvm::Value *IsVirtual;
25098944Sobrien  if (IsARM)
25198944Sobrien    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
25298944Sobrien  else
25398944Sobrien    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
25498944Sobrien  IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
25598944Sobrien  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
25698944Sobrien
25798944Sobrien  // In the virtual path, the adjustment left 'This' pointing to the
25898944Sobrien  // vtable of the correct base subobject.  The "function pointer" is an
259130803Smarcel  // offset within the vtable (+1 for the virtual flag on non-ARM).
260130803Smarcel  CGF.EmitBlock(FnVirtual);
261130803Smarcel
262130803Smarcel  // Cast the adjusted this to a pointer to vtable pointer and load.
26398944Sobrien  const llvm::Type *VTableTy = Builder.getInt8PtrTy();
26498944Sobrien  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
265130803Smarcel  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
266130803Smarcel
267130803Smarcel  // Apply the offset.
268130803Smarcel  llvm::Value *VTableOffset = FnAsInt;
26998944Sobrien  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
27098944Sobrien  VTable = Builder.CreateGEP(VTable, VTableOffset);
27198944Sobrien
27298944Sobrien  // Load the virtual function to call.
27398944Sobrien  VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
27498944Sobrien  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
27598944Sobrien  CGF.EmitBranch(FnEnd);
27698944Sobrien
27798944Sobrien  // In the non-virtual path, the function pointer is actually a
27898944Sobrien  // function pointer.
27998944Sobrien  CGF.EmitBlock(FnNonVirtual);
28098944Sobrien  llvm::Value *NonVirtualFn =
28198944Sobrien    Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
28298944Sobrien
28398944Sobrien  // We're done.
28498944Sobrien  CGF.EmitBlock(FnEnd);
28598944Sobrien  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
286130803Smarcel  Callee->addIncoming(VirtualFn, FnVirtual);
287130803Smarcel  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
288130803Smarcel  return Callee;
28998944Sobrien}
290130803Smarcel
291130803Smarcel/// Compute an l-value by applying the given pointer-to-member to a
292130803Smarcel/// base object.
293130803Smarcelllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
294130803Smarcel                                                         llvm::Value *Base,
295130803Smarcel                                                         llvm::Value *MemPtr,
296130803Smarcel                                           const MemberPointerType *MPT) {
297130803Smarcel  assert(MemPtr->getType() == getPtrDiffTy());
298130803Smarcel
299130803Smarcel  CGBuilderTy &Builder = CGF.Builder;
300130803Smarcel
301130803Smarcel  unsigned AS = cast<llvm::PointerType>(Base->getType())->getAddressSpace();
302130803Smarcel
303130803Smarcel  // Cast to char*.
304130803Smarcel  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
305130803Smarcel
306130803Smarcel  // Apply the offset, which we assume is non-null.
307130803Smarcel  llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
308130803Smarcel
309130803Smarcel  // Cast the address to the appropriate pointer type, adopting the
310130803Smarcel  // address space of the base pointer.
311130803Smarcel  const llvm::Type *PType
312130803Smarcel    = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
313130803Smarcel  return Builder.CreateBitCast(Addr, PType);
314130803Smarcel}
315130803Smarcel
316130803Smarcel/// Perform a derived-to-base or base-to-derived member pointer conversion.
317130803Smarcel///
318130803Smarcel/// Obligatory offset/adjustment diagram:
319130803Smarcel///         <-- offset -->          <-- adjustment -->
320130803Smarcel///   |--------------------------|----------------------|--------------------|
321130803Smarcel///   ^Derived address point     ^Base address point    ^Member address point
322130803Smarcel///
323130803Smarcel/// So when converting a base member pointer to a derived member pointer,
32498944Sobrien/// we add the offset to the adjustment because the address point has
32598944Sobrien/// decreased;  and conversely, when converting a derived MP to a base MP
32698944Sobrien/// we subtract the offset from the adjustment because the address point
32798944Sobrien/// has increased.
32898944Sobrien///
329130803Smarcel/// The standard forbids (at compile time) conversion to and from
330130803Smarcel/// virtual bases, which is why we don't have to consider them here.
33198944Sobrien///
33298944Sobrien/// The standard forbids (at run time) casting a derived MP to a base
33398944Sobrien/// MP when the derived MP does not point to a member of the base.
334130803Smarcel/// This is why -1 is a reasonable choice for null data member
335130803Smarcel/// pointers.
33698944Sobrienllvm::Value *
33798944SobrienItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
33898944Sobrien                                           const CastExpr *E,
33998944Sobrien                                           llvm::Value *Src) {
34098944Sobrien  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
34198944Sobrien         E->getCastKind() == CK_BaseToDerivedMemberPointer);
34298944Sobrien
34398944Sobrien  if (isa<llvm::Constant>(Src))
34498944Sobrien    return EmitMemberPointerConversion(cast<llvm::Constant>(Src), E);
34598944Sobrien
346130803Smarcel  CGBuilderTy &Builder = CGF.Builder;
347130803Smarcel
348130803Smarcel  const MemberPointerType *SrcTy =
349130803Smarcel    E->getSubExpr()->getType()->getAs<MemberPointerType>();
350130803Smarcel  const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
351130803Smarcel
352130803Smarcel  const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
353130803Smarcel  const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
354130803Smarcel
35598944Sobrien  bool DerivedToBase =
356130803Smarcel    E->getCastKind() == CK_DerivedToBaseMemberPointer;
357130803Smarcel
35898944Sobrien  const CXXRecordDecl *DerivedDecl;
35998944Sobrien  if (DerivedToBase)
36098944Sobrien    DerivedDecl = SrcDecl;
36198944Sobrien  else
36298944Sobrien    DerivedDecl = DestDecl;
36398944Sobrien
36498944Sobrien  llvm::Constant *Adj =
36598944Sobrien    CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
36698944Sobrien                                         E->path_begin(),
36798944Sobrien                                         E->path_end());
36898944Sobrien  if (!Adj) return Src;
36998944Sobrien
37098944Sobrien  // For member data pointers, this is just a matter of adding the
37198944Sobrien  // offset if the source is non-null.
37298944Sobrien  if (SrcTy->isMemberDataPointer()) {
37398944Sobrien    llvm::Value *Dst;
37498944Sobrien    if (DerivedToBase)
37598944Sobrien      Dst = Builder.CreateNSWSub(Src, Adj, "adj");
37698944Sobrien    else
37798944Sobrien      Dst = Builder.CreateNSWAdd(Src, Adj, "adj");
37898944Sobrien
37998944Sobrien    // Null check.
38098944Sobrien    llvm::Value *Null = llvm::Constant::getAllOnesValue(Src->getType());
38198944Sobrien    llvm::Value *IsNull = Builder.CreateICmpEQ(Src, Null, "memptr.isnull");
38298944Sobrien    return Builder.CreateSelect(IsNull, Src, Dst);
38398944Sobrien  }
38498944Sobrien
38598944Sobrien  // The this-adjustment is left-shifted by 1 on ARM.
38698944Sobrien  if (IsARM) {
38798944Sobrien    uint64_t Offset = cast<llvm::ConstantInt>(Adj)->getZExtValue();
38898944Sobrien    Offset <<= 1;
38998944Sobrien    Adj = llvm::ConstantInt::get(Adj->getType(), Offset);
39098944Sobrien  }
39198944Sobrien
39298944Sobrien  llvm::Value *SrcAdj = Builder.CreateExtractValue(Src, 1, "src.adj");
39398944Sobrien  llvm::Value *DstAdj;
39498944Sobrien  if (DerivedToBase)
39598944Sobrien    DstAdj = Builder.CreateNSWSub(SrcAdj, Adj, "adj");
39698944Sobrien  else
39798944Sobrien    DstAdj = Builder.CreateNSWAdd(SrcAdj, Adj, "adj");
39898944Sobrien
39998944Sobrien  return Builder.CreateInsertValue(Src, DstAdj, 1);
40098944Sobrien}
40198944Sobrien
40298944Sobrienllvm::Constant *
40398944SobrienItaniumCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
40498944Sobrien                                           const CastExpr *E) {
40598944Sobrien  const MemberPointerType *SrcTy =
40698944Sobrien    E->getSubExpr()->getType()->getAs<MemberPointerType>();
40798944Sobrien  const MemberPointerType *DestTy =
40898944Sobrien    E->getType()->getAs<MemberPointerType>();
40998944Sobrien
41098944Sobrien  bool DerivedToBase =
41198944Sobrien    E->getCastKind() == CK_DerivedToBaseMemberPointer;
41298944Sobrien
41398944Sobrien  const CXXRecordDecl *DerivedDecl;
41498944Sobrien  if (DerivedToBase)
41598944Sobrien    DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
41698944Sobrien  else
41798944Sobrien    DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
41898944Sobrien
41998944Sobrien  // Calculate the offset to the base class.
42098944Sobrien  llvm::Constant *Offset =
42198944Sobrien    CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
42298944Sobrien                                     E->path_begin(),
42398944Sobrien                                     E->path_end());
42498944Sobrien  // If there's no offset, we're done.
42598944Sobrien  if (!Offset) return C;
42698944Sobrien
42798944Sobrien  // If the source is a member data pointer, we have to do a null
42898944Sobrien  // check and then add the offset.  In the common case, we can fold
42998944Sobrien  // away the offset.
43098944Sobrien  if (SrcTy->isMemberDataPointer()) {
43198944Sobrien    assert(C->getType() == getPtrDiffTy());
43298944Sobrien
43398944Sobrien    // If it's a constant int, just create a new constant int.
43498944Sobrien    if (llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C)) {
43598944Sobrien      int64_t Src = CI->getSExtValue();
43698944Sobrien
43798944Sobrien      // Null converts to null.
438130803Smarcel      if (Src == -1) return CI;
43998944Sobrien
44098944Sobrien      // Otherwise, just add the offset.
44198944Sobrien      int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
44298944Sobrien      int64_t Dst = (DerivedToBase ? Src - OffsetV : Src + OffsetV);
44398944Sobrien      return llvm::ConstantInt::get(CI->getType(), Dst, /*signed*/ true);
444130803Smarcel    }
44598944Sobrien
44698944Sobrien    // Otherwise, we have to form a constant select expression.
44798944Sobrien    llvm::Constant *Null = llvm::Constant::getAllOnesValue(C->getType());
44898944Sobrien
44998944Sobrien    llvm::Constant *IsNull =
45098944Sobrien      llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_EQ, C, Null);
45198944Sobrien
45298944Sobrien    llvm::Constant *Dst;
45398944Sobrien    if (DerivedToBase)
45498944Sobrien      Dst = llvm::ConstantExpr::getNSWSub(C, Offset);
45598944Sobrien    else
45698944Sobrien      Dst = llvm::ConstantExpr::getNSWAdd(C, Offset);
45798944Sobrien
45898944Sobrien    return llvm::ConstantExpr::getSelect(IsNull, Null, Dst);
45998944Sobrien  }
46098944Sobrien
46198944Sobrien  // The this-adjustment is left-shifted by 1 on ARM.
46298944Sobrien  if (IsARM) {
46398944Sobrien    int64_t OffsetV = cast<llvm::ConstantInt>(Offset)->getSExtValue();
46498944Sobrien    OffsetV <<= 1;
46598944Sobrien    Offset = llvm::ConstantInt::get(Offset->getType(), OffsetV);
46698944Sobrien  }
46798944Sobrien
46898944Sobrien  llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
46998944Sobrien
47098944Sobrien  llvm::Constant *Values[2] = { CS->getOperand(0), 0 };
47198944Sobrien  if (DerivedToBase)
47298944Sobrien    Values[1] = llvm::ConstantExpr::getSub(CS->getOperand(1), Offset);
47398944Sobrien  else
47498944Sobrien    Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
47598944Sobrien
47698944Sobrien  return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
47798944Sobrien                                   /*Packed=*/false);
47898944Sobrien}
47998944Sobrien
48098944Sobrien
48198944Sobrienllvm::Constant *
48298944SobrienItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
48398944Sobrien  const llvm::Type *ptrdiff_t = getPtrDiffTy();
48498944Sobrien
48598944Sobrien  // Itanium C++ ABI 2.3:
48698944Sobrien  //   A NULL pointer is represented as -1.
48798944Sobrien  if (MPT->isMemberDataPointer())
48898944Sobrien    return llvm::ConstantInt::get(ptrdiff_t, -1ULL, /*isSigned=*/true);
48998944Sobrien
49098944Sobrien  llvm::Constant *Zero = llvm::ConstantInt::get(ptrdiff_t, 0);
49198944Sobrien  llvm::Constant *Values[2] = { Zero, Zero };
49298944Sobrien  return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
49398944Sobrien                                   /*Packed=*/false);
49498944Sobrien}
49598944Sobrien
49698944Sobrienllvm::Constant *
49798944SobrienItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
49898944Sobrien                                     CharUnits offset) {
49998944Sobrien  // Itanium C++ ABI 2.3:
50098944Sobrien  //   A pointer to data member is an offset from the base address of
50198944Sobrien  //   the class object containing it, represented as a ptrdiff_t
50298944Sobrien  return llvm::ConstantInt::get(getPtrDiffTy(), offset.getQuantity());
50398944Sobrien}
50498944Sobrien
50598944Sobrienllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
50698944Sobrien  assert(MD->isInstance() && "Member function must not be static!");
50798944Sobrien  MD = MD->getCanonicalDecl();
50898944Sobrien
50998944Sobrien  CodeGenTypes &Types = CGM.getTypes();
51098944Sobrien  const llvm::Type *ptrdiff_t = getPtrDiffTy();
51198944Sobrien
51298944Sobrien  // Get the function pointer (or index if this is a virtual function).
51398944Sobrien  llvm::Constant *MemPtr[2];
51498944Sobrien  if (MD->isVirtual()) {
51598944Sobrien    uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
516130803Smarcel
517130803Smarcel    const ASTContext &Context = getContext();
518130803Smarcel    CharUnits PointerWidth =
519130803Smarcel      Context.toCharUnitsFromBits(Context.Target.getPointerWidth(0));
520130803Smarcel    uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
521130803Smarcel
522130803Smarcel    if (IsARM) {
523130803Smarcel      // ARM C++ ABI 3.2.1:
524130803Smarcel      //   This ABI specifies that adj contains twice the this
525130803Smarcel      //   adjustment, plus 1 if the member function is virtual. The
526130803Smarcel      //   least significant bit of adj then makes exactly the same
527130803Smarcel      //   discrimination as the least significant bit of ptr does for
528130803Smarcel      //   Itanium.
529130803Smarcel      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset);
530130803Smarcel      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 1);
531130803Smarcel    } else {
532130803Smarcel      // Itanium C++ ABI 2.3:
533130803Smarcel      //   For a virtual function, [the pointer field] is 1 plus the
534130803Smarcel      //   virtual table offset (in bytes) of the function,
535130803Smarcel      //   represented as a ptrdiff_t.
536130803Smarcel      MemPtr[0] = llvm::ConstantInt::get(ptrdiff_t, VTableOffset + 1);
537130803Smarcel      MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
53898944Sobrien    }
53998944Sobrien  } else {
54098944Sobrien    const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
54198944Sobrien    const llvm::Type *Ty;
54298944Sobrien    // Check whether the function has a computable LLVM signature.
54398944Sobrien    if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) {
54498944Sobrien      // The function has a computable LLVM signature; use the correct type.
54598944Sobrien      Ty = Types.GetFunctionType(Types.getFunctionInfo(MD),
54698944Sobrien                                 FPT->isVariadic());
54798944Sobrien    } else {
54898944Sobrien      // Use an arbitrary non-function type to tell GetAddrOfFunction that the
54998944Sobrien      // function type is incomplete.
55098944Sobrien      Ty = ptrdiff_t;
55198944Sobrien    }
55298944Sobrien    llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
55398944Sobrien
55498944Sobrien    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, ptrdiff_t);
55598944Sobrien    MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0);
55698944Sobrien  }
55798944Sobrien
55898944Sobrien  return llvm::ConstantStruct::get(CGM.getLLVMContext(),
55998944Sobrien                                   MemPtr, 2, /*Packed=*/false);
56098944Sobrien}
56198944Sobrien
562130803Smarcel/// The comparison algorithm is pretty easy: the member pointers are
56398944Sobrien/// the same if they're either bitwise identical *or* both null.
56498944Sobrien///
56598944Sobrien/// ARM is different here only because null-ness is more complicated.
56698944Sobrienllvm::Value *
56798944SobrienItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
56898944Sobrien                                           llvm::Value *L,
56998944Sobrien                                           llvm::Value *R,
57098944Sobrien                                           const MemberPointerType *MPT,
57198944Sobrien                                           bool Inequality) {
57298944Sobrien  CGBuilderTy &Builder = CGF.Builder;
573130803Smarcel
57498944Sobrien  llvm::ICmpInst::Predicate Eq;
57598944Sobrien  llvm::Instruction::BinaryOps And, Or;
57698944Sobrien  if (Inequality) {
57798944Sobrien    Eq = llvm::ICmpInst::ICMP_NE;
57898944Sobrien    And = llvm::Instruction::Or;
57998944Sobrien    Or = llvm::Instruction::And;
58098944Sobrien  } else {
58198944Sobrien    Eq = llvm::ICmpInst::ICMP_EQ;
58298944Sobrien    And = llvm::Instruction::And;
58398944Sobrien    Or = llvm::Instruction::Or;
58498944Sobrien  }
58598944Sobrien
58698944Sobrien  // Member data pointers are easy because there's a unique null
58798944Sobrien  // value, so it just comes down to bitwise equality.
58898944Sobrien  if (MPT->isMemberDataPointer())
58998944Sobrien    return Builder.CreateICmp(Eq, L, R);
59098944Sobrien
59198944Sobrien  // For member function pointers, the tautologies are more complex.
59298944Sobrien  // The Itanium tautology is:
59398944Sobrien  //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
59498944Sobrien  // The ARM tautology is:
59598944Sobrien  //   (L == R) <==> (L.ptr == R.ptr &&
59698944Sobrien  //                  (L.adj == R.adj ||
59798944Sobrien  //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
59898944Sobrien  // The inequality tautologies have exactly the same structure, except
59998944Sobrien  // applying De Morgan's laws.
60098944Sobrien
60198944Sobrien  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
60298944Sobrien  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
60398944Sobrien
60498944Sobrien  // This condition tests whether L.ptr == R.ptr.  This must always be
60598944Sobrien  // true for equality to hold.
60698944Sobrien  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
60798944Sobrien
60898944Sobrien  // This condition, together with the assumption that L.ptr == R.ptr,
60998944Sobrien  // tests whether the pointers are both null.  ARM imposes an extra
610130803Smarcel  // condition.
61198944Sobrien  llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
61298944Sobrien  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
61398944Sobrien
61498944Sobrien  // This condition tests whether L.adj == R.adj.  If this isn't
61598944Sobrien  // true, the pointers are unequal unless they're both null.
61698944Sobrien  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
61798944Sobrien  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
61898944Sobrien  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
61998944Sobrien
62098944Sobrien  // Null member function pointers on ARM clear the low bit of Adj,
62198944Sobrien  // so the zero condition has to check that neither low bit is set.
62298944Sobrien  if (IsARM) {
62398944Sobrien    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
62498944Sobrien
62598944Sobrien    // Compute (l.adj | r.adj) & 1 and test it against zero.
62698944Sobrien    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
62798944Sobrien    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
62898944Sobrien    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
62998944Sobrien                                                      "cmp.or.adj");
63098944Sobrien    EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
63198944Sobrien  }
63298944Sobrien
63398944Sobrien  // Tie together all our conditions.
63498944Sobrien  llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
63598944Sobrien  Result = Builder.CreateBinOp(And, PtrEq, Result,
63698944Sobrien                               Inequality ? "memptr.ne" : "memptr.eq");
63798944Sobrien  return Result;
63898944Sobrien}
63998944Sobrien
64098944Sobrienllvm::Value *
64198944SobrienItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
64298944Sobrien                                          llvm::Value *MemPtr,
64398944Sobrien                                          const MemberPointerType *MPT) {
64498944Sobrien  CGBuilderTy &Builder = CGF.Builder;
64598944Sobrien
64698944Sobrien  /// For member data pointers, this is just a check against -1.
64798944Sobrien  if (MPT->isMemberDataPointer()) {
64898944Sobrien    assert(MemPtr->getType() == getPtrDiffTy());
64998944Sobrien    llvm::Value *NegativeOne =
65098944Sobrien      llvm::Constant::getAllOnesValue(MemPtr->getType());
65198944Sobrien    return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
65298944Sobrien  }
65398944Sobrien
65498944Sobrien  // In Itanium, a member function pointer is not null if 'ptr' is not null.
65598944Sobrien  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
656130803Smarcel
65798944Sobrien  llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
65898944Sobrien  llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
659130803Smarcel
660130803Smarcel  // On ARM, a member function pointer is also non-null if the low bit of 'adj'
66198944Sobrien  // (the virtual bit) is set.
66298944Sobrien  if (IsARM) {
66398944Sobrien    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
66498944Sobrien    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
66598944Sobrien    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
66698944Sobrien    llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
66798944Sobrien                                                  "memptr.isvirtual");
66898944Sobrien    Result = Builder.CreateOr(Result, IsVirtual);
66998944Sobrien  }
67098944Sobrien
67198944Sobrien  return Result;
672130803Smarcel}
673130803Smarcel
674130803Smarcel/// The Itanium ABI requires non-zero initialization only for data
675130803Smarcel/// member pointers, for which '0' is a valid offset.
676130803Smarcelbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
677130803Smarcel  return MPT->getPointeeType()->isFunctionType();
678130803Smarcel}
679130803Smarcel
680130803Smarcel/// The generic ABI passes 'this', plus a VTT if it's initializing a
681130803Smarcel/// base subobject.
682130803Smarcelvoid ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
683130803Smarcel                                              CXXCtorType Type,
68498944Sobrien                                              CanQualType &ResTy,
68598944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys) {
68698944Sobrien  ASTContext &Context = getContext();
68798944Sobrien
688130803Smarcel  // 'this' is already there.
68998944Sobrien
69098944Sobrien  // Check if we need to add a VTT parameter (which has type void **).
69198944Sobrien  if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
69298944Sobrien    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
69398944Sobrien}
69498944Sobrien
69598944Sobrien/// The ARM ABI does the same as the Itanium ABI, but returns 'this'.
69698944Sobrienvoid ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
69798944Sobrien                                          CXXCtorType Type,
69898944Sobrien                                          CanQualType &ResTy,
69998944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys) {
70098944Sobrien  ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys);
70198944Sobrien  ResTy = ArgTys[0];
70298944Sobrien}
70398944Sobrien
70498944Sobrien/// The generic ABI passes 'this', plus a VTT if it's destroying a
70598944Sobrien/// base subobject.
70698944Sobrienvoid ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
70798944Sobrien                                             CXXDtorType Type,
70898944Sobrien                                             CanQualType &ResTy,
70998944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys) {
71098944Sobrien  ASTContext &Context = getContext();
71198944Sobrien
71298944Sobrien  // 'this' is already there.
71398944Sobrien
71498944Sobrien  // Check if we need to add a VTT parameter (which has type void **).
71598944Sobrien  if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
71698944Sobrien    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
71798944Sobrien}
71898944Sobrien
71998944Sobrien/// The ARM ABI does the same as the Itanium ABI, but returns 'this'
72098944Sobrien/// for non-deleting destructors.
72198944Sobrienvoid ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
72298944Sobrien                                         CXXDtorType Type,
72398944Sobrien                                         CanQualType &ResTy,
72498944Sobrien                                llvm::SmallVectorImpl<CanQualType> &ArgTys) {
725130803Smarcel  ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys);
726130803Smarcel
727130803Smarcel  if (Type != Dtor_Deleting)
72898944Sobrien    ResTy = ArgTys[0];
72998944Sobrien}
73098944Sobrien
73198944Sobrienvoid ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
73298944Sobrien                                                QualType &ResTy,
73398944Sobrien                                                FunctionArgList &Params) {
73498944Sobrien  /// Create the 'this' variable.
73598944Sobrien  BuildThisParam(CGF, Params);
73698944Sobrien
73798944Sobrien  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
73898944Sobrien  assert(MD->isInstance());
73998944Sobrien
74098944Sobrien  // Check if we need a VTT parameter as well.
74198944Sobrien  if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
74298944Sobrien    ASTContext &Context = getContext();
74398944Sobrien
74498944Sobrien    // FIXME: avoid the fake decl
74598944Sobrien    QualType T = Context.getPointerType(Context.VoidPtrTy);
74698944Sobrien    ImplicitParamDecl *VTTDecl
74798944Sobrien      = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
74898944Sobrien                                  &Context.Idents.get("vtt"), T);
74998944Sobrien    Params.push_back(VTTDecl);
75098944Sobrien    getVTTDecl(CGF) = VTTDecl;
75198944Sobrien  }
75298944Sobrien}
75398944Sobrien
75498944Sobrienvoid ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
75598944Sobrien                                            QualType &ResTy,
75698944Sobrien                                            FunctionArgList &Params) {
75798944Sobrien  ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params);
75898944Sobrien
75998944Sobrien  // Return 'this' from certain constructors and destructors.
76098944Sobrien  if (HasThisReturn(CGF.CurGD))
76198944Sobrien    ResTy = Params[0]->getType();
76298944Sobrien}
76398944Sobrien
76498944Sobrienvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
76598944Sobrien  /// Initialize the 'this' slot.
76698944Sobrien  EmitThisParam(CGF);
767130803Smarcel
768130803Smarcel  /// Initialize the 'vtt' slot if needed.
76998944Sobrien  if (getVTTDecl(CGF)) {
77098944Sobrien    getVTTValue(CGF)
77198944Sobrien      = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
77298944Sobrien                               "vtt");
77398944Sobrien  }
774130803Smarcel}
775130803Smarcel
77698944Sobrienvoid ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
77798944Sobrien  ItaniumCXXABI::EmitInstanceFunctionProlog(CGF);
778130803Smarcel
779130803Smarcel  /// Initialize the return slot to 'this' at the start of the
780130803Smarcel  /// function.
78198944Sobrien  if (HasThisReturn(CGF.CurGD))
78298944Sobrien    CGF.Builder.CreateStore(CGF.LoadCXXThis(), CGF.ReturnValue);
78398944Sobrien}
78498944Sobrien
78598944Sobrienvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
78698944Sobrien                                    RValue RV, QualType ResultType) {
78798944Sobrien  if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
78898944Sobrien    return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
78998944Sobrien
79098944Sobrien  // Destructor thunks in the ARM ABI have indeterminate results.
79198944Sobrien  const llvm::Type *T =
79298944Sobrien    cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
79398944Sobrien  RValue Undef = RValue::get(llvm::UndefValue::get(T));
79498944Sobrien  return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
79598944Sobrien}
79698944Sobrien
79798944Sobrien/************************** Array allocation cookies **************************/
79898944Sobrien
79998944Sobrienbool ItaniumCXXABI::NeedsArrayCookie(const CXXNewExpr *expr) {
80098944Sobrien  // If the class's usual deallocation function takes two arguments,
80198944Sobrien  // it needs a cookie.
80298944Sobrien  if (expr->doesUsualArrayDeleteWantSize())
80398944Sobrien    return true;
80498944Sobrien
80598944Sobrien  // Otherwise, if the class has a non-trivial destructor, it always
80698944Sobrien  // needs a cookie.
80798944Sobrien  const CXXRecordDecl *record =
80898944Sobrien    expr->getAllocatedType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
80998944Sobrien  return (record && !record->hasTrivialDestructor());
81098944Sobrien}
81198944Sobrien
81298944Sobrienbool ItaniumCXXABI::NeedsArrayCookie(const CXXDeleteExpr *expr,
81398944Sobrien                                     QualType elementType) {
81498944Sobrien  // If the class's usual deallocation function takes two arguments,
81598944Sobrien  // it needs a cookie.
81698944Sobrien  if (expr->doesUsualArrayDeleteWantSize())
81798944Sobrien    return true;
81898944Sobrien
81998944Sobrien  // Otherwise, if the class has a non-trivial destructor, it always
82098944Sobrien  // needs a cookie.
82198944Sobrien  const CXXRecordDecl *record =
82298944Sobrien    elementType->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
82398944Sobrien  return (record && !record->hasTrivialDestructor());
82498944Sobrien}
82598944Sobrien
82698944SobrienCharUnits ItaniumCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
82798944Sobrien  if (!NeedsArrayCookie(expr))
82898944Sobrien    return CharUnits::Zero();
82998944Sobrien
83098944Sobrien  // Padding is the maximum of sizeof(size_t) and alignof(elementType)
83198944Sobrien  ASTContext &Ctx = getContext();
83298944Sobrien  return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
83398944Sobrien                  Ctx.getTypeAlignInChars(expr->getAllocatedType()));
83498944Sobrien}
83598944Sobrien
83698944Sobrienllvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
83798944Sobrien                                                  llvm::Value *NewPtr,
83898944Sobrien                                                  llvm::Value *NumElements,
83998944Sobrien                                                  const CXXNewExpr *expr,
84098944Sobrien                                                  QualType ElementType) {
84198944Sobrien  assert(NeedsArrayCookie(expr));
84298944Sobrien
84398944Sobrien  unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
84498944Sobrien
84598944Sobrien  ASTContext &Ctx = getContext();
84698944Sobrien  QualType SizeTy = Ctx.getSizeType();
84798944Sobrien  CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
84898944Sobrien
84998944Sobrien  // The size of the cookie.
85098944Sobrien  CharUnits CookieSize =
85198944Sobrien    std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
85298944Sobrien
85398944Sobrien  // Compute an offset to the cookie.
85498944Sobrien  llvm::Value *CookiePtr = NewPtr;
85598944Sobrien  CharUnits CookieOffset = CookieSize - SizeSize;
85698944Sobrien  if (!CookieOffset.isZero())
85798944Sobrien    CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
85898944Sobrien                                                 CookieOffset.getQuantity());
85998944Sobrien
86098944Sobrien  // Write the number of elements into the appropriate slot.
86198944Sobrien  llvm::Value *NumElementsPtr
86298944Sobrien    = CGF.Builder.CreateBitCast(CookiePtr,
86398944Sobrien                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
86498944Sobrien  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
86598944Sobrien
86698944Sobrien  // Finally, compute a pointer to the actual data buffer by skipping
86798944Sobrien  // over the cookie completely.
86898944Sobrien  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
86998944Sobrien                                                CookieSize.getQuantity());
87098944Sobrien}
87198944Sobrien
87298944Sobrienvoid ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
87398944Sobrien                                    llvm::Value *Ptr,
87498944Sobrien                                    const CXXDeleteExpr *expr,
87598944Sobrien                                    QualType ElementType,
87698944Sobrien                                    llvm::Value *&NumElements,
87798944Sobrien                                    llvm::Value *&AllocPtr,
87898944Sobrien                                    CharUnits &CookieSize) {
87998944Sobrien  // Derive a char* in the same address space as the pointer.
88098944Sobrien  unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
88198944Sobrien  const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
88298944Sobrien
88398944Sobrien  // If we don't need an array cookie, bail out early.
88498944Sobrien  if (!NeedsArrayCookie(expr, ElementType)) {
88598944Sobrien    AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
88698944Sobrien    NumElements = 0;
88798944Sobrien    CookieSize = CharUnits::Zero();
88898944Sobrien    return;
88998944Sobrien  }
89098944Sobrien
89198944Sobrien  QualType SizeTy = getContext().getSizeType();
89298944Sobrien  CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
89398944Sobrien  const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
89498944Sobrien
89598944Sobrien  CookieSize
89698944Sobrien    = std::max(SizeSize, getContext().getTypeAlignInChars(ElementType));
89798944Sobrien
89898944Sobrien  CharUnits NumElementsOffset = CookieSize - SizeSize;
89998944Sobrien
90098944Sobrien  // Compute the allocated pointer.
90198944Sobrien  AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
90298944Sobrien  AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
90398944Sobrien                                                    -CookieSize.getQuantity());
90498944Sobrien
90598944Sobrien  llvm::Value *NumElementsPtr = AllocPtr;
90698944Sobrien  if (!NumElementsOffset.isZero())
90798944Sobrien    NumElementsPtr =
90898944Sobrien      CGF.Builder.CreateConstInBoundsGEP1_64(NumElementsPtr,
90998944Sobrien                                             NumElementsOffset.getQuantity());
91098944Sobrien  NumElementsPtr =
91198944Sobrien    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
91298944Sobrien  NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
91398944Sobrien}
91498944Sobrien
91598944SobrienCharUnits ARMCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
91698944Sobrien  if (!NeedsArrayCookie(expr))
91798944Sobrien    return CharUnits::Zero();
91898944Sobrien
91998944Sobrien  // On ARM, the cookie is always:
92098944Sobrien  //   struct array_cookie {
92198944Sobrien  //     std::size_t element_size; // element_size != 0
92298944Sobrien  //     std::size_t element_count;
92398944Sobrien  //   };
92498944Sobrien  // TODO: what should we do if the allocated type actually wants
92598944Sobrien  // greater alignment?
92698944Sobrien  return getContext().getTypeSizeInChars(getContext().getSizeType()) * 2;
92798944Sobrien}
92898944Sobrien
92998944Sobrienllvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
93098944Sobrien                                              llvm::Value *NewPtr,
93198944Sobrien                                              llvm::Value *NumElements,
93298944Sobrien                                              const CXXNewExpr *expr,
93398944Sobrien                                              QualType ElementType) {
93498944Sobrien  assert(NeedsArrayCookie(expr));
93598944Sobrien
93698944Sobrien  // NewPtr is a char*.
93798944Sobrien
93898944Sobrien  unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
93998944Sobrien
94098944Sobrien  ASTContext &Ctx = getContext();
94198944Sobrien  CharUnits SizeSize = Ctx.getTypeSizeInChars(Ctx.getSizeType());
94298944Sobrien  const llvm::IntegerType *SizeTy =
94398944Sobrien    cast<llvm::IntegerType>(CGF.ConvertType(Ctx.getSizeType()));
94498944Sobrien
94598944Sobrien  // The cookie is always at the start of the buffer.
94698944Sobrien  llvm::Value *CookiePtr = NewPtr;
94798944Sobrien
94898944Sobrien  // The first element is the element size.
94998944Sobrien  CookiePtr = CGF.Builder.CreateBitCast(CookiePtr, SizeTy->getPointerTo(AS));
95098944Sobrien  llvm::Value *ElementSize = llvm::ConstantInt::get(SizeTy,
95198944Sobrien                          Ctx.getTypeSizeInChars(ElementType).getQuantity());
95298944Sobrien  CGF.Builder.CreateStore(ElementSize, CookiePtr);
95398944Sobrien
95498944Sobrien  // The second element is the element count.
95598944Sobrien  CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_32(CookiePtr, 1);
95698944Sobrien  CGF.Builder.CreateStore(NumElements, CookiePtr);
95798944Sobrien
95898944Sobrien  // Finally, compute a pointer to the actual data buffer by skipping
95998944Sobrien  // over the cookie completely.
96098944Sobrien  CharUnits CookieSize = 2 * SizeSize;
96198944Sobrien  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
96298944Sobrien                                                CookieSize.getQuantity());
96398944Sobrien}
96498944Sobrien
96598944Sobrienvoid ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
96698944Sobrien                                llvm::Value *Ptr,
96798944Sobrien                                const CXXDeleteExpr *expr,
96898944Sobrien                                QualType ElementType,
96998944Sobrien                                llvm::Value *&NumElements,
97098944Sobrien                                llvm::Value *&AllocPtr,
97198944Sobrien                                CharUnits &CookieSize) {
97298944Sobrien  // Derive a char* in the same address space as the pointer.
97398944Sobrien  unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
97498944Sobrien  const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
97598944Sobrien
97698944Sobrien  // If we don't need an array cookie, bail out early.
97798944Sobrien  if (!NeedsArrayCookie(expr, ElementType)) {
97898944Sobrien    AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
97998944Sobrien    NumElements = 0;
98098944Sobrien    CookieSize = CharUnits::Zero();
98198944Sobrien    return;
98298944Sobrien  }
98398944Sobrien
98498944Sobrien  QualType SizeTy = getContext().getSizeType();
98598944Sobrien  CharUnits SizeSize = getContext().getTypeSizeInChars(SizeTy);
986130803Smarcel  const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
987130803Smarcel
988130803Smarcel  // The cookie size is always 2 * sizeof(size_t).
989130803Smarcel  CookieSize = 2 * SizeSize;
990130803Smarcel
991130803Smarcel  // The allocated pointer is the input ptr, minus that amount.
992130803Smarcel  AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
993130803Smarcel  AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
994130803Smarcel                                               -CookieSize.getQuantity());
995130803Smarcel
996130803Smarcel  // The number of elements is at offset sizeof(size_t) relative to that.
997130803Smarcel  llvm::Value *NumElementsPtr
998130803Smarcel    = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
999130803Smarcel                                             SizeSize.getQuantity());
1000130803Smarcel  NumElementsPtr =
1001130803Smarcel    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
1002130803Smarcel  NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
1003130803Smarcel}
1004130803Smarcel
1005130803Smarcel/*********************** Static local initialization **************************/
1006130803Smarcel
1007130803Smarcelstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
1008130803Smarcel                                         const llvm::PointerType *GuardPtrTy) {
1009130803Smarcel  // int __cxa_guard_acquire(__guard *guard_object);
1010130803Smarcel
1011130803Smarcel  std::vector<const llvm::Type*> Args(1, GuardPtrTy);
1012130803Smarcel  const llvm::FunctionType *FTy =
1013130803Smarcel    llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
1014130803Smarcel                            Args, /*isVarArg=*/false);
1015130803Smarcel
1016130803Smarcel  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
1017130803Smarcel}
101898944Sobrien
101998944Sobrienstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
102098944Sobrien                                         const llvm::PointerType *GuardPtrTy) {
102198944Sobrien  // void __cxa_guard_release(__guard *guard_object);
102298944Sobrien
102398944Sobrien  std::vector<const llvm::Type*> Args(1, GuardPtrTy);
102498944Sobrien
102598944Sobrien  const llvm::FunctionType *FTy =
102698944Sobrien    llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
102798944Sobrien                            Args, /*isVarArg=*/false);
102898944Sobrien
102998944Sobrien  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
103098944Sobrien}
103198944Sobrien
103298944Sobrienstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
103398944Sobrien                                       const llvm::PointerType *GuardPtrTy) {
103498944Sobrien  // void __cxa_guard_abort(__guard *guard_object);
103598944Sobrien
103698944Sobrien  std::vector<const llvm::Type*> Args(1, GuardPtrTy);
103798944Sobrien
103898944Sobrien  const llvm::FunctionType *FTy =
103998944Sobrien    llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
104098944Sobrien                            Args, /*isVarArg=*/false);
104198944Sobrien
104298944Sobrien  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
104398944Sobrien}
1044130803Smarcel
1045130803Smarcelnamespace {
104698944Sobrien  struct CallGuardAbort : EHScopeStack::Cleanup {
104798944Sobrien    llvm::GlobalVariable *Guard;
104898944Sobrien    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
104998944Sobrien
105098944Sobrien    void Emit(CodeGenFunction &CGF, bool IsForEH) {
105198944Sobrien      CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
105298944Sobrien        ->setDoesNotThrow();
105398944Sobrien    }
105498944Sobrien  };
105598944Sobrien}
105698944Sobrien
105798944Sobrien/// The ARM code here follows the Itanium code closely enough that we
105898944Sobrien/// just special-case it at particular places.
105998944Sobrienvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
106098944Sobrien                                    const VarDecl &D,
106198944Sobrien                                    llvm::GlobalVariable *GV) {
106298944Sobrien  CGBuilderTy &Builder = CGF.Builder;
106398944Sobrien
106498944Sobrien  // We only need to use thread-safe statics for local variables;
106598944Sobrien  // global initialization is always single-threaded.
106698944Sobrien  bool ThreadsafeStatics = (getContext().getLangOptions().ThreadsafeStatics &&
106798944Sobrien                            D.isLocalVarDecl());
106898944Sobrien
106998944Sobrien  const llvm::IntegerType *GuardTy;
107098944Sobrien
107198944Sobrien  // If we have a global variable with internal linkage and thread-safe statics
107298944Sobrien  // are disabled, we can just let the guard variable be of type i8.
107398944Sobrien  bool UseInt8GuardVariable = !ThreadsafeStatics && GV->hasInternalLinkage();
107498944Sobrien  if (UseInt8GuardVariable)
107598944Sobrien    GuardTy = Builder.getInt8Ty();
107698944Sobrien  else {
107798944Sobrien    // Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
107898944Sobrien    GuardTy = (IsARM ? Builder.getInt32Ty() : Builder.getInt64Ty());
107998944Sobrien  }
108098944Sobrien  const llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo();
108198944Sobrien
108298944Sobrien  // Create the guard variable.
108398944Sobrien  llvm::SmallString<256> GuardVName;
1084130803Smarcel  llvm::raw_svector_ostream Out(GuardVName);
1085130803Smarcel  getMangleContext().mangleItaniumGuardVariable(&D, Out);
108698944Sobrien  Out.flush();
108798944Sobrien
108898944Sobrien  // Just absorb linkage and visibility from the variable.
108998944Sobrien  llvm::GlobalVariable *GuardVariable =
109098944Sobrien    new llvm::GlobalVariable(CGM.getModule(), GuardTy,
109198944Sobrien                             false, GV->getLinkage(),
109298944Sobrien                             llvm::ConstantInt::get(GuardTy, 0),
109398944Sobrien                             GuardVName.str());
109498944Sobrien  GuardVariable->setVisibility(GV->getVisibility());
109598944Sobrien
109698944Sobrien  // Test whether the variable has completed initialization.
109798944Sobrien  llvm::Value *IsInitialized;
109898944Sobrien
109998944Sobrien  // ARM C++ ABI 3.2.3.1:
110098944Sobrien  //   To support the potential use of initialization guard variables
110198944Sobrien  //   as semaphores that are the target of ARM SWP and LDREX/STREX
110298944Sobrien  //   synchronizing instructions we define a static initialization
110398944Sobrien  //   guard variable to be a 4-byte aligned, 4- byte word with the
110498944Sobrien  //   following inline access protocol.
110598944Sobrien  //     #define INITIALIZED 1
110698944Sobrien  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
110798944Sobrien  //       if (__cxa_guard_acquire(&obj_guard))
110898944Sobrien  //         ...
110998944Sobrien  //     }
111098944Sobrien  if (IsARM && !UseInt8GuardVariable) {
111198944Sobrien    llvm::Value *V = Builder.CreateLoad(GuardVariable);
111298944Sobrien    V = Builder.CreateAnd(V, Builder.getInt32(1));
111398944Sobrien    IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
111498944Sobrien
111598944Sobrien  // Itanium C++ ABI 3.3.2:
111698944Sobrien  //   The following is pseudo-code showing how these functions can be used:
111798944Sobrien  //     if (obj_guard.first_byte == 0) {
111898944Sobrien  //       if ( __cxa_guard_acquire (&obj_guard) ) {
111998944Sobrien  //         try {
112098944Sobrien  //           ... initialize the object ...;
112198944Sobrien  //         } catch (...) {
112298944Sobrien  //            __cxa_guard_abort (&obj_guard);
112398944Sobrien  //            throw;
112498944Sobrien  //         }
112598944Sobrien  //         ... queue object destructor with __cxa_atexit() ...;
112698944Sobrien  //         __cxa_guard_release (&obj_guard);
112798944Sobrien  //       }
112898944Sobrien  //     }
112998944Sobrien  } else {
113098944Sobrien    // Load the first byte of the guard variable.
113198944Sobrien    const llvm::Type *PtrTy = Builder.getInt8PtrTy();
113298944Sobrien    llvm::Value *V =
113398944Sobrien      Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp");
113498944Sobrien
113598944Sobrien    IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
113698944Sobrien  }
113798944Sobrien
113898944Sobrien  llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
113998944Sobrien  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
114098944Sobrien
114198944Sobrien  // Check if the first byte of the guard variable is zero.
114298944Sobrien  Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock);
114398944Sobrien
114498944Sobrien  CGF.EmitBlock(InitCheckBlock);
114598944Sobrien
114698944Sobrien  // Variables used when coping with thread-safe statics and exceptions.
114798944Sobrien  if (ThreadsafeStatics) {
114898944Sobrien    // Call __cxa_guard_acquire.
114998944Sobrien    llvm::Value *V
115098944Sobrien      = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable);
115198944Sobrien
115298944Sobrien    llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
115398944Sobrien
115498944Sobrien    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
115598944Sobrien                         InitBlock, EndBlock);
115698944Sobrien
115798944Sobrien    // Call __cxa_guard_abort along the exceptional edge.
115898944Sobrien    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
115998944Sobrien
116098944Sobrien    CGF.EmitBlock(InitBlock);
116198944Sobrien  }
116298944Sobrien
116398944Sobrien  // Emit the initializer and add a global destructor if appropriate.
116498944Sobrien  CGF.EmitCXXGlobalVarDeclInit(D, GV);
116598944Sobrien
116698944Sobrien  if (ThreadsafeStatics) {
116798944Sobrien    // Pop the guard-abort cleanup if we pushed one.
116898944Sobrien    CGF.PopCleanupBlock();
116998944Sobrien
117098944Sobrien    // Call __cxa_guard_release.  This cannot throw.
117198944Sobrien    Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable);
117298944Sobrien  } else {
117398944Sobrien    Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable);
117498944Sobrien  }
117598944Sobrien
117698944Sobrien  CGF.EmitBlock(EndBlock);
117798944Sobrien}
117898944Sobrien