1208600Srdivacky//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===// 2208600Srdivacky// 3208600Srdivacky// The LLVM Compiler Infrastructure 4208600Srdivacky// 5208600Srdivacky// This file is distributed under the University of Illinois Open Source 6208600Srdivacky// License. See LICENSE.TXT for details. 7208600Srdivacky// 8208600Srdivacky//===----------------------------------------------------------------------===// 9208600Srdivacky// 10221345Sdim// This provides C++ code generation targeting the Itanium C++ ABI. The class 11208600Srdivacky// in this file generates structures that follow the Itanium C++ ABI, which is 12208600Srdivacky// documented at: 13208600Srdivacky// http://www.codesourcery.com/public/cxx-abi/abi.html 14208600Srdivacky// http://www.codesourcery.com/public/cxx-abi/abi-eh.html 15212904Sdim// 16212904Sdim// It also supports the closely-related ARM ABI, documented at: 17212904Sdim// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 18212904Sdim// 19208600Srdivacky//===----------------------------------------------------------------------===// 20208600Srdivacky 21208600Srdivacky#include "CGCXXABI.h" 22212904Sdim#include "CGRecordLayout.h" 23245431Sdim#include "CGVTables.h" 24212904Sdim#include "CodeGenFunction.h" 25208600Srdivacky#include "CodeGenModule.h" 26245431Sdim#include "clang/AST/Mangle.h" 27245431Sdim#include "clang/AST/Type.h" 28252723Sdim#include "llvm/IR/DataLayout.h" 29252723Sdim#include "llvm/IR/Intrinsics.h" 30252723Sdim#include "llvm/IR/Value.h" 31208600Srdivacky 32208600Srdivackyusing namespace clang; 33212904Sdimusing namespace CodeGen; 34208600Srdivacky 35208600Srdivackynamespace { 36212904Sdimclass ItaniumCXXABI : public CodeGen::CGCXXABI { 37263509Sdim /// VTables - All the vtables which have been defined. 38263509Sdim llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; 39263509Sdim 40212904Sdimprotected: 41263509Sdim bool UseARMMethodPtrABI; 42263509Sdim bool UseARMGuardVarABI; 43212904Sdim 44263509Sdim ItaniumMangleContext &getMangleContext() { 45263509Sdim return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext()); 46263509Sdim } 47263509Sdim 48208600Srdivackypublic: 49263509Sdim ItaniumCXXABI(CodeGen::CodeGenModule &CGM, 50263509Sdim bool UseARMMethodPtrABI = false, 51263509Sdim bool UseARMGuardVarABI = false) : 52263509Sdim CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), 53263509Sdim UseARMGuardVarABI(UseARMGuardVarABI) { } 54208600Srdivacky 55252723Sdim bool isReturnTypeIndirect(const CXXRecordDecl *RD) const { 56252723Sdim // Structures with either a non-trivial destructor or a non-trivial 57252723Sdim // copy constructor are always indirect. 58252723Sdim return !RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor(); 59252723Sdim } 60252723Sdim 61252723Sdim RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { 62252723Sdim // Structures with either a non-trivial destructor or a non-trivial 63252723Sdim // copy constructor are always indirect. 64252723Sdim if (!RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) 65252723Sdim return RAA_Indirect; 66252723Sdim return RAA_Default; 67252723Sdim } 68252723Sdim 69212904Sdim bool isZeroInitializable(const MemberPointerType *MPT); 70212904Sdim 71224145Sdim llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); 72212904Sdim 73212904Sdim llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 74212904Sdim llvm::Value *&This, 75212904Sdim llvm::Value *MemFnPtr, 76212904Sdim const MemberPointerType *MPT); 77212904Sdim 78212904Sdim llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 79212904Sdim llvm::Value *Base, 80212904Sdim llvm::Value *MemPtr, 81212904Sdim const MemberPointerType *MPT); 82212904Sdim 83212904Sdim llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 84212904Sdim const CastExpr *E, 85212904Sdim llvm::Value *Src); 86235633Sdim llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 87235633Sdim llvm::Constant *Src); 88212904Sdim 89212904Sdim llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 90212904Sdim 91212904Sdim llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); 92218893Sdim llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 93218893Sdim CharUnits offset); 94235633Sdim llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 95235633Sdim llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD, 96235633Sdim CharUnits ThisAdjustment); 97212904Sdim 98212904Sdim llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 99212904Sdim llvm::Value *L, 100212904Sdim llvm::Value *R, 101212904Sdim const MemberPointerType *MPT, 102212904Sdim bool Inequality); 103212904Sdim 104212904Sdim llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 105212904Sdim llvm::Value *Addr, 106212904Sdim const MemberPointerType *MPT); 107212904Sdim 108245431Sdim llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 109245431Sdim llvm::Value *ptr, 110245431Sdim QualType type); 111245431Sdim 112263509Sdim llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, 113263509Sdim llvm::Value *This, 114263509Sdim const CXXRecordDecl *ClassDecl, 115263509Sdim const CXXRecordDecl *BaseClassDecl); 116263509Sdim 117212904Sdim void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 118212904Sdim CXXCtorType T, 119212904Sdim CanQualType &ResTy, 120226890Sdim SmallVectorImpl<CanQualType> &ArgTys); 121212904Sdim 122263509Sdim void EmitCXXConstructors(const CXXConstructorDecl *D); 123263509Sdim 124212904Sdim void BuildDestructorSignature(const CXXDestructorDecl *Dtor, 125212904Sdim CXXDtorType T, 126212904Sdim CanQualType &ResTy, 127226890Sdim SmallVectorImpl<CanQualType> &ArgTys); 128212904Sdim 129263509Sdim bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, 130263509Sdim CXXDtorType DT) const { 131263509Sdim // Itanium does not emit any destructor variant as an inline thunk. 132263509Sdim // Delegating may occur as an optimization, but all variants are either 133263509Sdim // emitted with external linkage or as linkonce if they are inline and used. 134263509Sdim return false; 135263509Sdim } 136263509Sdim 137263509Sdim void EmitCXXDestructors(const CXXDestructorDecl *D); 138263509Sdim 139212904Sdim void BuildInstanceFunctionParams(CodeGenFunction &CGF, 140212904Sdim QualType &ResTy, 141212904Sdim FunctionArgList &Params); 142212904Sdim 143212904Sdim void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 144212904Sdim 145263509Sdim void EmitConstructorCall(CodeGenFunction &CGF, 146263509Sdim const CXXConstructorDecl *D, CXXCtorType Type, 147263509Sdim bool ForVirtualBase, bool Delegating, 148252723Sdim llvm::Value *This, 149252723Sdim CallExpr::const_arg_iterator ArgBeg, 150252723Sdim CallExpr::const_arg_iterator ArgEnd); 151252723Sdim 152263509Sdim void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD); 153252723Sdim 154263509Sdim llvm::Value *getVTableAddressPointInStructor( 155263509Sdim CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, 156263509Sdim BaseSubobject Base, const CXXRecordDecl *NearestVBase, 157263509Sdim bool &NeedsVirtualOffset); 158263509Sdim 159263509Sdim llvm::Constant * 160263509Sdim getVTableAddressPointForConstExpr(BaseSubobject Base, 161263509Sdim const CXXRecordDecl *VTableClass); 162263509Sdim 163263509Sdim llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, 164263509Sdim CharUnits VPtrOffset); 165263509Sdim 166263509Sdim llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, 167263509Sdim llvm::Value *This, llvm::Type *Ty); 168263509Sdim 169263509Sdim void EmitVirtualDestructorCall(CodeGenFunction &CGF, 170263509Sdim const CXXDestructorDecl *Dtor, 171263509Sdim CXXDtorType DtorType, SourceLocation CallLoc, 172263509Sdim llvm::Value *This); 173263509Sdim 174263509Sdim void emitVirtualInheritanceTables(const CXXRecordDecl *RD); 175263509Sdim 176263509Sdim void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) { 177263509Sdim // Allow inlining of thunks by emitting them with available_externally 178263509Sdim // linkage together with vtables when needed. 179263509Sdim if (ForVTable) 180263509Sdim Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); 181263509Sdim } 182263509Sdim 183263509Sdim llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This, 184263509Sdim const ThisAdjustment &TA); 185263509Sdim 186263509Sdim llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, 187263509Sdim const ReturnAdjustment &RA); 188263509Sdim 189245431Sdim StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; } 190245431Sdim StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; } 191245431Sdim 192245431Sdim CharUnits getArrayCookieSizeImpl(QualType elementType); 193212904Sdim llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 194212904Sdim llvm::Value *NewPtr, 195212904Sdim llvm::Value *NumElements, 196218893Sdim const CXXNewExpr *expr, 197212904Sdim QualType ElementType); 198245431Sdim llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 199245431Sdim llvm::Value *allocPtr, 200245431Sdim CharUnits cookieSize); 201218893Sdim 202218893Sdim void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 203235633Sdim llvm::GlobalVariable *DeclPtr, bool PerformInit); 204252723Sdim void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, 205252723Sdim llvm::Constant *dtor, llvm::Constant *addr); 206245431Sdim 207252723Sdim llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD, 208252723Sdim llvm::GlobalVariable *Var); 209252723Sdim void EmitThreadLocalInitFuncs( 210252723Sdim llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls, 211252723Sdim llvm::Function *InitFunc); 212252723Sdim LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF, 213252723Sdim const DeclRefExpr *DRE); 214263509Sdim 215263509Sdim bool NeedsVTTParameter(GlobalDecl GD); 216208600Srdivacky}; 217212904Sdim 218212904Sdimclass ARMCXXABI : public ItaniumCXXABI { 219212904Sdimpublic: 220263509Sdim ARMCXXABI(CodeGen::CodeGenModule &CGM) : 221263509Sdim ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 222263509Sdim /* UseARMGuardVarABI = */ true) {} 223212904Sdim 224263509Sdim bool HasThisReturn(GlobalDecl GD) const { 225263509Sdim return (isa<CXXConstructorDecl>(GD.getDecl()) || ( 226263509Sdim isa<CXXDestructorDecl>(GD.getDecl()) && 227263509Sdim GD.getDtorType() != Dtor_Deleting)); 228263509Sdim } 229212904Sdim 230212904Sdim void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy); 231212904Sdim 232245431Sdim CharUnits getArrayCookieSizeImpl(QualType elementType); 233212904Sdim llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 234212904Sdim llvm::Value *NewPtr, 235212904Sdim llvm::Value *NumElements, 236218893Sdim const CXXNewExpr *expr, 237212904Sdim QualType ElementType); 238245431Sdim llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr, 239245431Sdim CharUnits cookieSize); 240212904Sdim}; 241208600Srdivacky} 242208600Srdivacky 243212904SdimCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { 244252723Sdim switch (CGM.getTarget().getCXXABI().getKind()) { 245252723Sdim // For IR-generation purposes, there's no significant difference 246252723Sdim // between the ARM and iOS ABIs. 247252723Sdim case TargetCXXABI::GenericARM: 248252723Sdim case TargetCXXABI::iOS: 249252723Sdim return new ARMCXXABI(CGM); 250208600Srdivacky 251252723Sdim // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't 252252723Sdim // include the other 32-bit ARM oddities: constructor/destructor return values 253252723Sdim // and array cookies. 254252723Sdim case TargetCXXABI::GenericAArch64: 255263509Sdim return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 256263509Sdim /* UseARMGuardVarABI = */ true); 257252723Sdim 258252723Sdim case TargetCXXABI::GenericItanium: 259263509Sdim if (CGM.getContext().getTargetInfo().getTriple().getArch() 260263509Sdim == llvm::Triple::le32) { 261263509Sdim // For PNaCl, use ARM-style method pointers so that PNaCl code 262263509Sdim // does not assume anything about the alignment of function 263263509Sdim // pointers. 264263509Sdim return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 265263509Sdim /* UseARMGuardVarABI = */ false); 266263509Sdim } 267252723Sdim return new ItaniumCXXABI(CGM); 268252723Sdim 269252723Sdim case TargetCXXABI::Microsoft: 270252723Sdim llvm_unreachable("Microsoft ABI is not Itanium-based"); 271252723Sdim } 272252723Sdim llvm_unreachable("bad ABI kind"); 273212904Sdim} 274212904Sdim 275224145Sdimllvm::Type * 276212904SdimItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 277212904Sdim if (MPT->isMemberDataPointer()) 278252723Sdim return CGM.PtrDiffTy; 279252723Sdim return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, NULL); 280212904Sdim} 281212904Sdim 282212904Sdim/// In the Itanium and ARM ABIs, method pointers have the form: 283212904Sdim/// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr; 284212904Sdim/// 285212904Sdim/// In the Itanium ABI: 286212904Sdim/// - method pointers are virtual if (memptr.ptr & 1) is nonzero 287212904Sdim/// - the this-adjustment is (memptr.adj) 288212904Sdim/// - the virtual offset is (memptr.ptr - 1) 289212904Sdim/// 290212904Sdim/// In the ARM ABI: 291212904Sdim/// - method pointers are virtual if (memptr.adj & 1) is nonzero 292212904Sdim/// - the this-adjustment is (memptr.adj >> 1) 293212904Sdim/// - the virtual offset is (memptr.ptr) 294212904Sdim/// ARM uses 'adj' for the virtual flag because Thumb functions 295212904Sdim/// may be only single-byte aligned. 296212904Sdim/// 297212904Sdim/// If the member is virtual, the adjusted 'this' pointer points 298212904Sdim/// to a vtable pointer from which the virtual offset is applied. 299212904Sdim/// 300212904Sdim/// If the member is non-virtual, memptr.ptr is the address of 301212904Sdim/// the function to call. 302212904Sdimllvm::Value * 303212904SdimItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 304212904Sdim llvm::Value *&This, 305212904Sdim llvm::Value *MemFnPtr, 306212904Sdim const MemberPointerType *MPT) { 307212904Sdim CGBuilderTy &Builder = CGF.Builder; 308212904Sdim 309212904Sdim const FunctionProtoType *FPT = 310212904Sdim MPT->getPointeeType()->getAs<FunctionProtoType>(); 311212904Sdim const CXXRecordDecl *RD = 312212904Sdim cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); 313212904Sdim 314226890Sdim llvm::FunctionType *FTy = 315235633Sdim CGM.getTypes().GetFunctionType( 316235633Sdim CGM.getTypes().arrangeCXXMethodType(RD, FPT)); 317212904Sdim 318252723Sdim llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1); 319212904Sdim 320212904Sdim llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual"); 321212904Sdim llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual"); 322212904Sdim llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end"); 323212904Sdim 324212904Sdim // Extract memptr.adj, which is in the second field. 325212904Sdim llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj"); 326212904Sdim 327212904Sdim // Compute the true adjustment. 328212904Sdim llvm::Value *Adj = RawAdj; 329263509Sdim if (UseARMMethodPtrABI) 330212904Sdim Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted"); 331212904Sdim 332212904Sdim // Apply the adjustment and cast back to the original struct type 333212904Sdim // for consistency. 334212904Sdim llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 335212904Sdim Ptr = Builder.CreateInBoundsGEP(Ptr, Adj); 336212904Sdim This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 337212904Sdim 338212904Sdim // Load the function pointer. 339212904Sdim llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr"); 340212904Sdim 341212904Sdim // If the LSB in the function pointer is 1, the function pointer points to 342212904Sdim // a virtual function. 343212904Sdim llvm::Value *IsVirtual; 344263509Sdim if (UseARMMethodPtrABI) 345212904Sdim IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1); 346212904Sdim else 347212904Sdim IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1); 348212904Sdim IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual"); 349212904Sdim Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual); 350212904Sdim 351212904Sdim // In the virtual path, the adjustment left 'This' pointing to the 352212904Sdim // vtable of the correct base subobject. The "function pointer" is an 353212904Sdim // offset within the vtable (+1 for the virtual flag on non-ARM). 354212904Sdim CGF.EmitBlock(FnVirtual); 355212904Sdim 356212904Sdim // Cast the adjusted this to a pointer to vtable pointer and load. 357226890Sdim llvm::Type *VTableTy = Builder.getInt8PtrTy(); 358212904Sdim llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo()); 359212904Sdim VTable = Builder.CreateLoad(VTable, "memptr.vtable"); 360212904Sdim 361212904Sdim // Apply the offset. 362212904Sdim llvm::Value *VTableOffset = FnAsInt; 363263509Sdim if (!UseARMMethodPtrABI) 364263509Sdim VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1); 365212904Sdim VTable = Builder.CreateGEP(VTable, VTableOffset); 366212904Sdim 367212904Sdim // Load the virtual function to call. 368212904Sdim VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo()); 369212904Sdim llvm::Value *VirtualFn = Builder.CreateLoad(VTable, "memptr.virtualfn"); 370212904Sdim CGF.EmitBranch(FnEnd); 371212904Sdim 372212904Sdim // In the non-virtual path, the function pointer is actually a 373212904Sdim // function pointer. 374212904Sdim CGF.EmitBlock(FnNonVirtual); 375212904Sdim llvm::Value *NonVirtualFn = 376212904Sdim Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn"); 377212904Sdim 378212904Sdim // We're done. 379212904Sdim CGF.EmitBlock(FnEnd); 380221345Sdim llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2); 381212904Sdim Callee->addIncoming(VirtualFn, FnVirtual); 382212904Sdim Callee->addIncoming(NonVirtualFn, FnNonVirtual); 383212904Sdim return Callee; 384212904Sdim} 385212904Sdim 386212904Sdim/// Compute an l-value by applying the given pointer-to-member to a 387212904Sdim/// base object. 388212904Sdimllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, 389212904Sdim llvm::Value *Base, 390212904Sdim llvm::Value *MemPtr, 391212904Sdim const MemberPointerType *MPT) { 392252723Sdim assert(MemPtr->getType() == CGM.PtrDiffTy); 393212904Sdim 394212904Sdim CGBuilderTy &Builder = CGF.Builder; 395212904Sdim 396245431Sdim unsigned AS = Base->getType()->getPointerAddressSpace(); 397212904Sdim 398212904Sdim // Cast to char*. 399212904Sdim Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS)); 400212904Sdim 401212904Sdim // Apply the offset, which we assume is non-null. 402212904Sdim llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset"); 403212904Sdim 404212904Sdim // Cast the address to the appropriate pointer type, adopting the 405212904Sdim // address space of the base pointer. 406226890Sdim llvm::Type *PType 407212904Sdim = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); 408212904Sdim return Builder.CreateBitCast(Addr, PType); 409212904Sdim} 410212904Sdim 411235633Sdim/// Perform a bitcast, derived-to-base, or base-to-derived member pointer 412235633Sdim/// conversion. 413212904Sdim/// 414235633Sdim/// Bitcast conversions are always a no-op under Itanium. 415235633Sdim/// 416212904Sdim/// Obligatory offset/adjustment diagram: 417212904Sdim/// <-- offset --> <-- adjustment --> 418212904Sdim/// |--------------------------|----------------------|--------------------| 419212904Sdim/// ^Derived address point ^Base address point ^Member address point 420212904Sdim/// 421212904Sdim/// So when converting a base member pointer to a derived member pointer, 422212904Sdim/// we add the offset to the adjustment because the address point has 423212904Sdim/// decreased; and conversely, when converting a derived MP to a base MP 424212904Sdim/// we subtract the offset from the adjustment because the address point 425212904Sdim/// has increased. 426212904Sdim/// 427212904Sdim/// The standard forbids (at compile time) conversion to and from 428212904Sdim/// virtual bases, which is why we don't have to consider them here. 429212904Sdim/// 430212904Sdim/// The standard forbids (at run time) casting a derived MP to a base 431212904Sdim/// MP when the derived MP does not point to a member of the base. 432212904Sdim/// This is why -1 is a reasonable choice for null data member 433212904Sdim/// pointers. 434212904Sdimllvm::Value * 435212904SdimItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 436212904Sdim const CastExpr *E, 437235633Sdim llvm::Value *src) { 438212904Sdim assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 439235633Sdim E->getCastKind() == CK_BaseToDerivedMemberPointer || 440235633Sdim E->getCastKind() == CK_ReinterpretMemberPointer); 441212904Sdim 442235633Sdim // Under Itanium, reinterprets don't require any additional processing. 443235633Sdim if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; 444212904Sdim 445235633Sdim // Use constant emission if we can. 446235633Sdim if (isa<llvm::Constant>(src)) 447235633Sdim return EmitMemberPointerConversion(E, cast<llvm::Constant>(src)); 448212904Sdim 449235633Sdim llvm::Constant *adj = getMemberPointerAdjustment(E); 450235633Sdim if (!adj) return src; 451212904Sdim 452235633Sdim CGBuilderTy &Builder = CGF.Builder; 453235633Sdim bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 454212904Sdim 455235633Sdim const MemberPointerType *destTy = 456235633Sdim E->getType()->castAs<MemberPointerType>(); 457212904Sdim 458212904Sdim // For member data pointers, this is just a matter of adding the 459212904Sdim // offset if the source is non-null. 460235633Sdim if (destTy->isMemberDataPointer()) { 461235633Sdim llvm::Value *dst; 462235633Sdim if (isDerivedToBase) 463235633Sdim dst = Builder.CreateNSWSub(src, adj, "adj"); 464212904Sdim else 465235633Sdim dst = Builder.CreateNSWAdd(src, adj, "adj"); 466212904Sdim 467212904Sdim // Null check. 468235633Sdim llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType()); 469235633Sdim llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull"); 470235633Sdim return Builder.CreateSelect(isNull, src, dst); 471212904Sdim } 472212904Sdim 473212904Sdim // The this-adjustment is left-shifted by 1 on ARM. 474263509Sdim if (UseARMMethodPtrABI) { 475235633Sdim uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); 476235633Sdim offset <<= 1; 477235633Sdim adj = llvm::ConstantInt::get(adj->getType(), offset); 478212904Sdim } 479212904Sdim 480235633Sdim llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj"); 481235633Sdim llvm::Value *dstAdj; 482235633Sdim if (isDerivedToBase) 483235633Sdim dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj"); 484212904Sdim else 485235633Sdim dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj"); 486212904Sdim 487235633Sdim return Builder.CreateInsertValue(src, dstAdj, 1); 488212904Sdim} 489212904Sdim 490212904Sdimllvm::Constant * 491235633SdimItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, 492235633Sdim llvm::Constant *src) { 493235633Sdim assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 494235633Sdim E->getCastKind() == CK_BaseToDerivedMemberPointer || 495235633Sdim E->getCastKind() == CK_ReinterpretMemberPointer); 496212904Sdim 497235633Sdim // Under Itanium, reinterprets don't require any additional processing. 498235633Sdim if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; 499212904Sdim 500235633Sdim // If the adjustment is trivial, we don't need to do anything. 501235633Sdim llvm::Constant *adj = getMemberPointerAdjustment(E); 502235633Sdim if (!adj) return src; 503212904Sdim 504235633Sdim bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 505212904Sdim 506235633Sdim const MemberPointerType *destTy = 507235633Sdim E->getType()->castAs<MemberPointerType>(); 508212904Sdim 509235633Sdim // For member data pointers, this is just a matter of adding the 510235633Sdim // offset if the source is non-null. 511235633Sdim if (destTy->isMemberDataPointer()) { 512235633Sdim // null maps to null. 513235633Sdim if (src->isAllOnesValue()) return src; 514212904Sdim 515235633Sdim if (isDerivedToBase) 516235633Sdim return llvm::ConstantExpr::getNSWSub(src, adj); 517212904Sdim else 518235633Sdim return llvm::ConstantExpr::getNSWAdd(src, adj); 519212904Sdim } 520212904Sdim 521212904Sdim // The this-adjustment is left-shifted by 1 on ARM. 522263509Sdim if (UseARMMethodPtrABI) { 523235633Sdim uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); 524235633Sdim offset <<= 1; 525235633Sdim adj = llvm::ConstantInt::get(adj->getType(), offset); 526212904Sdim } 527212904Sdim 528235633Sdim llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1); 529235633Sdim llvm::Constant *dstAdj; 530235633Sdim if (isDerivedToBase) 531235633Sdim dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj); 532212904Sdim else 533235633Sdim dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj); 534212904Sdim 535235633Sdim return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1); 536235633Sdim} 537212904Sdim 538212904Sdimllvm::Constant * 539212904SdimItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 540212904Sdim // Itanium C++ ABI 2.3: 541212904Sdim // A NULL pointer is represented as -1. 542212904Sdim if (MPT->isMemberDataPointer()) 543252723Sdim return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true); 544212904Sdim 545252723Sdim llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0); 546212904Sdim llvm::Constant *Values[2] = { Zero, Zero }; 547224145Sdim return llvm::ConstantStruct::getAnon(Values); 548212904Sdim} 549212904Sdim 550218893Sdimllvm::Constant * 551218893SdimItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 552218893Sdim CharUnits offset) { 553212904Sdim // Itanium C++ ABI 2.3: 554212904Sdim // A pointer to data member is an offset from the base address of 555212904Sdim // the class object containing it, represented as a ptrdiff_t 556252723Sdim return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()); 557212904Sdim} 558212904Sdim 559212904Sdimllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { 560235633Sdim return BuildMemberPointer(MD, CharUnits::Zero()); 561235633Sdim} 562235633Sdim 563235633Sdimllvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, 564235633Sdim CharUnits ThisAdjustment) { 565212904Sdim assert(MD->isInstance() && "Member function must not be static!"); 566212904Sdim MD = MD->getCanonicalDecl(); 567212904Sdim 568212904Sdim CodeGenTypes &Types = CGM.getTypes(); 569212904Sdim 570212904Sdim // Get the function pointer (or index if this is a virtual function). 571212904Sdim llvm::Constant *MemPtr[2]; 572212904Sdim if (MD->isVirtual()) { 573263509Sdim uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD); 574212904Sdim 575221345Sdim const ASTContext &Context = getContext(); 576221345Sdim CharUnits PointerWidth = 577226890Sdim Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 578221345Sdim uint64_t VTableOffset = (Index * PointerWidth.getQuantity()); 579212904Sdim 580263509Sdim if (UseARMMethodPtrABI) { 581212904Sdim // ARM C++ ABI 3.2.1: 582212904Sdim // This ABI specifies that adj contains twice the this 583212904Sdim // adjustment, plus 1 if the member function is virtual. The 584212904Sdim // least significant bit of adj then makes exactly the same 585212904Sdim // discrimination as the least significant bit of ptr does for 586212904Sdim // Itanium. 587252723Sdim MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); 588252723Sdim MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 589235633Sdim 2 * ThisAdjustment.getQuantity() + 1); 590212904Sdim } else { 591212904Sdim // Itanium C++ ABI 2.3: 592212904Sdim // For a virtual function, [the pointer field] is 1 plus the 593212904Sdim // virtual table offset (in bytes) of the function, 594212904Sdim // represented as a ptrdiff_t. 595252723Sdim MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1); 596252723Sdim MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 597235633Sdim ThisAdjustment.getQuantity()); 598212904Sdim } 599212904Sdim } else { 600221345Sdim const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 601226890Sdim llvm::Type *Ty; 602212904Sdim // Check whether the function has a computable LLVM signature. 603224145Sdim if (Types.isFuncTypeConvertible(FPT)) { 604212904Sdim // The function has a computable LLVM signature; use the correct type. 605235633Sdim Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 606212904Sdim } else { 607212904Sdim // Use an arbitrary non-function type to tell GetAddrOfFunction that the 608212904Sdim // function type is incomplete. 609252723Sdim Ty = CGM.PtrDiffTy; 610212904Sdim } 611221345Sdim llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty); 612212904Sdim 613252723Sdim MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); 614263509Sdim MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 615263509Sdim (UseARMMethodPtrABI ? 2 : 1) * 616235633Sdim ThisAdjustment.getQuantity()); 617212904Sdim } 618212904Sdim 619224145Sdim return llvm::ConstantStruct::getAnon(MemPtr); 620212904Sdim} 621212904Sdim 622235633Sdimllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, 623235633Sdim QualType MPType) { 624235633Sdim const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); 625235633Sdim const ValueDecl *MPD = MP.getMemberPointerDecl(); 626235633Sdim if (!MPD) 627235633Sdim return EmitNullMemberPointer(MPT); 628235633Sdim 629263509Sdim CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); 630235633Sdim 631235633Sdim if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) 632235633Sdim return BuildMemberPointer(MD, ThisAdjustment); 633235633Sdim 634235633Sdim CharUnits FieldOffset = 635235633Sdim getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); 636235633Sdim return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); 637235633Sdim} 638235633Sdim 639212904Sdim/// The comparison algorithm is pretty easy: the member pointers are 640212904Sdim/// the same if they're either bitwise identical *or* both null. 641212904Sdim/// 642212904Sdim/// ARM is different here only because null-ness is more complicated. 643212904Sdimllvm::Value * 644212904SdimItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 645212904Sdim llvm::Value *L, 646212904Sdim llvm::Value *R, 647212904Sdim const MemberPointerType *MPT, 648212904Sdim bool Inequality) { 649212904Sdim CGBuilderTy &Builder = CGF.Builder; 650212904Sdim 651212904Sdim llvm::ICmpInst::Predicate Eq; 652212904Sdim llvm::Instruction::BinaryOps And, Or; 653212904Sdim if (Inequality) { 654212904Sdim Eq = llvm::ICmpInst::ICMP_NE; 655212904Sdim And = llvm::Instruction::Or; 656212904Sdim Or = llvm::Instruction::And; 657212904Sdim } else { 658212904Sdim Eq = llvm::ICmpInst::ICMP_EQ; 659212904Sdim And = llvm::Instruction::And; 660212904Sdim Or = llvm::Instruction::Or; 661212904Sdim } 662212904Sdim 663212904Sdim // Member data pointers are easy because there's a unique null 664212904Sdim // value, so it just comes down to bitwise equality. 665212904Sdim if (MPT->isMemberDataPointer()) 666212904Sdim return Builder.CreateICmp(Eq, L, R); 667212904Sdim 668212904Sdim // For member function pointers, the tautologies are more complex. 669212904Sdim // The Itanium tautology is: 670212904Sdim // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj)) 671212904Sdim // The ARM tautology is: 672212904Sdim // (L == R) <==> (L.ptr == R.ptr && 673212904Sdim // (L.adj == R.adj || 674212904Sdim // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0))) 675212904Sdim // The inequality tautologies have exactly the same structure, except 676212904Sdim // applying De Morgan's laws. 677212904Sdim 678212904Sdim llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr"); 679212904Sdim llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr"); 680212904Sdim 681212904Sdim // This condition tests whether L.ptr == R.ptr. This must always be 682212904Sdim // true for equality to hold. 683212904Sdim llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr"); 684212904Sdim 685212904Sdim // This condition, together with the assumption that L.ptr == R.ptr, 686212904Sdim // tests whether the pointers are both null. ARM imposes an extra 687212904Sdim // condition. 688212904Sdim llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType()); 689212904Sdim llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null"); 690212904Sdim 691212904Sdim // This condition tests whether L.adj == R.adj. If this isn't 692212904Sdim // true, the pointers are unequal unless they're both null. 693212904Sdim llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj"); 694212904Sdim llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj"); 695212904Sdim llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj"); 696212904Sdim 697212904Sdim // Null member function pointers on ARM clear the low bit of Adj, 698212904Sdim // so the zero condition has to check that neither low bit is set. 699263509Sdim if (UseARMMethodPtrABI) { 700212904Sdim llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1); 701212904Sdim 702212904Sdim // Compute (l.adj | r.adj) & 1 and test it against zero. 703212904Sdim llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj"); 704212904Sdim llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One); 705212904Sdim llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero, 706212904Sdim "cmp.or.adj"); 707212904Sdim EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero); 708212904Sdim } 709212904Sdim 710212904Sdim // Tie together all our conditions. 711212904Sdim llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq); 712212904Sdim Result = Builder.CreateBinOp(And, PtrEq, Result, 713212904Sdim Inequality ? "memptr.ne" : "memptr.eq"); 714212904Sdim return Result; 715212904Sdim} 716212904Sdim 717212904Sdimllvm::Value * 718212904SdimItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 719212904Sdim llvm::Value *MemPtr, 720212904Sdim const MemberPointerType *MPT) { 721212904Sdim CGBuilderTy &Builder = CGF.Builder; 722212904Sdim 723212904Sdim /// For member data pointers, this is just a check against -1. 724212904Sdim if (MPT->isMemberDataPointer()) { 725252723Sdim assert(MemPtr->getType() == CGM.PtrDiffTy); 726212904Sdim llvm::Value *NegativeOne = 727212904Sdim llvm::Constant::getAllOnesValue(MemPtr->getType()); 728212904Sdim return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool"); 729212904Sdim } 730212904Sdim 731221345Sdim // In Itanium, a member function pointer is not null if 'ptr' is not null. 732212904Sdim llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr"); 733212904Sdim 734212904Sdim llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0); 735212904Sdim llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool"); 736212904Sdim 737221345Sdim // On ARM, a member function pointer is also non-null if the low bit of 'adj' 738221345Sdim // (the virtual bit) is set. 739263509Sdim if (UseARMMethodPtrABI) { 740212904Sdim llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1); 741212904Sdim llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj"); 742212904Sdim llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit"); 743221345Sdim llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero, 744221345Sdim "memptr.isvirtual"); 745221345Sdim Result = Builder.CreateOr(Result, IsVirtual); 746212904Sdim } 747212904Sdim 748212904Sdim return Result; 749212904Sdim} 750212904Sdim 751212904Sdim/// The Itanium ABI requires non-zero initialization only for data 752212904Sdim/// member pointers, for which '0' is a valid offset. 753212904Sdimbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 754212904Sdim return MPT->getPointeeType()->isFunctionType(); 755212904Sdim} 756212904Sdim 757245431Sdim/// The Itanium ABI always places an offset to the complete object 758245431Sdim/// at entry -2 in the vtable. 759245431Sdimllvm::Value *ItaniumCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 760245431Sdim llvm::Value *ptr, 761245431Sdim QualType type) { 762245431Sdim // Grab the vtable pointer as an intptr_t*. 763245431Sdim llvm::Value *vtable = CGF.GetVTablePtr(ptr, CGF.IntPtrTy->getPointerTo()); 764245431Sdim 765245431Sdim // Track back to entry -2 and pull out the offset there. 766245431Sdim llvm::Value *offsetPtr = 767245431Sdim CGF.Builder.CreateConstInBoundsGEP1_64(vtable, -2, "complete-offset.ptr"); 768245431Sdim llvm::LoadInst *offset = CGF.Builder.CreateLoad(offsetPtr); 769245431Sdim offset->setAlignment(CGF.PointerAlignInBytes); 770245431Sdim 771245431Sdim // Apply the offset. 772245431Sdim ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); 773245431Sdim return CGF.Builder.CreateInBoundsGEP(ptr, offset); 774245431Sdim} 775245431Sdim 776263509Sdimllvm::Value * 777263509SdimItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, 778263509Sdim llvm::Value *This, 779263509Sdim const CXXRecordDecl *ClassDecl, 780263509Sdim const CXXRecordDecl *BaseClassDecl) { 781263509Sdim llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy); 782263509Sdim CharUnits VBaseOffsetOffset = 783263509Sdim CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl, 784263509Sdim BaseClassDecl); 785263509Sdim 786263509Sdim llvm::Value *VBaseOffsetPtr = 787263509Sdim CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 788263509Sdim "vbase.offset.ptr"); 789263509Sdim VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr, 790263509Sdim CGM.PtrDiffTy->getPointerTo()); 791263509Sdim 792263509Sdim llvm::Value *VBaseOffset = 793263509Sdim CGF.Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 794263509Sdim 795263509Sdim return VBaseOffset; 796263509Sdim} 797263509Sdim 798212904Sdim/// The generic ABI passes 'this', plus a VTT if it's initializing a 799212904Sdim/// base subobject. 800212904Sdimvoid ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 801212904Sdim CXXCtorType Type, 802212904Sdim CanQualType &ResTy, 803226890Sdim SmallVectorImpl<CanQualType> &ArgTys) { 804212904Sdim ASTContext &Context = getContext(); 805212904Sdim 806263509Sdim // 'this' parameter is already there, as well as 'this' return if 807263509Sdim // HasThisReturn(GlobalDecl(Ctor, Type)) is true 808212904Sdim 809212904Sdim // Check if we need to add a VTT parameter (which has type void **). 810212904Sdim if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0) 811212904Sdim ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); 812212904Sdim} 813212904Sdim 814263509Sdimvoid ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { 815263509Sdim // Just make sure we're in sync with TargetCXXABI. 816263509Sdim assert(CGM.getTarget().getCXXABI().hasConstructorVariants()); 817263509Sdim 818263509Sdim // The constructor used for constructing this as a complete class; 819263509Sdim // constucts the virtual bases, then calls the base constructor. 820263509Sdim if (!D->getParent()->isAbstract()) { 821263509Sdim // We don't need to emit the complete ctor if the class is abstract. 822263509Sdim CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); 823263509Sdim } 824263509Sdim 825263509Sdim // The constructor used for constructing this as a base class; 826263509Sdim // ignores virtual bases. 827263509Sdim CGM.EmitGlobal(GlobalDecl(D, Ctor_Base)); 828212904Sdim} 829212904Sdim 830212904Sdim/// The generic ABI passes 'this', plus a VTT if it's destroying a 831212904Sdim/// base subobject. 832212904Sdimvoid ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 833212904Sdim CXXDtorType Type, 834212904Sdim CanQualType &ResTy, 835226890Sdim SmallVectorImpl<CanQualType> &ArgTys) { 836212904Sdim ASTContext &Context = getContext(); 837212904Sdim 838263509Sdim // 'this' parameter is already there, as well as 'this' return if 839263509Sdim // HasThisReturn(GlobalDecl(Dtor, Type)) is true 840212904Sdim 841212904Sdim // Check if we need to add a VTT parameter (which has type void **). 842212904Sdim if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0) 843212904Sdim ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); 844212904Sdim} 845212904Sdim 846263509Sdimvoid ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { 847263509Sdim // The destructor in a virtual table is always a 'deleting' 848263509Sdim // destructor, which calls the complete destructor and then uses the 849263509Sdim // appropriate operator delete. 850263509Sdim if (D->isVirtual()) 851263509Sdim CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting)); 852212904Sdim 853263509Sdim // The destructor used for destructing this as a most-derived class; 854263509Sdim // call the base destructor and then destructs any virtual bases. 855263509Sdim CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete)); 856263509Sdim 857263509Sdim // The destructor used for destructing this as a base class; ignores 858263509Sdim // virtual bases. 859263509Sdim CGM.EmitGlobal(GlobalDecl(D, Dtor_Base)); 860212904Sdim} 861212904Sdim 862212904Sdimvoid ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 863212904Sdim QualType &ResTy, 864212904Sdim FunctionArgList &Params) { 865212904Sdim /// Create the 'this' variable. 866212904Sdim BuildThisParam(CGF, Params); 867212904Sdim 868212904Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 869212904Sdim assert(MD->isInstance()); 870212904Sdim 871212904Sdim // Check if we need a VTT parameter as well. 872263509Sdim if (NeedsVTTParameter(CGF.CurGD)) { 873212904Sdim ASTContext &Context = getContext(); 874212904Sdim 875212904Sdim // FIXME: avoid the fake decl 876212904Sdim QualType T = Context.getPointerType(Context.VoidPtrTy); 877212904Sdim ImplicitParamDecl *VTTDecl 878212904Sdim = ImplicitParamDecl::Create(Context, 0, MD->getLocation(), 879212904Sdim &Context.Idents.get("vtt"), T); 880221345Sdim Params.push_back(VTTDecl); 881212904Sdim getVTTDecl(CGF) = VTTDecl; 882212904Sdim } 883212904Sdim} 884212904Sdim 885212904Sdimvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 886212904Sdim /// Initialize the 'this' slot. 887212904Sdim EmitThisParam(CGF); 888212904Sdim 889212904Sdim /// Initialize the 'vtt' slot if needed. 890212904Sdim if (getVTTDecl(CGF)) { 891212904Sdim getVTTValue(CGF) 892212904Sdim = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)), 893212904Sdim "vtt"); 894212904Sdim } 895212904Sdim 896263509Sdim /// If this is a function that the ABI specifies returns 'this', initialize 897263509Sdim /// the return slot to 'this' at the start of the function. 898263509Sdim /// 899263509Sdim /// Unlike the setting of return types, this is done within the ABI 900263509Sdim /// implementation instead of by clients of CGCXXABI because: 901263509Sdim /// 1) getThisValue is currently protected 902263509Sdim /// 2) in theory, an ABI could implement 'this' returns some other way; 903263509Sdim /// HasThisReturn only specifies a contract, not the implementation 904212904Sdim if (HasThisReturn(CGF.CurGD)) 905235633Sdim CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 906212904Sdim} 907212904Sdim 908263509Sdimvoid ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 909252723Sdim const CXXConstructorDecl *D, 910263509Sdim CXXCtorType Type, 911263509Sdim bool ForVirtualBase, bool Delegating, 912252723Sdim llvm::Value *This, 913252723Sdim CallExpr::const_arg_iterator ArgBeg, 914252723Sdim CallExpr::const_arg_iterator ArgEnd) { 915252723Sdim llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, 916252723Sdim Delegating); 917252723Sdim QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); 918252723Sdim llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 919252723Sdim 920252723Sdim // FIXME: Provide a source location here. 921263509Sdim CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), 922263509Sdim This, VTT, VTTTy, ArgBeg, ArgEnd); 923252723Sdim} 924252723Sdim 925263509Sdimvoid ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, 926263509Sdim const CXXRecordDecl *RD) { 927263509Sdim llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits()); 928263509Sdim if (VTable->hasInitializer()) 929263509Sdim return; 930263509Sdim 931263509Sdim ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); 932263509Sdim const VTableLayout &VTLayout = VTContext.getVTableLayout(RD); 933263509Sdim llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); 934263509Sdim 935263509Sdim // Create and set the initializer. 936263509Sdim llvm::Constant *Init = CGVT.CreateVTableInitializer( 937263509Sdim RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(), 938263509Sdim VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks()); 939263509Sdim VTable->setInitializer(Init); 940263509Sdim 941263509Sdim // Set the correct linkage. 942263509Sdim VTable->setLinkage(Linkage); 943263509Sdim 944263509Sdim // Set the right visibility. 945263509Sdim CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); 946263509Sdim 947263509Sdim // If this is the magic class __cxxabiv1::__fundamental_type_info, 948263509Sdim // we will emit the typeinfo for the fundamental types. This is the 949263509Sdim // same behaviour as GCC. 950263509Sdim const DeclContext *DC = RD->getDeclContext(); 951263509Sdim if (RD->getIdentifier() && 952263509Sdim RD->getIdentifier()->isStr("__fundamental_type_info") && 953263509Sdim isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() && 954263509Sdim cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && 955263509Sdim DC->getParent()->isTranslationUnit()) 956263509Sdim CGM.EmitFundamentalRTTIDescriptors(); 957263509Sdim} 958263509Sdim 959263509Sdimllvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor( 960263509Sdim CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, 961263509Sdim const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { 962263509Sdim bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD); 963263509Sdim NeedsVirtualOffset = (NeedsVTTParam && NearestVBase); 964263509Sdim 965263509Sdim llvm::Value *VTableAddressPoint; 966263509Sdim if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase)) { 967263509Sdim // Get the secondary vpointer index. 968263509Sdim uint64_t VirtualPointerIndex = 969263509Sdim CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 970263509Sdim 971263509Sdim /// Load the VTT. 972263509Sdim llvm::Value *VTT = CGF.LoadCXXVTT(); 973263509Sdim if (VirtualPointerIndex) 974263509Sdim VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 975263509Sdim 976263509Sdim // And load the address point from the VTT. 977263509Sdim VTableAddressPoint = CGF.Builder.CreateLoad(VTT); 978263509Sdim } else { 979263509Sdim llvm::Constant *VTable = 980263509Sdim CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits()); 981263509Sdim uint64_t AddressPoint = CGM.getItaniumVTableContext() 982263509Sdim .getVTableLayout(VTableClass) 983263509Sdim .getAddressPoint(Base); 984263509Sdim VTableAddressPoint = 985263509Sdim CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); 986263509Sdim } 987263509Sdim 988263509Sdim return VTableAddressPoint; 989263509Sdim} 990263509Sdim 991263509Sdimllvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( 992263509Sdim BaseSubobject Base, const CXXRecordDecl *VTableClass) { 993263509Sdim llvm::Constant *VTable = getAddrOfVTable(VTableClass, CharUnits()); 994263509Sdim 995263509Sdim // Find the appropriate vtable within the vtable group. 996263509Sdim uint64_t AddressPoint = CGM.getItaniumVTableContext() 997263509Sdim .getVTableLayout(VTableClass) 998263509Sdim .getAddressPoint(Base); 999263509Sdim llvm::Value *Indices[] = { 1000263509Sdim llvm::ConstantInt::get(CGM.Int64Ty, 0), 1001263509Sdim llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint) 1002263509Sdim }; 1003263509Sdim 1004263509Sdim return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices); 1005263509Sdim} 1006263509Sdim 1007263509Sdimllvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, 1008263509Sdim CharUnits VPtrOffset) { 1009263509Sdim assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); 1010263509Sdim 1011263509Sdim llvm::GlobalVariable *&VTable = VTables[RD]; 1012263509Sdim if (VTable) 1013263509Sdim return VTable; 1014263509Sdim 1015263509Sdim // Queue up this v-table for possible deferred emission. 1016263509Sdim CGM.addDeferredVTable(RD); 1017263509Sdim 1018263509Sdim SmallString<256> OutName; 1019263509Sdim llvm::raw_svector_ostream Out(OutName); 1020263509Sdim getMangleContext().mangleCXXVTable(RD, Out); 1021263509Sdim Out.flush(); 1022263509Sdim StringRef Name = OutName.str(); 1023263509Sdim 1024263509Sdim ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); 1025263509Sdim llvm::ArrayType *ArrayType = llvm::ArrayType::get( 1026263509Sdim CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents()); 1027263509Sdim 1028263509Sdim VTable = CGM.CreateOrReplaceCXXRuntimeVariable( 1029263509Sdim Name, ArrayType, llvm::GlobalValue::ExternalLinkage); 1030263509Sdim VTable->setUnnamedAddr(true); 1031263509Sdim return VTable; 1032263509Sdim} 1033263509Sdim 1034263509Sdimllvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, 1035263509Sdim GlobalDecl GD, 1036263509Sdim llvm::Value *This, 1037263509Sdim llvm::Type *Ty) { 1038263509Sdim GD = GD.getCanonicalDecl(); 1039263509Sdim Ty = Ty->getPointerTo()->getPointerTo(); 1040263509Sdim llvm::Value *VTable = CGF.GetVTablePtr(This, Ty); 1041263509Sdim 1042263509Sdim uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); 1043263509Sdim llvm::Value *VFuncPtr = 1044263509Sdim CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); 1045263509Sdim return CGF.Builder.CreateLoad(VFuncPtr); 1046263509Sdim} 1047263509Sdim 1048263509Sdimvoid ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 1049263509Sdim const CXXDestructorDecl *Dtor, 1050263509Sdim CXXDtorType DtorType, 1051263509Sdim SourceLocation CallLoc, 1052263509Sdim llvm::Value *This) { 1053252723Sdim assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 1054252723Sdim 1055252723Sdim const CGFunctionInfo *FInfo 1056252723Sdim = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType); 1057252723Sdim llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 1058263509Sdim llvm::Value *Callee = 1059263509Sdim getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty); 1060252723Sdim 1061263509Sdim CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This, 1062263509Sdim /*ImplicitParam=*/0, QualType(), 0, 0); 1063252723Sdim} 1064252723Sdim 1065263509Sdimvoid ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { 1066263509Sdim CodeGenVTables &VTables = CGM.getVTables(); 1067263509Sdim llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD); 1068263509Sdim VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD); 1069263509Sdim} 1070263509Sdim 1071263509Sdimstatic llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, 1072263509Sdim llvm::Value *Ptr, 1073263509Sdim int64_t NonVirtualAdjustment, 1074263509Sdim int64_t VirtualAdjustment, 1075263509Sdim bool IsReturnAdjustment) { 1076263509Sdim if (!NonVirtualAdjustment && !VirtualAdjustment) 1077263509Sdim return Ptr; 1078263509Sdim 1079263509Sdim llvm::Type *Int8PtrTy = CGF.Int8PtrTy; 1080263509Sdim llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); 1081263509Sdim 1082263509Sdim if (NonVirtualAdjustment && !IsReturnAdjustment) { 1083263509Sdim // Perform the non-virtual adjustment for a base-to-derived cast. 1084263509Sdim V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); 1085263509Sdim } 1086263509Sdim 1087263509Sdim if (VirtualAdjustment) { 1088263509Sdim llvm::Type *PtrDiffTy = 1089263509Sdim CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1090263509Sdim 1091263509Sdim // Perform the virtual adjustment. 1092263509Sdim llvm::Value *VTablePtrPtr = 1093263509Sdim CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); 1094263509Sdim 1095263509Sdim llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); 1096263509Sdim 1097263509Sdim llvm::Value *OffsetPtr = 1098263509Sdim CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 1099263509Sdim 1100263509Sdim OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); 1101263509Sdim 1102263509Sdim // Load the adjustment offset from the vtable. 1103263509Sdim llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); 1104263509Sdim 1105263509Sdim // Adjust our pointer. 1106263509Sdim V = CGF.Builder.CreateInBoundsGEP(V, Offset); 1107263509Sdim } 1108263509Sdim 1109263509Sdim if (NonVirtualAdjustment && IsReturnAdjustment) { 1110263509Sdim // Perform the non-virtual adjustment for a derived-to-base cast. 1111263509Sdim V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); 1112263509Sdim } 1113263509Sdim 1114263509Sdim // Cast back to the original type. 1115263509Sdim return CGF.Builder.CreateBitCast(V, Ptr->getType()); 1116263509Sdim} 1117263509Sdim 1118263509Sdimllvm::Value *ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, 1119263509Sdim llvm::Value *This, 1120263509Sdim const ThisAdjustment &TA) { 1121263509Sdim return performTypeAdjustment(CGF, This, TA.NonVirtual, 1122263509Sdim TA.Virtual.Itanium.VCallOffsetOffset, 1123263509Sdim /*IsReturnAdjustment=*/false); 1124263509Sdim} 1125263509Sdim 1126263509Sdimllvm::Value * 1127263509SdimItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, 1128263509Sdim const ReturnAdjustment &RA) { 1129263509Sdim return performTypeAdjustment(CGF, Ret, RA.NonVirtual, 1130263509Sdim RA.Virtual.Itanium.VBaseOffsetOffset, 1131263509Sdim /*IsReturnAdjustment=*/true); 1132263509Sdim} 1133263509Sdim 1134212904Sdimvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, 1135212904Sdim RValue RV, QualType ResultType) { 1136212904Sdim if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl())) 1137212904Sdim return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType); 1138212904Sdim 1139212904Sdim // Destructor thunks in the ARM ABI have indeterminate results. 1140226890Sdim llvm::Type *T = 1141212904Sdim cast<llvm::PointerType>(CGF.ReturnValue->getType())->getElementType(); 1142212904Sdim RValue Undef = RValue::get(llvm::UndefValue::get(T)); 1143212904Sdim return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType); 1144212904Sdim} 1145212904Sdim 1146212904Sdim/************************** Array allocation cookies **************************/ 1147212904Sdim 1148245431SdimCharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) { 1149245431Sdim // The array cookie is a size_t; pad that up to the element alignment. 1150245431Sdim // The cookie is actually right-justified in that space. 1151245431Sdim return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes), 1152245431Sdim CGM.getContext().getTypeAlignInChars(elementType)); 1153218893Sdim} 1154212904Sdim 1155212904Sdimllvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 1156212904Sdim llvm::Value *NewPtr, 1157212904Sdim llvm::Value *NumElements, 1158218893Sdim const CXXNewExpr *expr, 1159212904Sdim QualType ElementType) { 1160245431Sdim assert(requiresArrayCookie(expr)); 1161212904Sdim 1162245431Sdim unsigned AS = NewPtr->getType()->getPointerAddressSpace(); 1163212904Sdim 1164212904Sdim ASTContext &Ctx = getContext(); 1165212904Sdim QualType SizeTy = Ctx.getSizeType(); 1166212904Sdim CharUnits SizeSize = Ctx.getTypeSizeInChars(SizeTy); 1167212904Sdim 1168212904Sdim // The size of the cookie. 1169212904Sdim CharUnits CookieSize = 1170212904Sdim std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType)); 1171245431Sdim assert(CookieSize == getArrayCookieSizeImpl(ElementType)); 1172212904Sdim 1173212904Sdim // Compute an offset to the cookie. 1174212904Sdim llvm::Value *CookiePtr = NewPtr; 1175212904Sdim CharUnits CookieOffset = CookieSize - SizeSize; 1176212904Sdim if (!CookieOffset.isZero()) 1177212904Sdim CookiePtr = CGF.Builder.CreateConstInBoundsGEP1_64(CookiePtr, 1178212904Sdim CookieOffset.getQuantity()); 1179212904Sdim 1180212904Sdim // Write the number of elements into the appropriate slot. 1181212904Sdim llvm::Value *NumElementsPtr 1182212904Sdim = CGF.Builder.CreateBitCast(CookiePtr, 1183212904Sdim CGF.ConvertType(SizeTy)->getPointerTo(AS)); 1184212904Sdim CGF.Builder.CreateStore(NumElements, NumElementsPtr); 1185212904Sdim 1186212904Sdim // Finally, compute a pointer to the actual data buffer by skipping 1187212904Sdim // over the cookie completely. 1188212904Sdim return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr, 1189212904Sdim CookieSize.getQuantity()); 1190212904Sdim} 1191212904Sdim 1192245431Sdimllvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 1193245431Sdim llvm::Value *allocPtr, 1194245431Sdim CharUnits cookieSize) { 1195245431Sdim // The element size is right-justified in the cookie. 1196245431Sdim llvm::Value *numElementsPtr = allocPtr; 1197245431Sdim CharUnits numElementsOffset = 1198245431Sdim cookieSize - CharUnits::fromQuantity(CGF.SizeSizeInBytes); 1199245431Sdim if (!numElementsOffset.isZero()) 1200245431Sdim numElementsPtr = 1201245431Sdim CGF.Builder.CreateConstInBoundsGEP1_64(numElementsPtr, 1202245431Sdim numElementsOffset.getQuantity()); 1203212904Sdim 1204245431Sdim unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 1205245431Sdim numElementsPtr = 1206245431Sdim CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS)); 1207245431Sdim return CGF.Builder.CreateLoad(numElementsPtr); 1208212904Sdim} 1209212904Sdim 1210245431SdimCharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { 1211252723Sdim // ARM says that the cookie is always: 1212212904Sdim // struct array_cookie { 1213212904Sdim // std::size_t element_size; // element_size != 0 1214212904Sdim // std::size_t element_count; 1215212904Sdim // }; 1216252723Sdim // But the base ABI doesn't give anything an alignment greater than 1217252723Sdim // 8, so we can dismiss this as typical ABI-author blindness to 1218252723Sdim // actual language complexity and round up to the element alignment. 1219252723Sdim return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes), 1220252723Sdim CGM.getContext().getTypeAlignInChars(elementType)); 1221212904Sdim} 1222212904Sdim 1223212904Sdimllvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 1224252723Sdim llvm::Value *newPtr, 1225252723Sdim llvm::Value *numElements, 1226218893Sdim const CXXNewExpr *expr, 1227252723Sdim QualType elementType) { 1228245431Sdim assert(requiresArrayCookie(expr)); 1229212904Sdim 1230252723Sdim // NewPtr is a char*, but we generalize to arbitrary addrspaces. 1231252723Sdim unsigned AS = newPtr->getType()->getPointerAddressSpace(); 1232212904Sdim 1233212904Sdim // The cookie is always at the start of the buffer. 1234252723Sdim llvm::Value *cookie = newPtr; 1235212904Sdim 1236212904Sdim // The first element is the element size. 1237252723Sdim cookie = CGF.Builder.CreateBitCast(cookie, CGF.SizeTy->getPointerTo(AS)); 1238252723Sdim llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy, 1239252723Sdim getContext().getTypeSizeInChars(elementType).getQuantity()); 1240252723Sdim CGF.Builder.CreateStore(elementSize, cookie); 1241212904Sdim 1242212904Sdim // The second element is the element count. 1243252723Sdim cookie = CGF.Builder.CreateConstInBoundsGEP1_32(cookie, 1); 1244252723Sdim CGF.Builder.CreateStore(numElements, cookie); 1245212904Sdim 1246212904Sdim // Finally, compute a pointer to the actual data buffer by skipping 1247212904Sdim // over the cookie completely. 1248252723Sdim CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType); 1249252723Sdim return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 1250252723Sdim cookieSize.getQuantity()); 1251212904Sdim} 1252212904Sdim 1253245431Sdimllvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 1254245431Sdim llvm::Value *allocPtr, 1255245431Sdim CharUnits cookieSize) { 1256245431Sdim // The number of elements is at offset sizeof(size_t) relative to 1257245431Sdim // the allocated pointer. 1258245431Sdim llvm::Value *numElementsPtr 1259245431Sdim = CGF.Builder.CreateConstInBoundsGEP1_64(allocPtr, CGF.SizeSizeInBytes); 1260212904Sdim 1261245431Sdim unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 1262245431Sdim numElementsPtr = 1263245431Sdim CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS)); 1264245431Sdim return CGF.Builder.CreateLoad(numElementsPtr); 1265212904Sdim} 1266212904Sdim 1267218893Sdim/*********************** Static local initialization **************************/ 1268218893Sdim 1269218893Sdimstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM, 1270224145Sdim llvm::PointerType *GuardPtrTy) { 1271218893Sdim // int __cxa_guard_acquire(__guard *guard_object); 1272226890Sdim llvm::FunctionType *FTy = 1273218893Sdim llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy), 1274226890Sdim GuardPtrTy, /*isVarArg=*/false); 1275235633Sdim return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire", 1276252723Sdim llvm::AttributeSet::get(CGM.getLLVMContext(), 1277252723Sdim llvm::AttributeSet::FunctionIndex, 1278252723Sdim llvm::Attribute::NoUnwind)); 1279218893Sdim} 1280218893Sdim 1281218893Sdimstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM, 1282224145Sdim llvm::PointerType *GuardPtrTy) { 1283218893Sdim // void __cxa_guard_release(__guard *guard_object); 1284226890Sdim llvm::FunctionType *FTy = 1285235633Sdim llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); 1286235633Sdim return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release", 1287252723Sdim llvm::AttributeSet::get(CGM.getLLVMContext(), 1288252723Sdim llvm::AttributeSet::FunctionIndex, 1289252723Sdim llvm::Attribute::NoUnwind)); 1290218893Sdim} 1291218893Sdim 1292218893Sdimstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM, 1293224145Sdim llvm::PointerType *GuardPtrTy) { 1294218893Sdim // void __cxa_guard_abort(__guard *guard_object); 1295226890Sdim llvm::FunctionType *FTy = 1296235633Sdim llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); 1297235633Sdim return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort", 1298252723Sdim llvm::AttributeSet::get(CGM.getLLVMContext(), 1299252723Sdim llvm::AttributeSet::FunctionIndex, 1300252723Sdim llvm::Attribute::NoUnwind)); 1301218893Sdim} 1302218893Sdim 1303218893Sdimnamespace { 1304218893Sdim struct CallGuardAbort : EHScopeStack::Cleanup { 1305218893Sdim llvm::GlobalVariable *Guard; 1306218893Sdim CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} 1307218893Sdim 1308224145Sdim void Emit(CodeGenFunction &CGF, Flags flags) { 1309252723Sdim CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()), 1310252723Sdim Guard); 1311218893Sdim } 1312218893Sdim }; 1313218893Sdim} 1314218893Sdim 1315218893Sdim/// The ARM code here follows the Itanium code closely enough that we 1316218893Sdim/// just special-case it at particular places. 1317218893Sdimvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, 1318218893Sdim const VarDecl &D, 1319235633Sdim llvm::GlobalVariable *var, 1320235633Sdim bool shouldPerformInit) { 1321218893Sdim CGBuilderTy &Builder = CGF.Builder; 1322218893Sdim 1323252723Sdim // We only need to use thread-safe statics for local non-TLS variables; 1324218893Sdim // global initialization is always single-threaded. 1325252723Sdim bool threadsafe = getContext().getLangOpts().ThreadsafeStatics && 1326252723Sdim D.isLocalVarDecl() && !D.getTLSKind(); 1327221345Sdim 1328221345Sdim // If we have a global variable with internal linkage and thread-safe statics 1329221345Sdim // are disabled, we can just let the guard variable be of type i8. 1330235633Sdim bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage(); 1331235633Sdim 1332235633Sdim llvm::IntegerType *guardTy; 1333224145Sdim if (useInt8GuardVariable) { 1334235633Sdim guardTy = CGF.Int8Ty; 1335224145Sdim } else { 1336252723Sdim // Guard variables are 64 bits in the generic ABI and size width on ARM 1337252723Sdim // (i.e. 32-bit on AArch32, 64-bit on AArch64). 1338263509Sdim guardTy = (UseARMGuardVarABI ? CGF.SizeTy : CGF.Int64Ty); 1339221345Sdim } 1340235633Sdim llvm::PointerType *guardPtrTy = guardTy->getPointerTo(); 1341218893Sdim 1342235633Sdim // Create the guard variable if we don't already have it (as we 1343235633Sdim // might if we're double-emitting this function body). 1344235633Sdim llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D); 1345235633Sdim if (!guard) { 1346235633Sdim // Mangle the name for the guard. 1347235633Sdim SmallString<256> guardName; 1348235633Sdim { 1349235633Sdim llvm::raw_svector_ostream out(guardName); 1350263509Sdim getMangleContext().mangleStaticGuardVariable(&D, out); 1351235633Sdim out.flush(); 1352235633Sdim } 1353218893Sdim 1354235633Sdim // Create the guard variable with a zero-initializer. 1355235633Sdim // Just absorb linkage and visibility from the guarded variable. 1356235633Sdim guard = new llvm::GlobalVariable(CGM.getModule(), guardTy, 1357235633Sdim false, var->getLinkage(), 1358235633Sdim llvm::ConstantInt::get(guardTy, 0), 1359235633Sdim guardName.str()); 1360235633Sdim guard->setVisibility(var->getVisibility()); 1361252723Sdim // If the variable is thread-local, so is its guard variable. 1362252723Sdim guard->setThreadLocalMode(var->getThreadLocalMode()); 1363218893Sdim 1364235633Sdim CGM.setStaticLocalDeclGuardAddress(&D, guard); 1365235633Sdim } 1366235633Sdim 1367218893Sdim // Test whether the variable has completed initialization. 1368235633Sdim llvm::Value *isInitialized; 1369218893Sdim 1370218893Sdim // ARM C++ ABI 3.2.3.1: 1371218893Sdim // To support the potential use of initialization guard variables 1372218893Sdim // as semaphores that are the target of ARM SWP and LDREX/STREX 1373218893Sdim // synchronizing instructions we define a static initialization 1374218893Sdim // guard variable to be a 4-byte aligned, 4- byte word with the 1375218893Sdim // following inline access protocol. 1376218893Sdim // #define INITIALIZED 1 1377218893Sdim // if ((obj_guard & INITIALIZED) != INITIALIZED) { 1378218893Sdim // if (__cxa_guard_acquire(&obj_guard)) 1379218893Sdim // ... 1380218893Sdim // } 1381263509Sdim if (UseARMGuardVarABI && !useInt8GuardVariable) { 1382235633Sdim llvm::Value *V = Builder.CreateLoad(guard); 1383252723Sdim llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1); 1384252723Sdim V = Builder.CreateAnd(V, Test1); 1385235633Sdim isInitialized = Builder.CreateIsNull(V, "guard.uninitialized"); 1386218893Sdim 1387218893Sdim // Itanium C++ ABI 3.3.2: 1388218893Sdim // The following is pseudo-code showing how these functions can be used: 1389218893Sdim // if (obj_guard.first_byte == 0) { 1390218893Sdim // if ( __cxa_guard_acquire (&obj_guard) ) { 1391218893Sdim // try { 1392218893Sdim // ... initialize the object ...; 1393218893Sdim // } catch (...) { 1394218893Sdim // __cxa_guard_abort (&obj_guard); 1395218893Sdim // throw; 1396218893Sdim // } 1397218893Sdim // ... queue object destructor with __cxa_atexit() ...; 1398218893Sdim // __cxa_guard_release (&obj_guard); 1399218893Sdim // } 1400218893Sdim // } 1401218893Sdim } else { 1402218893Sdim // Load the first byte of the guard variable. 1403226890Sdim llvm::LoadInst *LI = 1404235633Sdim Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy)); 1405226890Sdim LI->setAlignment(1); 1406218893Sdim 1407226890Sdim // Itanium ABI: 1408226890Sdim // An implementation supporting thread-safety on multiprocessor 1409226890Sdim // systems must also guarantee that references to the initialized 1410226890Sdim // object do not occur before the load of the initialization flag. 1411226890Sdim // 1412226890Sdim // In LLVM, we do this by marking the load Acquire. 1413226890Sdim if (threadsafe) 1414226890Sdim LI->setAtomic(llvm::Acquire); 1415226890Sdim 1416235633Sdim isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized"); 1417218893Sdim } 1418218893Sdim 1419218893Sdim llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check"); 1420218893Sdim llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end"); 1421218893Sdim 1422218893Sdim // Check if the first byte of the guard variable is zero. 1423235633Sdim Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock); 1424218893Sdim 1425218893Sdim CGF.EmitBlock(InitCheckBlock); 1426218893Sdim 1427218893Sdim // Variables used when coping with thread-safe statics and exceptions. 1428224145Sdim if (threadsafe) { 1429218893Sdim // Call __cxa_guard_acquire. 1430218893Sdim llvm::Value *V 1431252723Sdim = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard); 1432218893Sdim 1433218893Sdim llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); 1434218893Sdim 1435218893Sdim Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 1436218893Sdim InitBlock, EndBlock); 1437218893Sdim 1438218893Sdim // Call __cxa_guard_abort along the exceptional edge. 1439235633Sdim CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard); 1440218893Sdim 1441218893Sdim CGF.EmitBlock(InitBlock); 1442218893Sdim } 1443218893Sdim 1444218893Sdim // Emit the initializer and add a global destructor if appropriate. 1445235633Sdim CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit); 1446218893Sdim 1447224145Sdim if (threadsafe) { 1448218893Sdim // Pop the guard-abort cleanup if we pushed one. 1449218893Sdim CGF.PopCleanupBlock(); 1450218893Sdim 1451218893Sdim // Call __cxa_guard_release. This cannot throw. 1452252723Sdim CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard); 1453218893Sdim } else { 1454235633Sdim Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard); 1455218893Sdim } 1456218893Sdim 1457218893Sdim CGF.EmitBlock(EndBlock); 1458218893Sdim} 1459245431Sdim 1460245431Sdim/// Register a global destructor using __cxa_atexit. 1461245431Sdimstatic void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, 1462245431Sdim llvm::Constant *dtor, 1463252723Sdim llvm::Constant *addr, 1464252723Sdim bool TLS) { 1465252723Sdim const char *Name = "__cxa_atexit"; 1466252723Sdim if (TLS) { 1467252723Sdim const llvm::Triple &T = CGF.getTarget().getTriple(); 1468252723Sdim Name = T.isMacOSX() ? "_tlv_atexit" : "__cxa_thread_atexit"; 1469252723Sdim } 1470252723Sdim 1471245431Sdim // We're assuming that the destructor function is something we can 1472245431Sdim // reasonably call with the default CC. Go ahead and cast it to the 1473245431Sdim // right prototype. 1474245431Sdim llvm::Type *dtorTy = 1475245431Sdim llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo(); 1476245431Sdim 1477245431Sdim // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d); 1478245431Sdim llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy }; 1479245431Sdim llvm::FunctionType *atexitTy = 1480245431Sdim llvm::FunctionType::get(CGF.IntTy, paramTys, false); 1481245431Sdim 1482245431Sdim // Fetch the actual function. 1483252723Sdim llvm::Constant *atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name); 1484245431Sdim if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit)) 1485245431Sdim fn->setDoesNotThrow(); 1486245431Sdim 1487245431Sdim // Create a variable that binds the atexit to this shared object. 1488245431Sdim llvm::Constant *handle = 1489245431Sdim CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle"); 1490245431Sdim 1491245431Sdim llvm::Value *args[] = { 1492245431Sdim llvm::ConstantExpr::getBitCast(dtor, dtorTy), 1493245431Sdim llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy), 1494245431Sdim handle 1495245431Sdim }; 1496252723Sdim CGF.EmitNounwindRuntimeCall(atexit, args); 1497245431Sdim} 1498245431Sdim 1499245431Sdim/// Register a global destructor as best as we know how. 1500245431Sdimvoid ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, 1501252723Sdim const VarDecl &D, 1502245431Sdim llvm::Constant *dtor, 1503245431Sdim llvm::Constant *addr) { 1504245431Sdim // Use __cxa_atexit if available. 1505252723Sdim if (CGM.getCodeGenOpts().CXAAtExit) 1506252723Sdim return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind()); 1507245431Sdim 1508252723Sdim if (D.getTLSKind()) 1509252723Sdim CGM.ErrorUnsupported(&D, "non-trivial TLS destruction"); 1510252723Sdim 1511245431Sdim // In Apple kexts, we want to add a global destructor entry. 1512245431Sdim // FIXME: shouldn't this be guarded by some variable? 1513245431Sdim if (CGM.getLangOpts().AppleKext) { 1514245431Sdim // Generate a global destructor entry. 1515245431Sdim return CGM.AddCXXDtorEntry(dtor, addr); 1516245431Sdim } 1517245431Sdim 1518263509Sdim CGF.registerGlobalDtorWithAtExit(D, dtor, addr); 1519245431Sdim} 1520245431Sdim 1521252723Sdim/// Get the appropriate linkage for the wrapper function. This is essentially 1522252723Sdim/// the weak form of the variable's linkage; every translation unit which wneeds 1523252723Sdim/// the wrapper emits a copy, and we want the linker to merge them. 1524252723Sdimstatic llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage( 1525252723Sdim llvm::GlobalValue::LinkageTypes VarLinkage) { 1526252723Sdim if (llvm::GlobalValue::isLinkerPrivateLinkage(VarLinkage)) 1527252723Sdim return llvm::GlobalValue::LinkerPrivateWeakLinkage; 1528252723Sdim // For internal linkage variables, we don't need an external or weak wrapper. 1529252723Sdim if (llvm::GlobalValue::isLocalLinkage(VarLinkage)) 1530252723Sdim return VarLinkage; 1531252723Sdim return llvm::GlobalValue::WeakODRLinkage; 1532245431Sdim} 1533252723Sdim 1534252723Sdimllvm::Function * 1535252723SdimItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, 1536252723Sdim llvm::GlobalVariable *Var) { 1537252723Sdim // Mangle the name for the thread_local wrapper function. 1538252723Sdim SmallString<256> WrapperName; 1539252723Sdim { 1540252723Sdim llvm::raw_svector_ostream Out(WrapperName); 1541252723Sdim getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out); 1542252723Sdim Out.flush(); 1543252723Sdim } 1544252723Sdim 1545252723Sdim if (llvm::Value *V = Var->getParent()->getNamedValue(WrapperName)) 1546252723Sdim return cast<llvm::Function>(V); 1547252723Sdim 1548252723Sdim llvm::Type *RetTy = Var->getType(); 1549252723Sdim if (VD->getType()->isReferenceType()) 1550252723Sdim RetTy = RetTy->getPointerElementType(); 1551252723Sdim 1552252723Sdim llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false); 1553252723Sdim llvm::Function *Wrapper = llvm::Function::Create( 1554252723Sdim FnTy, getThreadLocalWrapperLinkage(Var->getLinkage()), WrapperName.str(), 1555252723Sdim &CGM.getModule()); 1556252723Sdim // Always resolve references to the wrapper at link time. 1557252723Sdim Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); 1558252723Sdim return Wrapper; 1559252723Sdim} 1560252723Sdim 1561252723Sdimvoid ItaniumCXXABI::EmitThreadLocalInitFuncs( 1562252723Sdim llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls, 1563252723Sdim llvm::Function *InitFunc) { 1564252723Sdim for (unsigned I = 0, N = Decls.size(); I != N; ++I) { 1565252723Sdim const VarDecl *VD = Decls[I].first; 1566252723Sdim llvm::GlobalVariable *Var = Decls[I].second; 1567252723Sdim 1568252723Sdim // Mangle the name for the thread_local initialization function. 1569252723Sdim SmallString<256> InitFnName; 1570252723Sdim { 1571252723Sdim llvm::raw_svector_ostream Out(InitFnName); 1572252723Sdim getMangleContext().mangleItaniumThreadLocalInit(VD, Out); 1573252723Sdim Out.flush(); 1574252723Sdim } 1575252723Sdim 1576252723Sdim // If we have a definition for the variable, emit the initialization 1577252723Sdim // function as an alias to the global Init function (if any). Otherwise, 1578252723Sdim // produce a declaration of the initialization function. 1579252723Sdim llvm::GlobalValue *Init = 0; 1580252723Sdim bool InitIsInitFunc = false; 1581252723Sdim if (VD->hasDefinition()) { 1582252723Sdim InitIsInitFunc = true; 1583252723Sdim if (InitFunc) 1584252723Sdim Init = 1585252723Sdim new llvm::GlobalAlias(InitFunc->getType(), Var->getLinkage(), 1586252723Sdim InitFnName.str(), InitFunc, &CGM.getModule()); 1587252723Sdim } else { 1588252723Sdim // Emit a weak global function referring to the initialization function. 1589252723Sdim // This function will not exist if the TU defining the thread_local 1590252723Sdim // variable in question does not need any dynamic initialization for 1591252723Sdim // its thread_local variables. 1592252723Sdim llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false); 1593252723Sdim Init = llvm::Function::Create( 1594252723Sdim FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(), 1595252723Sdim &CGM.getModule()); 1596252723Sdim } 1597252723Sdim 1598252723Sdim if (Init) 1599252723Sdim Init->setVisibility(Var->getVisibility()); 1600252723Sdim 1601252723Sdim llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var); 1602252723Sdim llvm::LLVMContext &Context = CGM.getModule().getContext(); 1603252723Sdim llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper); 1604252723Sdim CGBuilderTy Builder(Entry); 1605252723Sdim if (InitIsInitFunc) { 1606252723Sdim if (Init) 1607252723Sdim Builder.CreateCall(Init); 1608252723Sdim } else { 1609252723Sdim // Don't know whether we have an init function. Call it if it exists. 1610252723Sdim llvm::Value *Have = Builder.CreateIsNotNull(Init); 1611252723Sdim llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper); 1612252723Sdim llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper); 1613252723Sdim Builder.CreateCondBr(Have, InitBB, ExitBB); 1614252723Sdim 1615252723Sdim Builder.SetInsertPoint(InitBB); 1616252723Sdim Builder.CreateCall(Init); 1617252723Sdim Builder.CreateBr(ExitBB); 1618252723Sdim 1619252723Sdim Builder.SetInsertPoint(ExitBB); 1620252723Sdim } 1621252723Sdim 1622252723Sdim // For a reference, the result of the wrapper function is a pointer to 1623252723Sdim // the referenced object. 1624252723Sdim llvm::Value *Val = Var; 1625252723Sdim if (VD->getType()->isReferenceType()) { 1626252723Sdim llvm::LoadInst *LI = Builder.CreateLoad(Val); 1627252723Sdim LI->setAlignment(CGM.getContext().getDeclAlign(VD).getQuantity()); 1628252723Sdim Val = LI; 1629252723Sdim } 1630252723Sdim 1631252723Sdim Builder.CreateRet(Val); 1632252723Sdim } 1633252723Sdim} 1634252723Sdim 1635252723SdimLValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF, 1636252723Sdim const DeclRefExpr *DRE) { 1637252723Sdim const VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1638252723Sdim QualType T = VD->getType(); 1639252723Sdim llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T); 1640252723Sdim llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty); 1641252723Sdim llvm::Function *Wrapper = 1642252723Sdim getOrCreateThreadLocalWrapper(VD, cast<llvm::GlobalVariable>(Val)); 1643252723Sdim 1644252723Sdim Val = CGF.Builder.CreateCall(Wrapper); 1645252723Sdim 1646252723Sdim LValue LV; 1647252723Sdim if (VD->getType()->isReferenceType()) 1648252723Sdim LV = CGF.MakeNaturalAlignAddrLValue(Val, T); 1649252723Sdim else 1650252723Sdim LV = CGF.MakeAddrLValue(Val, DRE->getType(), 1651252723Sdim CGF.getContext().getDeclAlign(VD)); 1652252723Sdim // FIXME: need setObjCGCLValueClass? 1653252723Sdim return LV; 1654252723Sdim} 1655263509Sdim 1656263509Sdim/// Return whether the given global decl needs a VTT parameter, which it does 1657263509Sdim/// if it's a base constructor or destructor with virtual bases. 1658263509Sdimbool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) { 1659263509Sdim const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 1660263509Sdim 1661263509Sdim // We don't have any virtual bases, just return early. 1662263509Sdim if (!MD->getParent()->getNumVBases()) 1663263509Sdim return false; 1664263509Sdim 1665263509Sdim // Check if we have a base constructor. 1666263509Sdim if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) 1667263509Sdim return true; 1668263509Sdim 1669263509Sdim // Check if we have a base destructor. 1670263509Sdim if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 1671263509Sdim return true; 1672263509Sdim 1673263509Sdim return false; 1674263509Sdim} 1675