ItaniumCXXABI.cpp revision a4130baad9d10b7feabb7e003da53424e986d269
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This provides C++ code generation targeting the Itanium C++ ABI.  The class
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// in this file generates structures that follow the Itanium C++ ABI, which is
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// documented at:
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  http://www.codesourcery.com/public/cxx-abi/abi.html
14c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
150979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor//
16a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner// It also supports the closely-related ARM ABI, documented at:
172eadfb638eb1bb6ccfd6fd0453e764d47e27eed9Chris Lattner// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
18a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner//
1998cd599ee8a9b259ed7388ee2921a20d97658864Douglas Gregor//===----------------------------------------------------------------------===//
20aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
2119cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "CGCXXABI.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CGRecordLayout.h"
2308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "CGVTables.h"
2408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "CodeGenFunction.h"
251b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "CodeGenModule.h"
2608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner#include "clang/AST/Mangle.h"
27da5a6b6d9fd52899499d5b7b46273ec844dcaa6eChris Lattner#include "clang/AST/Type.h"
28cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor#include "llvm/IR/DataLayout.h"
293a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson#include "llvm/IR/Intrinsics.h"
30ffb4b6e299069139908540ce97be4462e16b53a4Douglas Gregor#include "llvm/IR/Value.h"
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
33bef0efd11bc4430a3ee437a3213cec5c18af855aChris Lattnerusing namespace CodeGen;
34bef0efd11bc4430a3ee437a3213cec5c18af855aChris Lattner
352b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattnernamespace {
362b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattnerclass ItaniumCXXABI : public CodeGen::CGCXXABI {
372b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattnerprotected:
382b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  bool IsARM;
392b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
402b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattnerpublic:
412b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
42c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    CGCXXABI(CGM), IsARM(IsARM) { }
432ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor
44c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {
452b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    // Structures with either a non-trivial destructor or a non-trivial
462b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    // copy constructor are always indirect.
47c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    return !RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor();
482b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  }
492b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
502de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const {
512de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    // Structures with either a non-trivial destructor or a non-trivial
522b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    // copy constructor are always indirect.
532b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    if (!RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
542b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner      return RAA_Indirect;
552b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    return RAA_Default;
562b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  }
57c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
586907fbe758d23e1aec4c0a67e7b633d1d855feb4John McCall  bool isZeroInitializable(const MemberPointerType *MPT);
596907fbe758d23e1aec4c0a67e7b633d1d855feb4John McCall
606907fbe758d23e1aec4c0a67e7b633d1d855feb4John McCall  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
612b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
62c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
632b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                               llvm::Value *&This,
642b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                               llvm::Value *MemFnPtr,
652b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                               const MemberPointerType *MPT);
662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                            llvm::Value *Base,
692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                            llvm::Value *MemPtr,
702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                            const MemberPointerType *MPT);
712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
722de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                           const CastExpr *E,
742b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                           llvm::Value *Src);
75c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
762de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                              llvm::Constant *Src);
772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
792b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
802b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
812b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
82c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                        CharUnits offset);
832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
842de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
852b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                     CharUnits ThisAdjustment);
862b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
872b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
88c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                           llvm::Value *L,
892b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                           llvm::Value *R,
902b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                           const MemberPointerType *MPT,
912b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                           bool Inequality);
92c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
932b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
942b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                          llvm::Value *Addr,
952b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner                                          const MemberPointerType *MPT);
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                      llvm::Value *ptr,
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                      QualType type);
100d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
101d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
102d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                         llvm::Value *This,
103d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                         const CXXRecordDecl *ClassDecl,
104d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                         const CXXRecordDecl *BaseClassDecl);
105d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
106d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
107d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                 CXXCtorType T,
108d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                 CanQualType &ResTy,
109d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                 SmallVectorImpl<CanQualType> &ArgTys);
110d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
111d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
112d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                CXXDtorType T,
113d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                CanQualType &ResTy,
114d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                SmallVectorImpl<CanQualType> &ArgTys);
115d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
116d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
117d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                              CXXDtorType DT) const {
118d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    // Itanium does not emit any destructor variant as an inline thunk.
1198dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    // Delegating may occur as an optimization, but all variants are either
1208dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    // emitted with external linkage or as linkonce if they are inline and used.
1218dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis    return false;
1228dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis  }
1238dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis
124d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void EmitCXXDestructors(const CXXDestructorDecl *D);
125d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
1268dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
127d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                   QualType &ResTy,
128d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                   FunctionArgList &Params);
1290da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
1308e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
1318e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
132c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  void EmitConstructorCall(CodeGenFunction &CGF,
1330da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                           const CXXConstructorDecl *D, CXXCtorType Type,
1340da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                           bool ForVirtualBase, bool Delegating,
1350da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                           llvm::Value *This,
1360da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                           CallExpr::const_arg_iterator ArgBeg,
1370da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                           CallExpr::const_arg_iterator ArgEnd);
138c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
1390da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  void EmitVirtualDestructorCall(CodeGenFunction &CGF,
1400da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                 const CXXDestructorDecl *Dtor,
1410da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                 CXXDtorType DtorType, SourceLocation CallLoc,
1420da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                 llvm::Value *This);
1430da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
1440da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  void EmitVirtualInheritanceTables(llvm::GlobalVariable::LinkageTypes Linkage,
1450da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                    const CXXRecordDecl *RD);
1468e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1478e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
1480da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
1490da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
150c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  CharUnits getArrayCookieSizeImpl(QualType elementType);
1510da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
1520da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                     llvm::Value *NewPtr,
1538e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                                     llvm::Value *NumElements,
1548e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                                     const CXXNewExpr *expr,
1550da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                     QualType ElementType);
1560da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
157096832c5ed5b9106fa177ebc148489760c3bc496John McCall                                   llvm::Value *allocPtr,
1580da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                   CharUnits cookieSize);
159c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
1600da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
1618e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                       llvm::GlobalVariable *DeclPtr, bool PerformInit);
1628e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
1630da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                          llvm::Constant *dtor, llvm::Constant *addr);
1640da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
1650da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
1668e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                                                llvm::GlobalVariable *Var);
1670da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  void EmitThreadLocalInitFuncs(
1680da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
1690da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      llvm::Function *InitFunc);
1702ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor  LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
171501edb6a54524555ad27fbf41a7920dc756b08c6Douglas Gregor                                    const DeclRefExpr *DRE);
17231310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl
173501edb6a54524555ad27fbf41a7920dc756b08c6Douglas Gregor  bool NeedsVTTParameter(GlobalDecl GD);
1748e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall};
175bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor
176bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregorclass ARMCXXABI : public ItaniumCXXABI {
177bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregorpublic:
178bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {}
179bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor
1807ed5bd3e27a6f2b37ee0449aa818116cbd03306eDouglas Gregor  bool HasThisReturn(GlobalDecl GD) const {
1818e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    return (isa<CXXConstructorDecl>(GD.getDecl()) || (
182bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor              isa<CXXDestructorDecl>(GD.getDecl()) &&
183bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor              GD.getDtorType() != Dtor_Deleting));
184bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  }
185bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor
186bb6e73fcf60fa5a4cc36c14744dc366b658443b5Douglas Gregor  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
1878e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1880da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  CharUnits getArrayCookieSizeImpl(QualType elementType);
1890da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
1900da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                     llvm::Value *NewPtr,
1910da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                     llvm::Value *NumElements,
1920da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor                                     const CXXNewExpr *expr,
193c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                     QualType ElementType);
194a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,
195dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall                                   CharUnits cookieSize);
196d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall};
197f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall}
198f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
199a2813cec2605ce7878d1b13471d685f689b251afDouglas GregorCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
200a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  switch (CGM.getTarget().getCXXABI().getKind()) {
201d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  // For IR-generation purposes, there's no significant difference
202a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // between the ARM and iOS ABIs.
203a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  case TargetCXXABI::GenericARM:
204a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  case TargetCXXABI::iOS:
205a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    return new ARMCXXABI(CGM);
206a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
207a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
208c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // include the other 32-bit ARM oddities: constructor/destructor return values
209d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  // and array cookies.
210096832c5ed5b9106fa177ebc148489760c3bc496John McCall  case TargetCXXABI::GenericAArch64:
211a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    return  new ItaniumCXXABI(CGM, /*IsARM = */ true);
2120da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
213a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  case TargetCXXABI::GenericItanium:
214a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    return new ItaniumCXXABI(CGM);
2152577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
2162577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  case TargetCXXABI::Microsoft:
2172577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    llvm_unreachable("Microsoft ABI is not Itanium-based");
2182577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  }
219f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  llvm_unreachable("bad ABI kind");
220f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall}
2212577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
2222577743c5650c646fb705df01403707e94f2df04Abramo Bagnarallvm::Type *
2232577743c5650c646fb705df01403707e94f2df04Abramo BagnaraItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
2242577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  if (MPT->isMemberDataPointer())
2252577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    return CGM.PtrDiffTy;
2262577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, NULL);
2272577743c5650c646fb705df01403707e94f2df04Abramo Bagnara}
2282577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
2292577743c5650c646fb705df01403707e94f2df04Abramo Bagnara/// In the Itanium and ARM ABIs, method pointers have the form:
2302577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
2312577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///
232096832c5ed5b9106fa177ebc148489760c3bc496John McCall/// In the Itanium ABI:
2332577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
2342577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///  - the this-adjustment is (memptr.adj)
2352577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///  - the virtual offset is (memptr.ptr - 1)
2362577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///
237a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor/// In the ARM ABI:
238a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor///  - method pointers are virtual if (memptr.adj & 1) is nonzero
239a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor///  - the this-adjustment is (memptr.adj >> 1)
240dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall///  - the virtual offset is (memptr.ptr)
241a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor/// ARM uses 'adj' for the virtual flag because Thumb functions
2420da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor/// may be only single-byte aligned.
243f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall///
2440da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor/// If the member is virtual, the adjusted 'this' pointer points
2452577743c5650c646fb705df01403707e94f2df04Abramo Bagnara/// to a vtable pointer from which the virtual offset is applied.
2462577743c5650c646fb705df01403707e94f2df04Abramo Bagnara///
247f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall/// If the member is non-virtual, memptr.ptr is the address of
2482577743c5650c646fb705df01403707e94f2df04Abramo Bagnara/// the function to call.
2492577743c5650c646fb705df01403707e94f2df04Abramo Bagnarallvm::Value *
2502577743c5650c646fb705df01403707e94f2df04Abramo BagnaraItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
2512577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                                               llvm::Value *&This,
2522577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                                               llvm::Value *MemFnPtr,
2532577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                                               const MemberPointerType *MPT) {
2542577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  CGBuilderTy &Builder = CGF.Builder;
2552577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
256f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  const FunctionProtoType *FPT =
2572577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    MPT->getPointeeType()->getAs<FunctionProtoType>();
258a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  const CXXRecordDecl *RD =
259a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
260a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
261c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  llvm::FunctionType *FTy =
262d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    CGM.getTypes().GetFunctionType(
263d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      CGM.getTypes().arrangeCXXMethodType(RD, FPT));
264c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
2653248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
2662577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
267f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
268a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
269a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
270663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis
271663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  // Extract memptr.adj, which is in the second field.
272663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
273663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis
274663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  // Compute the true adjustment.
275663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  llvm::Value *Adj = RawAdj;
276663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  if (IsARM)
277663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis    Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
278663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis
2793248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner  // Apply the adjustment and cast back to the original struct type
280663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  // for consistency.
281663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
282663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis  Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
283a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
2842577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
285a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // Load the function pointer.
286a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
287096832c5ed5b9106fa177ebc148489760c3bc496John McCall
288a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // If the LSB in the function pointer is 1, the function pointer points to
289a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  // a virtual function.
290a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  llvm::Value *IsVirtual;
291a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor  if (IsARM)
2923a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
2933a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  else
294848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
295848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson  IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
296848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
2973a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
298848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson  // In the virtual path, the adjustment left 'This' pointing to the
2993a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // vtable of the correct base subobject.  The "function pointer" is an
3003a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // offset within the vtable (+1 for the virtual flag on non-ARM).
3013a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  CGF.EmitBlock(FnVirtual);
3023a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3033a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Cast the adjusted this to a pointer to vtable pointer and load.
3043a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::Type *VTableTy = Builder.getInt8PtrTy();
305848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
3063a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
3074eadcc569223135e13353c9381b448986e3f7053Sam Weinig
3084eadcc569223135e13353c9381b448986e3f7053Sam Weinig  // Apply the offset.
3093a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::Value *VTableOffset = FnAsInt;
3103a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
3113a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  VTable = Builder.CreateGEP(VTable, VTableOffset);
3123a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3133a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Load the virtual function to call.
3143a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
315183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn");
3163a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  CGF.EmitBranch(FnEnd);
3173a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3183a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // In the non-virtual path, the function pointer is actually a
3193a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // function pointer.
3203a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  CGF.EmitBlock(FnNonVirtual);
3213a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::Value *NonVirtualFn =
3223a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
3233a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3243a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // We're done.
3253a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  CGF.EmitBlock(FnEnd);
3263a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
3273a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  Callee->addIncoming(VirtualFn, FnVirtual);
3283a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  Callee->addIncoming(NonVirtualFn, FnNonVirtual);
3293a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return Callee;
3303a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
3313a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3323a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// Compute an l-value by applying the given pointer-to-member to a
3333a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// base object.
3343a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlssonllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
3353a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                                                         llvm::Value *Base,
3363a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                                                         llvm::Value *MemPtr,
3374eadcc569223135e13353c9381b448986e3f7053Sam Weinig                                           const MemberPointerType *MPT) {
3384eadcc569223135e13353c9381b448986e3f7053Sam Weinig  assert(MemPtr->getType() == CGM.PtrDiffTy);
3394eadcc569223135e13353c9381b448986e3f7053Sam Weinig
3404eadcc569223135e13353c9381b448986e3f7053Sam Weinig  CGBuilderTy &Builder = CGF.Builder;
3414eadcc569223135e13353c9381b448986e3f7053Sam Weinig
3424eadcc569223135e13353c9381b448986e3f7053Sam Weinig  unsigned AS = Base->getType()->getPointerAddressSpace();
3434eadcc569223135e13353c9381b448986e3f7053Sam Weinig
3444eadcc569223135e13353c9381b448986e3f7053Sam Weinig  // Cast to char*.
3453a1ce1ed0f5686384e712837bad28c576622e442Sam Weinig  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
3463a1ce1ed0f5686384e712837bad28c576622e442Sam Weinig
3473a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Apply the offset, which we assume is non-null.
3483a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
3493a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3503a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // Cast the address to the appropriate pointer type, adopting the
3513a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  // address space of the base pointer.
3523a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  llvm::Type *PType
3533a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson    = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
3543a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson  return Builder.CreateBitCast(Addr, PType);
3553a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson}
3563a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
3573a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// Perform a bitcast, derived-to-base, or base-to-derived member pointer
358b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek/// conversion.
359b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek///
360b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek/// Bitcast conversions are always a no-op under Itanium.
361b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek///
362900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer/// Obligatory offset/adjustment diagram:
363b03d33edaf24af2893a50caee4d2c99839242c44Ted Kremenek///         <-- offset -->          <-- adjustment -->
3643a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson///   |--------------------------|----------------------|--------------------|
365900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer///   ^Derived address point     ^Base address point    ^Member address point
366900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer///
367900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer/// So when converting a base member pointer to a derived member pointer,
3683a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// we add the offset to the adjustment because the address point has
3693a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// decreased;  and conversely, when converting a derived MP to a base MP
3703a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// we subtract the offset from the adjustment because the address point
3713a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// has increased.
3723a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson///
3733a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// The standard forbids (at compile time) conversion to and from
3743a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// virtual bases, which is why we don't have to consider them here.
3753a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson///
3763a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// The standard forbids (at run time) casting a derived MP to a base
3773a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// MP when the derived MP does not point to a member of the base.
3783a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// This is why -1 is a reasonable choice for null data member
3793a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson/// pointers.
3803a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlssonllvm::Value *
3813a082d81006e7a2e01a6e431a22e21c78490ff8fAnders CarlssonItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3829996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                           const CastExpr *E,
3839996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                           llvm::Value *src) {
3849996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
3859996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
3869996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis         E->getCastKind() == CK_ReinterpretMemberPointer);
3879996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
3889996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // Under Itanium, reinterprets don't require any additional processing.
3899996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
3909996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
3919996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // Use constant emission if we can.
3929996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (isa<llvm::Constant>(src))
3939996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
3949996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
3959996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  llvm::Constant *adj = getMemberPointerAdjustment(E);
3969996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (!adj) return src;
3979996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
3989996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  CGBuilderTy &Builder = CGF.Builder;
3999996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
4009996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4019996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  const MemberPointerType *destTy =
4029996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    E->getType()->castAs<MemberPointerType>();
4039996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4049996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // For member data pointers, this is just a matter of adding the
4059996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // offset if the source is non-null.
4069996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (destTy->isMemberDataPointer()) {
4079996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    llvm::Value *dst;
4089996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    if (isDerivedToBase)
4099996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      dst = Builder.CreateNSWSub(src, adj, "adj");
4109996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    else
4119996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      dst = Builder.CreateNSWAdd(src, adj, "adj");
4129996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4139996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    // Null check.
4149996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
4159996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
4169996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return Builder.CreateSelect(isNull, src, dst);
4179996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  }
4189996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
4199996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // The this-adjustment is left-shifted by 1 on ARM.
420da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  if (IsARM) {
421da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
422da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    offset <<= 1;
423da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    adj = llvm::ConstantInt::get(adj->getType(), offset);
424da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  }
425ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen
426ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen  llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
427ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen  llvm::Value *dstAdj;
428da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  if (isDerivedToBase)
429da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
430da8249e57f3badecf925571881fe57243935c6c1Chris Lattner  else
4312085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
4322085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
4332085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  return Builder.CreateInsertValue(src, dstAdj, 1);
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
435a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson
4362085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattnerllvm::Constant *
4372085fd6cd22ec5c268175251db10d7c60caf7aaaChris LattnerItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
4382085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                                           llvm::Constant *src) {
4392085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
4403248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner         E->getCastKind() == CK_BaseToDerivedMemberPointer ||
4412085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner         E->getCastKind() == CK_ReinterpretMemberPointer);
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Under Itanium, reinterprets don't require any additional processing.
4442085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
4452085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
4462085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  // If the adjustment is trivial, we don't need to do anything.
4472085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  llvm::Constant *adj = getMemberPointerAdjustment(E);
4482085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  if (!adj) return src;
4492085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
4502085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
452726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner  const MemberPointerType *destTy =
4532085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    E->getType()->castAs<MemberPointerType>();
4542085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
455726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner  // For member data pointers, this is just a matter of adding the
456726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner  // offset if the source is non-null.
457673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  if (destTy->isMemberDataPointer()) {
458673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    // null maps to null.
459673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    if (src->isAllOnesValue()) return src;
4603248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner
461673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    if (isDerivedToBase)
462673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      return llvm::ConstantExpr::getNSWSub(src, adj);
463673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    else
464673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      return llvm::ConstantExpr::getNSWAdd(src, adj);
465673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  }
466673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor
467673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  // The this-adjustment is left-shifted by 1 on ARM.
468b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar  if (IsARM) {
469b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar    uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
470b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar    offset <<= 1;
471673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    adj = llvm::ConstantInt::get(adj->getType(), offset);
472b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar  }
473673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor
474673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
47508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  llvm::Constant *dstAdj;
47608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  if (isDerivedToBase)
47708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
47808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  else
47908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
48008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
48108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
48208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner}
48308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
48408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattnerllvm::Constant *
48508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris LattnerItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
48608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  // Itanium C++ ABI 2.3:
48708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  //   A NULL pointer is represented as -1.
48808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  if (MPT->isMemberDataPointer())
48908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);
49008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
49108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
49208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  llvm::Constant *Values[2] = { Zero, Zero };
49308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  return llvm::ConstantStruct::getAnon(Values);
49408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner}
49508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
49608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattnerllvm::Constant *
49708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris LattnerItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
49808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                                     CharUnits offset) {
49908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  // Itanium C++ ABI 2.3:
50008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  //   A pointer to data member is an offset from the base address of
50108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  //   the class object containing it, represented as a ptrdiff_t
50208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
50308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner}
50408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
50508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattnerllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
50608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  return BuildMemberPointer(MD, CharUnits::Zero());
50708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner}
50808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
50908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattnerllvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
51008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                                                  CharUnits ThisAdjustment) {
51108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  assert(MD->isInstance() && "Member function must not be static!");
51208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  MD = MD->getCanonicalDecl();
51308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
51408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  CodeGenTypes &Types = CGM.getTypes();
51508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
51608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  // Get the function pointer (or index if this is a virtual function).
51708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  llvm::Constant *MemPtr[2];
51808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner  if (MD->isVirtual()) {
51908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
52008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
52108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    const ASTContext &Context = getContext();
52208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    CharUnits PointerWidth =
52308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
52408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    uint64_t VTableOffset = (Index * PointerWidth.getQuantity());
52508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
52608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    if (IsARM) {
52708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // ARM C++ ABI 3.2.1:
52808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   This ABI specifies that adj contains twice the this
52908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   adjustment, plus 1 if the member function is virtual. The
53008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   least significant bit of adj then makes exactly the same
53108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   discrimination as the least significant bit of ptr does for
53208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   Itanium.
53308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
53408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
53508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                                         2 * ThisAdjustment.getQuantity() + 1);
53608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    } else {
53708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      // Itanium C++ ABI 2.3:
53808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   For a virtual function, [the pointer field] is 1 plus the
53908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   virtual table offset (in bytes) of the function,
54008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      //   represented as a ptrdiff_t.
5415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                         ThisAdjustment.getQuantity());
5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
5462de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
5472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::Type *Ty;
5482de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    // Check whether the function has a computable LLVM signature.
5492de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (Types.isFuncTypeConvertible(FPT)) {
5502de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      // The function has a computable LLVM signature; use the correct type.
5512de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
5522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    } else {
5532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      // Use an arbitrary non-function type to tell GetAddrOfFunction that the
5542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      // function type is incomplete.
5552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      Ty = CGM.PtrDiffTy;
5562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
5572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
5582de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, (IsARM ? 2 : 1) *
5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                       ThisAdjustment.getQuantity());
5622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
563bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
564bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  return llvm::ConstantStruct::getAnon(MemPtr);
565bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor}
5662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
5672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
5682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                                 QualType MPType) {
5692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();
5702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  const ValueDecl *MPD = MP.getMemberPointerDecl();
5712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (!MPD)
5722de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    return EmitNullMemberPointer(MPT);
5732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
574bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
575bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
576bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
577bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor    return BuildMemberPointer(MD, ThisAdjustment);
578bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
5792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  CharUnits FieldOffset =
5802de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
5812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
5822de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
5832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
5842de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// The comparison algorithm is pretty easy: the member pointers are
5852de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// the same if they're either bitwise identical *or* both null.
5862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall///
587bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor/// ARM is different here only because null-ness is more complicated.
588bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregorllvm::Value *
589bc736fceca6f0bca31d16003a7587857190408fbDouglas GregorItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
590bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor                                           llvm::Value *L,
591bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor                                           llvm::Value *R,
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           const MemberPointerType *MPT,
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           bool Inequality) {
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  CGBuilderTy &Builder = CGF.Builder;
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
596668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  llvm::ICmpInst::Predicate Eq;
597f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  llvm::Instruction::BinaryOps And, Or;
598f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  if (Inequality) {
599f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Eq = llvm::ICmpInst::ICMP_NE;
600898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    And = llvm::Instruction::Or;
601d603eaa682cecac2c10771a700cb83aa301653b4Chris Lattner    Or = llvm::Instruction::And;
602898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  } else {
6031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Eq = llvm::ICmpInst::ICMP_EQ;
604668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek    And = llvm::Instruction::And;
605b4609806e9232593ece09ce08b630836e825865cDouglas Gregor    Or = llvm::Instruction::Or;
606b4609806e9232593ece09ce08b630836e825865cDouglas Gregor  }
607b4609806e9232593ece09ce08b630836e825865cDouglas Gregor
608668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  // Member data pointers are easy because there's a unique null
609b4609806e9232593ece09ce08b630836e825865cDouglas Gregor  // value, so it just comes down to bitwise equality.
610b4609806e9232593ece09ce08b630836e825865cDouglas Gregor  if (MPT->isMemberDataPointer())
611e2ce1d9440186cf3332368291cd884a6e3ae8946Nate Begeman    return Builder.CreateICmp(Eq, L, R);
612668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek
613f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // For member function pointers, the tautologies are more complex.
614f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // The Itanium tautology is:
615898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
616d603eaa682cecac2c10771a700cb83aa301653b4Chris Lattner  // The ARM tautology is:
617898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  //   (L == R) <==> (L.ptr == R.ptr &&
618668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  //                  (L.adj == R.adj ||
619668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
62077ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek  // The inequality tautologies have exactly the same structure, except
6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // applying De Morgan's laws.
62277ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
623668bf91d31265b6ea8c3eb854ba450857701f269Ted Kremenek  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // This condition tests whether L.ptr == R.ptr.  This must always be
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // true for equality to hold.
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
6291f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor
6301f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor  // This condition, together with the assumption that L.ptr == R.ptr,
6311f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor  // tests whether the pointers are both null.  ARM imposes an extra
632d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  // condition.
633a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu  llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
634200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
635200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl
636200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  // This condition tests whether L.adj == R.adj.  If this isn't
637200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  // true, the pointers are unequal unless they're both null.
638200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
639200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
640200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
641200121569dc6cff10a1fb6ed7500098770b9dd25Sebastian Redl
6426346f963145ed18b6edf50a78753b47db505e912Chris Lattner  // Null member function pointers on ARM clear the low bit of Adj,
643d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  // so the zero condition has to check that neither low bit is set.
644cb1c77f90d4e747b83a0d0cc125dc01567378f82Nuno Lopes  if (IsARM) {
645cb1c77f90d4e747b83a0d0cc125dc01567378f82Nuno Lopes    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
646a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu
647a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu    // Compute (l.adj | r.adj) & 1 and test it against zero.
648a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
649a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
650d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
651caabf9bf331156e96dacb072385901fdfa057ec1Chris Lattner                                                      "cmp.or.adj");
652d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes    EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
653d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes  }
654d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
655d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  // Tie together all our conditions.
656d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
6578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  Result = Builder.CreateBinOp(And, PtrEq, Result,
658d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner                               Inequality ? "memptr.ne" : "memptr.eq");
659d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  return Result;
6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
661d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
662d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattnerllvm::Value *
663d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris LattnerItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
664d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner                                          llvm::Value *MemPtr,
665d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner                                          const MemberPointerType *MPT) {
666d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  CGBuilderTy &Builder = CGF.Builder;
667d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
66868a049cab6015a7437bec5661601b7d37d23c70cDaniel Dunbar  /// For member data pointers, this is just a check against -1.
669d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  if (MPT->isMemberDataPointer()) {
670d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    assert(MemPtr->getType() == CGM.PtrDiffTy);
671d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    llvm::Value *NegativeOne =
672d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner      llvm::Constant::getAllOnesValue(MemPtr->getType());
673d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner    return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
674d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  }
6751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67688c9a46f0b84f1ee83e01917825346551ee540d0Douglas Gregor  // In Itanium, a member function pointer is not null if 'ptr' is not null.
677d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
678d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
679d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
680d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner  llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
681cb888967400a03504c88acedd5248d6778a82f46Chris Lattner
682cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  // On ARM, a member function pointer is also non-null if the low bit of 'adj'
6833c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor  // (the virtual bit) is set.
684c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff  if (IsARM) {
6851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
686c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
687c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
688c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff    llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
689cb888967400a03504c88acedd5248d6778a82f46Chris Lattner                                                  "memptr.isvirtual");
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Result = Builder.CreateOr(Result, IsVirtual);
691c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff  }
692c4f8e8b645b8e0e685c089dde0674c6f29a24168Steve Naroff
693cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  return Result;
6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
695bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlsson
696bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlsson/// The Itanium ABI requires non-zero initialization only for data
697cb888967400a03504c88acedd5248d6778a82f46Chris Lattner/// member pointers, for which '0' is a valid offset.
6981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
6994fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor  return MPT->getPointeeType()->isFunctionType();
7004fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor}
7014fcd399a52ae45ed8ebfdd3a25e01cfb76fa366dDouglas Gregor
7027814e6d6645d587891293d59ecf6576defcfac92Douglas Gregor/// The Itanium ABI always places an offset to the complete object
703cb888967400a03504c88acedd5248d6778a82f46Chris Lattner/// at entry -2 in the vtable.
704bcba201a1118d7852b8b97187d495ae2a4f49519Anders Carlssonllvm::Value *ItaniumCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
7056dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                                                   llvm::Value *ptr,
7066dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                                                   QualType type) {
7076217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  // Grab the vtable pointer as an intptr_t*.
7086dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson  llvm::Value *vtable = CGF.GetVTablePtr(ptr, CGF.IntPtrTy->getPointerTo());
7096217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek
7106dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson  // Track back to entry -2 and pull out the offset there.
7115291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  llvm::Value *offsetPtr =
7125291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor    CGF.Builder.CreateConstInBoundsGEP1_64(vtable, -2, "complete-offset.ptr");
7135291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  llvm::LoadInst *offset = CGF.Builder.CreateLoad(offsetPtr);
7145291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  offset->setAlignment(CGF.PointerAlignInBytes);
715183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall
7166dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson  // Apply the offset.
7176dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson  ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy);
718cb888967400a03504c88acedd5248d6778a82f46Chris Lattner  return CGF.Builder.CreateInBoundsGEP(ptr, offset);
719c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt}
7208ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
721c302113179a1c2b1254224ea9b6f5316ceeb375cSean Huntllvm::Value *
722c302113179a1c2b1254224ea9b6f5316ceeb375cSean HuntItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
7238ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                         llvm::Value *This,
7248ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                         const CXXRecordDecl *ClassDecl,
7258ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                         const CXXRecordDecl *BaseClassDecl) {
726c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy);
7278ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  CharUnits VBaseOffsetOffset =
7288ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl);
7298ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7308ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  llvm::Value *VBaseOffsetPtr =
7318ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(),
7328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                   "vbase.offset.ptr");
7338ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr,
7348ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                             CGM.PtrDiffTy->getPointerTo());
7358ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7368ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  llvm::Value *VBaseOffset =
7378ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    CGF.Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
7388ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7398ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  return VBaseOffset;
7408ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
741c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
7428ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor/// The generic ABI passes 'this', plus a VTT if it's initializing a
743c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt/// base subobject.
7448ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
7458ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                              CXXCtorType Type,
746f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                              CanQualType &ResTy,
747f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                SmallVectorImpl<CanQualType> &ArgTys) {
7488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ASTContext &Context = getContext();
7498ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7508ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // 'this' parameter is already there, as well as 'this' return if
751c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // HasThisReturn(GlobalDecl(Ctor, Type)) is true
752c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
7538ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // Check if we need to add a VTT parameter (which has type void **).
7548ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
7558ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
7568ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
757c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
7588ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor/// The generic ABI passes 'this', plus a VTT if it's destroying a
7598ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor/// base subobject.
7608ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
7618ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                             CXXDtorType Type,
7628ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                             CanQualType &ResTy,
7638ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                SmallVectorImpl<CanQualType> &ArgTys) {
7648ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ASTContext &Context = getContext();
7658ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7668ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // 'this' parameter is already there, as well as 'this' return if
767c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // HasThisReturn(GlobalDecl(Dtor, Type)) is true
7688ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
7698ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // Check if we need to add a VTT parameter (which has type void **).
7708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)
7711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
7721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
77383f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor
774f595cc41c4d95fe323f8a2b209523de9956f874dEli Friedmanvoid ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
775161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // The destructor in a virtual table is always a 'deleting'
7762577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  // destructor, which calls the complete destructor and then uses the
777d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  // appropriate operator delete.
778f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  if (D->isVirtual())
779f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));
780f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
78183f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor  // The destructor used for destructing this as a most-derived class;
7826bb8017bb9e828d118e15e59d71c66bba323c364John McCall  // call the base destructor and then destructs any virtual bases.
783161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
784161755a09898c95d21bfff33707da9ca41cd53c5John McCall
785161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // The destructor used for destructing this as a base class; ignores
7866bb8017bb9e828d118e15e59d71c66bba323c364John McCall  // virtual bases.
7876bb8017bb9e828d118e15e59d71c66bba323c364John McCall  CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
7881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
789d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
790d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallvoid ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
7911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                QualType &ResTy,
7923248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner                                                FunctionArgList &Params) {
793f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  /// Create the 'this' variable.
794f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  BuildThisParam(CGF, Params);
7956bb8017bb9e828d118e15e59d71c66bba323c364John McCall
7966bb8017bb9e828d118e15e59d71c66bba323c364John McCall  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
7976bb8017bb9e828d118e15e59d71c66bba323c364John McCall  assert(MD->isInstance());
7986bb8017bb9e828d118e15e59d71c66bba323c364John McCall
7996bb8017bb9e828d118e15e59d71c66bba323c364John McCall  // Check if we need a VTT parameter as well.
8006bb8017bb9e828d118e15e59d71c66bba323c364John McCall  if (NeedsVTTParameter(CGF.CurGD)) {
8016bb8017bb9e828d118e15e59d71c66bba323c364John McCall    ASTContext &Context = getContext();
8026bb8017bb9e828d118e15e59d71c66bba323c364John McCall
8036bb8017bb9e828d118e15e59d71c66bba323c364John McCall    // FIXME: avoid the fake decl
8046bb8017bb9e828d118e15e59d71c66bba323c364John McCall    QualType T = Context.getPointerType(Context.VoidPtrTy);
8056bb8017bb9e828d118e15e59d71c66bba323c364John McCall    ImplicitParamDecl *VTTDecl
8066bb8017bb9e828d118e15e59d71c66bba323c364John McCall      = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
8076bb8017bb9e828d118e15e59d71c66bba323c364John McCall                                  &Context.Idents.get("vtt"), T);
8086bb8017bb9e828d118e15e59d71c66bba323c364John McCall    Params.push_back(VTTDecl);
8096bb8017bb9e828d118e15e59d71c66bba323c364John McCall    getVTTDecl(CGF) = VTTDecl;
8106bb8017bb9e828d118e15e59d71c66bba323c364John McCall  }
811096832c5ed5b9106fa177ebc148489760c3bc496John McCall}
8126bb8017bb9e828d118e15e59d71c66bba323c364John McCall
8136bb8017bb9e828d118e15e59d71c66bba323c364John McCallvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
8146bb8017bb9e828d118e15e59d71c66bba323c364John McCall  /// Initialize the 'this' slot.
81583f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor  EmitThisParam(CGF);
81683f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor
817f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  /// Initialize the 'vtt' slot if needed.
818f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  if (getVTTDecl(CGF)) {
819daa8e4e888758d55a7a759dd4a91b83921cef222John McCall    getVTTValue(CGF)
820daa8e4e888758d55a7a759dd4a91b83921cef222John McCall      = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
8212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                               "vtt");
822f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  }
8232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
824e39a3894513349908cdb3beba2614e53cb288e6cDouglas Gregor  /// If this is a function that the ABI specifies returns 'this', initialize
8252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  /// the return slot to 'this' at the start of the function.
826f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  ///
8272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  /// Unlike the setting of return types, this is done within the ABI
82811de6de25a0110cd7be97eef761ef3b189781da6Anders Carlsson  /// implementation instead of by clients of CGCXXABI because:
8292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  /// 1) getThisValue is currently protected
830f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  /// 2) in theory, an ABI could implement 'this' returns some other way;
8312de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  ///    HasThisReturn only specifies a contract, not the implementation
83223cba801e11b03929c44f8cf54578305963a3476John McCall  if (HasThisReturn(CGF.CurGD))
8332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
834f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson}
8352de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
836f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlssonvoid ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
8372de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                        const CXXConstructorDecl *D,
838f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                                        CXXCtorType Type,
8392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                        bool ForVirtualBase, bool Delegating,
840f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                                        llvm::Value *This,
8412de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                        CallExpr::const_arg_iterator ArgBeg,
842f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
843404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall  llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase,
844404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall                                         Delegating);
8452de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
846f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
8472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
8481a31a18db9d657751f38c724adc0d62e86852bd7Anders Carlsson  // FIXME: Provide a source location here.
8492de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(),
850f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson                        This, VTT, VTTTy, ArgBeg, ArgEnd);
8512de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
852f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson
8532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallvoid ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
8547f9e646b7ed47bc8e9a60031ad0c2b55031e2077Anders Carlsson                                              const CXXDestructorDecl *Dtor,
8552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                              CXXDtorType DtorType,
8567f9e646b7ed47bc8e9a60031ad0c2b55031e2077Anders Carlsson                                              SourceLocation CallLoc,
857daa8e4e888758d55a7a759dd4a91b83921cef222John McCall                                              llvm::Value *This) {
858daa8e4e888758d55a7a759dd4a91b83921cef222John McCall  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
8592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
860ebeaf2031c968143c531bfe232d7507f20c57347Anders Carlsson  const CGFunctionInfo *FInfo
8612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType);
86216a8904f3f5ed19158657e1da95e5902fbee66f7Anders Carlsson  llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
8632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Value *Callee
86482debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlsson    = CGF.BuildVirtualCall(GlobalDecl(Dtor, DtorType), This, Ty);
865daa8e4e888758d55a7a759dd4a91b83921cef222John McCall
866daa8e4e888758d55a7a759dd4a91b83921cef222John McCall  CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This,
8672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                        /*ImplicitParam=*/0, QualType(), 0, 0);
86882debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlsson}
8692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
87082debc7d282e723e58d183bfa89ddc2500a8daafAnders Carlssonvoid ItaniumCXXABI::EmitVirtualInheritanceTables(
8712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD) {
872c6b29163557d02da5d2a4a06f986f0480291f51fBenjamin Kramer  CodeGenVTables &VTables = CGM.getVTables();
873daa8e4e888758d55a7a759dd4a91b83921cef222John McCall  llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD);
874daa8e4e888758d55a7a759dd4a91b83921cef222John McCall  VTables.EmitVTTDefinition(VTT, Linkage, RD);
8752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
876bc0e0781da778bd5eb41a810419912893ae20448Anders Carlsson
8772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
8784cbf9d43cc47bb7a070c5c5026521d7d6a8f73c7Fariborz Jahanian                                    RValue RV, QualType ResultType) {
8792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
8803b27f1a80e4e433b503efd344c909eeafaa9033cFariborz Jahanian    return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
8812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
882569c3166874324c24011f8ade6978421f0d39b3cDouglas Gregor  // Destructor thunks in the ARM ABI have indeterminate results.
8832bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall  llvm::Type *T =
8842bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall    cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType();
885f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall  RValue Undef = RValue::get(llvm::UndefValue::get(T));
886f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall  return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
887f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall}
888f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall
8892bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall/************************** Array allocation cookies **************************/
8902bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall
891f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCallCharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
892f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall  // The array cookie is a size_t; pad that up to the element alignment.
8932bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall  // The cookie is actually right-justified in that space.
8942bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall  return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
895f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall                  CGM.getContext().getTypeAlignInChars(elementType));
896f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall}
897f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall
898f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCallllvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
8992bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall                                                  llvm::Value *NewPtr,
9002bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall                                                  llvm::Value *NumElements,
901f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall                                                  const CXXNewExpr *expr,
902f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall                                                  QualType ElementType) {
903f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  assert(requiresArrayCookie(expr));
9041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9052bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall  unsigned AS = NewPtr->getType()->getPointerAddressSpace();
906f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson
907f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  ASTContext &Ctx = getContext();
908f8ec55a104e55961f8666f773dce99bbc628298fAnders Carlsson  QualType SizeTy = Ctx.getSizeType();
9096eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy);
9106eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
9116eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  // The size of the cookie.
9126eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  CharUnits CookieSize =
9136eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
914c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  assert(CookieSize == getArrayCookieSizeImpl(ElementType));
9156eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
9166eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  // Compute an offset to the cookie.
9176eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  llvm::Value *CookiePtr = NewPtr;
918c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  CharUnits CookieOffset = CookieSize - SizeSize;
9196eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  if (!CookieOffset.isZero())
9206eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr,
9212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                                 CookieOffset.getQuantity());
9226eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
9232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // Write the number of elements into the appropriate slot.
9246eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  llvm::Value *NumElementsPtr
925c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    = CGF.Builder.CreateBitCast(CookiePtr,
9266eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
9276eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
928c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
929c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // Finally, compute a pointer to the actual data buffer by skipping
9306eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  // over the cookie completely.
9316eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
9326eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                                                CookieSize.getQuantity());
933f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall}
934f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
935f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallllvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
936f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                                llvm::Value *allocPtr,
937f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                                CharUnits cookieSize) {
938f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // The element size is right-justified in the cookie.
939f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  llvm::Value *numElementsPtr = allocPtr;
940f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  CharUnits numElementsOffset =
941f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    cookieSize - CharUnits::fromQuantity(CGF.SizeSizeInBytes);
942f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  if (!numElementsOffset.isZero())
943f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    numElementsPtr =
944f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall      CGF.Builder.CreateConstInBoundsGEP1_64(numElementsPtr,
945f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                             numElementsOffset.getQuantity());
946f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
947f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  unsigned AS = allocPtr->getType()->getPointerAddressSpace();
948f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  numElementsPtr =
949f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
950f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  return CGF.Builder.CreateLoad(numElementsPtr);
951f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall}
952f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
953f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallCharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
954f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // ARM says that the cookie is always:
9555baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall  //   struct array_cookie {
956f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  //     std::size_t element_size; // element_size != 0
957f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  //     std::size_t element_count;
958f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  //   };
959f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // But the base ABI doesn't give anything an alignment greater than
9605baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall  // 8, so we can dismiss this as typical ABI-author blindness to
961f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // actual language complexity and round up to the element alignment.
962f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),
963f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                  CGM.getContext().getTypeAlignInChars(elementType));
964f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall}
965f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
966f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallllvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
967f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                              llvm::Value *newPtr,
968f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                              llvm::Value *numElements,
969f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                              const CXXNewExpr *expr,
970f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                              QualType elementType) {
971f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  assert(requiresArrayCookie(expr));
972f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
973f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // NewPtr is a char*, but we generalize to arbitrary addrspaces.
974f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  unsigned AS = newPtr->getType()->getPointerAddressSpace();
975f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
976f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // The cookie is always at the start of the buffer.
977f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  llvm::Value *cookie = newPtr;
978f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
979f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // The first element is the element size.
980f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  cookie = CGF.Builder.CreateBitCast(cookie, CGF.SizeTy->getPointerTo(AS));
981f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,
982f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                 getContext().getTypeSizeInChars(elementType).getQuantity());
983f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  CGF.Builder.CreateStore(elementSize, cookie);
984f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
985f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // The second element is the element count.
986f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  cookie = CGF.Builder.CreateConstInBoundsGEP1_32(cookie, 1);
987f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  CGF.Builder.CreateStore(numElements, cookie);
988f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
989f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // Finally, compute a pointer to the actual data buffer by skipping
990f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  // over the cookie completely.
991f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
992f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
9935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                                cookieSize.getQuantity());
9945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
9955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
9965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerllvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
9972de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                            llvm::Value *allocPtr,
9982de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                            CharUnits cookieSize) {
9992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // The number of elements is at offset sizeof(size_t) relative to
10002de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // the allocated pointer.
10012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Value *numElementsPtr
10022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    = CGF.Builder.CreateConstInBoundsGEP1_64(allocPtr, CGF.SizeSizeInBytes);
10032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  unsigned AS = allocPtr->getType()->getPointerAddressSpace();
10052de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  numElementsPtr =
10062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
10072de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return CGF.Builder.CreateLoad(numElementsPtr);
10082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
10092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/*********************** Static local initialization **************************/
10112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10122de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
10132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                         llvm::PointerType *GuardPtrTy) {
10142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // int __cxa_guard_acquire(__guard *guard_object);
10152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::FunctionType *FTy =
10162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
10172de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                            GuardPtrTy, /*isVarArg=*/false);
10182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire",
10192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
10202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                              llvm::AttributeSet::FunctionIndex,
10212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                                 llvm::Attribute::NoUnwind));
10222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
10232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
10252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                         llvm::PointerType *GuardPtrTy) {
10262de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // void __cxa_guard_release(__guard *guard_object);
10272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::FunctionType *FTy =
10282de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
10295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release",
1030baf534875ed0a55c6342636ff3f4602b8ac22b69Douglas Gregor                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
1031baf534875ed0a55c6342636ff3f4602b8ac22b69Douglas Gregor                                              llvm::AttributeSet::FunctionIndex,
10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                                 llvm::Attribute::NoUnwind));
10335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
10342de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
1035063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregorstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
1036063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor                                       llvm::PointerType *GuardPtrTy) {
1037b7beee9f2b52f34a3b0800a5f0038f0e4295b260Chris Lattner  // void __cxa_guard_abort(__guard *guard_object);
10382de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::FunctionType *FTy =
10392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
10402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort",
10412de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                   llvm::AttributeSet::get(CGM.getLLVMContext(),
10422de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                              llvm::AttributeSet::FunctionIndex,
10432de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                                 llvm::Attribute::NoUnwind));
10442de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
10452de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10462de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallnamespace {
10472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  struct CallGuardAbort : EHScopeStack::Cleanup {
10482de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::GlobalVariable *Guard;
10492de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
10502de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10512de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
10522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
10532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                  Guard);
10542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    }
10552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  };
10562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
10572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10582de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// The ARM code here follows the Itanium code closely enough that we
10592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall/// just special-case it at particular places.
10602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
10612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                    const VarDecl &D,
10622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                    llvm::GlobalVariable *var,
10632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                    bool shouldPerformInit) {
10642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  CGBuilderTy &Builder = CGF.Builder;
10652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
10662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // We only need to use thread-safe statics for local non-TLS variables;
10672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // global initialization is always single-threaded.
10682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
1069063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor                    D.isLocalVarDecl() && !D.getTLSKind();
1070063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1071063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  // If we have a global variable with internal linkage and thread-safe statics
1072063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  // are disabled, we can just let the guard variable be of type i8.
1073063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1074063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1075063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  llvm::IntegerType *guardTy;
1076063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  if (useInt8GuardVariable) {
1077063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    guardTy = CGF.Int8Ty;
1078063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  } else {
1079063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    // Guard variables are 64 bits in the generic ABI and size width on ARM
1080063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    // (i.e. 32-bit on AArch32, 64-bit on AArch64).
1081063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    guardTy = (IsARM ? CGF.SizeTy : CGF.Int64Ty);
1082063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  }
1083063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1084063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor
1085063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  // Create the guard variable if we don't already have it (as we
1086063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  // might if we're double-emitting this function body).
1087063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1088063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor  if (!guard) {
1089063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    // Mangle the name for the guard.
1090063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    SmallString<256> guardName;
1091063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    {
1092063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor      llvm::raw_svector_ostream out(guardName);
1093063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor      getMangleContext().mangleItaniumGuardVariable(&D, out);
1094063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor      out.flush();
1095063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor    }
1096709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek
1097418f6c7d142e5ff4607f70cd8431d008442bafe9Chris Lattner    // Create the guard variable with a zero-initializer.
10984c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    // Just absorb linkage and visibility from the guarded variable.
1099f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
1100709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek                                     false, var->getLinkage(),
11011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     llvm::ConstantInt::get(guardTy, 0),
1102c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                     guardName.str());
1103c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    guard->setVisibility(var->getVisibility());
1104ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    // If the variable is thread-local, so is its guard variable.
1105ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    guard->setThreadLocalMode(var->getThreadLocalMode());
11068e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1107ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    CGM.setStaticLocalDeclGuardAddress(&D, guard);
11088e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  }
110973460a32bc5299a5927d23d2e464d72af796eabfDouglas Gregor
1110c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // Test whether the variable has completed initialization.
1111709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  llvm::Value *isInitialized;
111266b5a8a39088598c01a9fa6f032dc908612dc8ecAnders Carlsson
11135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // ARM C++ ABI 3.2.3.1:
1114709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  //   To support the potential use of initialization guard variables
1115ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek  //   as semaphores that are the target of ARM SWP and LDREX/STREX
1116709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  //   synchronizing instructions we define a static initialization
1117fa2192042f223b5122a9e17719930f77634fd31fDouglas Gregor  //   guard variable to be a 4-byte aligned, 4- byte word with the
1118fa2192042f223b5122a9e17719930f77634fd31fDouglas Gregor  //   following inline access protocol.
1119709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  //     #define INITIALIZED 1
1120709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
11214c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //       if (__cxa_guard_acquire(&obj_guard))
11224c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //         ...
1123709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek  //     }
1124ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek  if (IsARM && !useInt8GuardVariable) {
1125709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek    llvm::Value *V = Builder.CreateLoad(guard);
1126ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1);
1127ba7bc5584b8d46f4e8deb3a9d363256908fa86eaTed Kremenek    V = Builder.CreateAnd(V, Test1);
11284c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
11291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11304c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  // Itanium C++ ABI 3.3.2:
11314c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //   The following is pseudo-code showing how these functions can be used:
11324c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //     if (obj_guard.first_byte == 0) {
11334c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //       if ( __cxa_guard_acquire (&obj_guard) ) {
11344c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor  //         try {
1135c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //           ... initialize the object ...;
1136c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //         } catch (...) {
1137c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //            __cxa_guard_abort (&obj_guard);
1138c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //            throw;
1139c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //         }
1140c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //         ... queue object destructor with __cxa_atexit() ...;
1141c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //         __cxa_guard_release (&obj_guard);
1142c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //       }
1143c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  //     }
1144c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  } else {
1145c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    // Load the first byte of the guard variable.
1146c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    llvm::LoadInst *LI =
1147c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek      Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
1148c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    LI->setAlignment(1);
1149c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1150c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    // Itanium ABI:
1151c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    //   An implementation supporting thread-safety on multiprocessor
1152c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    //   systems must also guarantee that references to the initialized
1153c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    //   object do not occur before the load of the initialization flag.
1154c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    //
1155c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    // In LLVM, we do this by marking the load Acquire.
1156c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    if (threadsafe)
1157c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek      LI->setAtomic(llvm::Acquire);
1158c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1159c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek    isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
1160c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  }
1161c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek
1162c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
1163c4ba51f365a3cd3374b3ef87272a9b3e517cd5d3Ted Kremenek  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
1164bfdcae678d44906293e21c0cddc6537f3ee8b5a4Steve Naroff
11654eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  // Check if the first byte of the guard variable is zero.
11664eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
11676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek
1168183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  CGF.EmitBlock(InitCheckBlock);
11694eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff
11704eb206bebcdab28ababe8df55c6185cec2cdc071Steve Naroff  // Variables used when coping with thread-safe statics and exceptions.
11711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (threadsafe) {
11721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Call __cxa_guard_acquire.
117356ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff    llvm::Value *V
11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
11757297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor
11767297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor    llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
11771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
11797297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor                         InitBlock, EndBlock);
118056ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff
118156ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff    // Call __cxa_guard_abort along the exceptional edge.
11825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
11835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CGF.EmitBlock(InitBlock);
11855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1186026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1187026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // Emit the initializer and add a global destructor if appropriate.
1188026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
1189026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1190026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (threadsafe) {
1191df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    // Pop the guard-abort cleanup if we pushed one.
1192ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson    CGF.PopCleanupBlock();
1193ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson
1194ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson    // Call __cxa_guard_release.  This cannot throw.
1195ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson    CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
11961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  } else {
11975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
11985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
11990faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall
12000faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall  CGF.EmitBlock(EndBlock);
1201026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1202026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1203026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner/// Register a global destructor using __cxa_atexit.
12045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
1205026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                                        llvm::Constant *dtor,
1206df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump                                        llvm::Constant *addr,
12075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                        bool TLS) {
12085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *Name = "__cxa_atexit";
12091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (TLS) {
12105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const llvm::Triple &T = CGF.getTarget().getTriple();
1211026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    Name = T.isMacOSX() ?  "_tlv_atexit" : "__cxa_thread_atexit";
12122de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  }
12132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
12142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // We're assuming that the destructor function is something we can
12152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  // reasonably call with the default CC.  Go ahead and cast it to the
1216026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // right prototype.
12172de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::Type *dtorTy =
12185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
1219df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump
1220026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
1221026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
12222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  llvm::FunctionType *atexitTy =
12232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    llvm::FunctionType::get(CGF.IntTy, paramTys, false);
12245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1225df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  // Fetch the actual function.
1226df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  llvm::Constant *atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);
1227026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
1228026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    fn->setDoesNotThrow();
12292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
1230df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  // Create a variable that binds the atexit to this shared object.
12315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::Constant *handle =
1232026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
1233026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1234026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm::Value *args[] = {
12355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    llvm::ConstantExpr::getBitCast(dtor, dtorTy),
1236e7716e6133e23e4a89248a65a388bc840d8c130cChris Lattner    llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
1237026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    handle
1238c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  };
1239c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  CGF.EmitNounwindRuntimeCall(atexit, args);
1240c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek}
124125973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis
124225973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis/// Register a global destructor as best as we know how.
12432de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCallvoid ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
1244c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek                                       const VarDecl &D,
1245c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek                                       llvm::Constant *dtor,
1246c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek                                       llvm::Constant *addr) {
1247c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  // Use __cxa_atexit if available.
1248c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek  if (CGM.getCodeGenOpts().CXAAtExit)
1249c46a246f5fb00bf8448a1081e7d7e73bb6dbfbf5Ted Kremenek    return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind());
125025973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis
125125973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis  if (D.getTLSKind())
12522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
12532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
125425973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis  // In Apple kexts, we want to add a global destructor entry.
125525973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis  // FIXME: shouldn't this be guarded by some variable?
125625973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis  if (CGM.getLangOpts().AppleKext) {
125725973455aed1cdc9c40b208c792b5db4f8f1297dArgyrios Kyrtzidis    // Generate a global destructor entry.
1258bf0ee354163f87623a4b60412544243911332343John McCall    return CGM.AddCXXDtorEntry(dtor, addr);
1259026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1260026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1261026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  CGF.registerGlobalDtorWithAtExit(dtor, addr);
1262026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
1263026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1264026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner/// Get the appropriate linkage for the wrapper function. This is essentially
1265e7716e6133e23e4a89248a65a388bc840d8c130cChris Lattner/// the weak form of the variable's linkage; every translation unit which wneeds
1266eb14fe839ec24c2ca14e5f094be147a34e3d3339Chris Lattner/// the wrapper emits a copy, and we want the linker to merge them.
1267c6dfe194f623b02c123759f235b504d4850fc178Douglas Gregorstatic llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(
1268026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    llvm::GlobalValue::LinkageTypes VarLinkage) {
12695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (llvm::GlobalValue::isLinkerPrivateLinkage(VarLinkage))
1270ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian    return llvm::GlobalValue::LinkerPrivateWeakLinkage;
1271026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // For internal linkage variables, we don't need an external or weak wrapper.
1272026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
1273ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian    return VarLinkage;
12741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return llvm::GlobalValue::WeakODRLinkage;
1275df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump}
1276026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1277df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stumpllvm::Function *
1278ab38e4b50268633f037a10841fdfb612513f8d33Fariborz JahanianItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
1279ab38e4b50268633f037a10841fdfb612513f8d33Fariborz Jahanian                                             llvm::GlobalVariable *Var) {
12805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Mangle the name for the thread_local wrapper function.
1281026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  SmallString<256> WrapperName;
1282026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  {
1283df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    llvm::raw_svector_ostream Out(WrapperName);
1284026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
1285026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    Out.flush();
1286026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
1287026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1288026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (llvm::Value *V = Var->getParent()->getNamedValue(WrapperName))
12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return cast<llvm::Function>(V);
12905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::Type *RetTy = Var->getType();
1292026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (VD->getType()->isReferenceType())
1293df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    RetTy = RetTy->getPointerElementType();
1294026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1295026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
1296026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm::Function *Wrapper = llvm::Function::Create(
1297026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      FnTy, getThreadLocalWrapperLinkage(Var->getLinkage()), WrapperName.str(),
1298026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      &CGM.getModule());
1299211f6adf1301a1461015fb6cb08a05f0a35b65f3Eli Friedman  // Always resolve references to the wrapper at link time.
13005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
1301852871abbff45f1c1d3787755a27fce08365b166Eli Friedman  return Wrapper;
1302852871abbff45f1c1d3787755a27fce08365b166Eli Friedman}
1303026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1304026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnervoid ItaniumCXXABI::EmitThreadLocalInitFuncs(
1305d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes    llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
1306026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    llvm::Function *InitFunc) {
1307026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
1308bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    const VarDecl *VD = Decls[I].first;
1309bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    llvm::GlobalVariable *Var = Decls[I].second;
1310bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner
1311bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    // Mangle the name for the thread_local initialization function.
1312bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    SmallString<256> InitFnName;
1313bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    {
1314bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      llvm::raw_svector_ostream Out(InitFnName);
1315bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
1316bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner      Out.flush();
1317bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    }
1318bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner
1319bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    // If we have a definition for the variable, emit the initialization
1320bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner    // function as an alias to the global Init function (if any). Otherwise,
1321026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    // produce a declaration of the initialization function.
1322026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    llvm::GlobalValue *Init = 0;
1323026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    bool InitIsInitFunc = false;
132458beed91d468863b8c85bce43425422703838d27Anders Carlsson    if (VD->hasDefinition()) {
132558beed91d468863b8c85bce43425422703838d27Anders Carlsson      InitIsInitFunc = true;
132658beed91d468863b8c85bce43425422703838d27Anders Carlsson      if (InitFunc)
132758beed91d468863b8c85bce43425422703838d27Anders Carlsson        Init =
132858beed91d468863b8c85bce43425422703838d27Anders Carlsson            new llvm::GlobalAlias(InitFunc->getType(), Var->getLinkage(),
1329f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian                                  InitFnName.str(), InitFunc, &CGM.getModule());
1330f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian    } else {
1331f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      // Emit a weak global function referring to the initialization function.
1332f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      // This function will not exist if the TU defining the thread_local
1333f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      // variable in question does not need any dynamic initialization for
1334f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      // its thread_local variables.
1335f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian      llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
1336026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      Init = llvm::Function::Create(
1337f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian          FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
13381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          &CGM.getModule());
133909105f52b1f28cbb1374c27c3c70f5517e2c465dFariborz Jahanian    }
1340a50089ec68a583d13718107c1b0c898f0903709eChris Lattner
13411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (Init)
134209105f52b1f28cbb1374c27c3c70f5517e2c465dFariborz Jahanian      Init->setVisibility(Var->getVisibility());
1343a50089ec68a583d13718107c1b0c898f0903709eChris Lattner
1344154440e6a8fa6ac5bca395876d79b530b39a2c1cFariborz Jahanian    llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
1345154440e6a8fa6ac5bca395876d79b530b39a2c1cFariborz Jahanian    llvm::LLVMContext &Context = CGM.getModule().getContext();
1346154440e6a8fa6ac5bca395876d79b530b39a2c1cFariborz Jahanian    llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);
1347154440e6a8fa6ac5bca395876d79b530b39a2c1cFariborz Jahanian    CGBuilderTy Builder(Entry);
13485e94a0d82b1f49be41c35a73106b219e3f588c8cChris Lattner    if (InitIsInitFunc) {
13495e94a0d82b1f49be41c35a73106b219e3f588c8cChris Lattner      if (Init)
13505e94a0d82b1f49be41c35a73106b219e3f588c8cChris Lattner        Builder.CreateCall(Init);
1351a50089ec68a583d13718107c1b0c898f0903709eChris Lattner    } else {
1352a50089ec68a583d13718107c1b0c898f0903709eChris Lattner      // Don't know whether we have an init function. Call it if it exists.
1353a50089ec68a583d13718107c1b0c898f0903709eChris Lattner      llvm::Value *Have = Builder.CreateIsNotNull(Init);
1354611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
1355611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
1356611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Builder.CreateCondBr(Have, InitBB, ExitBB);
1357611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner
1358611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Builder.SetInsertPoint(InitBB);
1359611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Builder.CreateCall(Init);
1360611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Builder.CreateBr(ExitBB);
1361d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis
1362611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner      Builder.SetInsertPoint(ExitBB);
1363df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    }
1364d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis
1365d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis    // For a reference, the result of the wrapper function is a pointer to
1366d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis    // the referenced object.
1367d2827af6f96d441d72315dbe6d8505c3be0f2aa6Argyrios Kyrtzidis    llvm::Value *Val = Var;
13681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (VD->getType()->isReferenceType()) {
13690faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall      llvm::LoadInst *LI = Builder.CreateLoad(Val);
13700faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall      LI->setAlignment(CGM.getContext().getDeclAlign(VD).getQuantity());
1371026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      Val = LI;
1372026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    }
1373026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
1374611b2eccaf3869f32de51ecc02985426d1c0aaefChris Lattner    Builder.CreateRet(Val);
13756eec8e883de118b431e3ead5b1e604a6ac68ff6bDouglas Gregor  }
1376fb84664349ca6f37f5ec4df440f6c362cca62470Chris Lattner}
1377fb84664349ca6f37f5ec4df440f6c362cca62470Chris Lattner
1378026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris LattnerLValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
1379fb84664349ca6f37f5ec4df440f6c362cca62470Chris Lattner                                                 const DeclRefExpr *DRE) {
1380026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  const VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1381026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  QualType T = VD->getType();
1382026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T);
138358beed91d468863b8c85bce43425422703838d27Anders Carlsson  llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty);
13840faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall  llvm::Function *Wrapper =
13850faede6f31b07bcec7b776f2b420c3ea9bb3e58cJohn McCall      getOrCreateThreadLocalWrapper(VD, cast<llvm::GlobalVariable>(Val));
138658beed91d468863b8c85bce43425422703838d27Anders Carlsson
1387c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  Val = CGF.Builder.CreateCall(Wrapper);
138858beed91d468863b8c85bce43425422703838d27Anders Carlsson
138958beed91d468863b8c85bce43425422703838d27Anders Carlsson  LValue LV;
13902de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  if (VD->getType()->isReferenceType())
13912de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    LV = CGF.MakeNaturalAlignAddrLValue(Val, T);
1392df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  else
1393df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    LV = CGF.MakeAddrLValue(Val, DRE->getType(),
1394026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                            CGF.getContext().getDeclAlign(VD));
1395026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // FIXME: need setObjCGCLValueClass?
1396026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  return LV;
139758beed91d468863b8c85bce43425422703838d27Anders Carlsson}
13981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13994be1f47de20525ad90f02ba8682a7e2cbd3205d1Eli Friedman/// Return whether the given global decl needs a VTT parameter, which it does
14004be1f47de20525ad90f02ba8682a7e2cbd3205d1Eli Friedman/// if it's a base constructor or destructor with virtual bases.
1401df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stumpbool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
1402df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
14034be1f47de20525ad90f02ba8682a7e2cbd3205d1Eli Friedman
140404421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner  // We don't have any virtual bases, just return early.
1405df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump  if (!MD->getParent()->getNumVBases())
1406df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    return false;
14074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl
14084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl  // Check if we have a base constructor.
14094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
14104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl    return true;
14114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl
1412026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // Check if we have a base destructor.
14132d46eb21eb2c904831b0e9f75ab3523384c70e66Anders Carlsson  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
1414df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump    return true;
1415df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump
14166b1d283fe879fb11d7ce7a69feecf66e77b0eaf3Anders Carlsson  return false;
1417df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump}
1418df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump