13a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===// 23a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// 33a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// The LLVM Compiler Infrastructure 43a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// 53a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// This file is distributed under the University of Illinois Open Source 63a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// License. See LICENSE.TXT for details. 73a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// 83a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis//===----------------------------------------------------------------------===// 93a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ code generation targeting the Itanium C++ ABI. The class 113a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// in this file generates structures that follow the Itanium C++ ABI, which is 123a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// documented at: 133a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// http://www.codesourcery.com/public/cxx-abi/abi.html 143a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis// http://www.codesourcery.com/public/cxx-abi/abi-eh.html 15ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// 16ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// It also supports the closely-related ARM ABI, documented at: 17ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 18ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall// 193a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis//===----------------------------------------------------------------------===// 203a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis 213a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#include "CGCXXABI.h" 223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "CGCleanup.h" 230bab0cdab751248ca389a5592bcb70eac5d39260John McCall#include "CGRecordLayout.h" 249ee494f98610dcd79441dce469d7bf609fcd7b92Charles Davis#include "CGVTables.h" 2593d557bc1867b7d7b102f87290194b4be7932c92John McCall#include "CodeGenFunction.h" 263a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis#include "CodeGenModule.h" 273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "TargetInfo.h" 28ba77cb9c82cc9d498e4d6474d128007249f07871Craig Topper#include "clang/AST/Mangle.h" 29ba77cb9c82cc9d498e4d6474d128007249f07871Craig Topper#include "clang/AST/Type.h" 303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "clang/AST/StmtCXX.h" 31c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include "llvm/IR/CallSite.h" 323b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/DataLayout.h" 333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "llvm/IR/Instructions.h" 343b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Intrinsics.h" 353b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Value.h" 363a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis 373a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davisusing namespace clang; 3893d557bc1867b7d7b102f87290194b4be7932c92John McCallusing namespace CodeGen; 393a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis 403a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davisnamespace { 41071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass ItaniumCXXABI : public CodeGen::CGCXXABI { 42a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov /// VTables - All the vtables which have been defined. 43a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; 44a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 4593d557bc1867b7d7b102f87290194b4be7932c92John McCallprotected: 4621fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn bool UseARMMethodPtrABI; 4721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn bool UseARMGuardVarABI; 480bab0cdab751248ca389a5592bcb70eac5d39260John McCall 4911f22a35b7f08a8d017f6ab26e440edffc930f96Timur Iskhodzhanov ItaniumMangleContext &getMangleContext() { 5011f22a35b7f08a8d017f6ab26e440edffc930f96Timur Iskhodzhanov return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext()); 5111f22a35b7f08a8d017f6ab26e440edffc930f96Timur Iskhodzhanov } 5211f22a35b7f08a8d017f6ab26e440edffc930f96Timur Iskhodzhanov 533a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davispublic: 5421fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn ItaniumCXXABI(CodeGen::CodeGenModule &CGM, 5521fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn bool UseARMMethodPtrABI = false, 5621fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn bool UseARMGuardVarABI = false) : 5721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), 5821fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn UseARMGuardVarABI(UseARMGuardVarABI) { } 5993d557bc1867b7d7b102f87290194b4be7932c92John McCall 606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool classifyReturnType(CGFunctionInfo &FI) const override; 61ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override { 63ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov // Structures with either a non-trivial destructor or a non-trivial 64ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov // copy constructor are always indirect. 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared 666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // special members. 676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) 68ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_Indirect; 69ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_Default; 70ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov } 71ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 72a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool isThisCompleteObject(GlobalDecl GD) const override { 73a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // The Itanium ABI has separate complete-object vs. base-object 74a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // variants of both constructors and destructors. 75a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (isa<CXXDestructorDecl>(GD.getDecl())) { 76a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar switch (GD.getDtorType()) { 77a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Dtor_Complete: 78a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Dtor_Deleting: 79a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 80a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 81a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Dtor_Base: 82a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 83a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 84a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Dtor_Comdat: 85a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("emitting dtor comdat as function?"); 86a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 87a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("bad dtor kind"); 88a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 89a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (isa<CXXConstructorDecl>(GD.getDecl())) { 90a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar switch (GD.getCtorType()) { 91a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Ctor_Complete: 92a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 93a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 94a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Ctor_Base: 95a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 96a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 97a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Ctor_CopyingClosure: 98a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Ctor_DefaultClosure: 99a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("closure ctors in Itanium ABI?"); 100a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 101a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Ctor_Comdat: 102a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("emitting ctor comdat as function?"); 103a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 104a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm_unreachable("bad dtor kind"); 105a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 106a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 107a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // No other kinds. 108a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 109a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 110a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isZeroInitializable(const MemberPointerType *MPT) override; 112cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; 1140bab0cdab751248ca389a5592bcb70eac5d39260John McCall 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value * 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *E, 118a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, 119a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *&ThisPtrForCall, 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *MemFnPtr, 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberPointerType *MPT) override; 1223023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value * 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, 125a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address Base, 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *MemPtr, 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberPointerType *MPT) override; 1286c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 1290bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 1300bab0cdab751248ca389a5592bcb70eac5d39260John McCall const CastExpr *E, 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *Src) override; 1324d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Constant *Src) override; 134cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override; 136cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall 137a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override; 1385808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits offset) override; 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override; 1412d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD, 1422d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CharUnits ThisAdjustment); 143875ab10245d3bf37252dd822aa1616bb0a391095John McCall 1440bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *L, llvm::Value *R, 1460bab0cdab751248ca389a5592bcb70eac5d39260John McCall const MemberPointerType *MPT, 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Inequality) override; 148e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 1490bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *Addr, 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberPointerType *MPT) override; 1524c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 153176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, 154a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address Ptr, QualType ElementType, 155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXDestructorDecl *Dtor) override; 156ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 157a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// Itanium says that an _Unwind_Exception has to be "double-word" 158a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// aligned (and thus the end of it is also so-aligned), meaning 16 159a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// bytes. Of course, that was written for the actual Itanium, 160a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// which is a 64-bit platform. Classically, the ABI doesn't really 161a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// specify the alignment on other platforms, but in practice 162a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// libUnwind declares the struct with __attribute__((aligned)), so 163a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// we assume that alignment here. (It's generally 16 bytes, but 164a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// some targets overwrite it.) 165a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits getAlignmentOfExnObject() { 166a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned(); 167a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGM.getContext().toCharUnitsFromBits(align); 168a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 169a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override; 1713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override; 1723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override; 1743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::CallInst * 1763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar emitTerminateForUnexpectedException(CodeGenFunction &CGF, 1773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Exn) override; 1780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 179c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void EmitFundamentalRTTIDescriptor(QualType Type); 180c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void EmitFundamentalRTTIDescriptors(); 181c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; 182a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CatchTypeInfo 18358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar getAddrOfCXXCatchHandlerType(QualType Ty, 18458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar QualType CatchHandlerType) override { 185a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0}; 1863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 187c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; 189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void EmitBadTypeidCall(CodeGenFunction &CGF) override; 190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, 191a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address ThisPtr, 192c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *StdTypeInfoPtrTy) override; 193c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 194c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, 195c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy) override; 196c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 197a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, Address Value, 198c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy, QualType DestTy, 199c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType DestRecordTy, 200c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::BasicBlock *CastEnd) override; 201c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 202a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, 203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy, 204c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType DestTy) override; 205c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool EmitBadCastCall(CodeGenFunction &CGF) override; 207c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value * 209a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *ClassDecl, 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *BaseClassDecl) override; 212b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EmitCXXConstructors(const CXXConstructorDecl *D) override; 214bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov 215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void buildStructorSignature(const CXXMethodDecl *MD, StructorType T, 216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallVectorImpl<CanQualType> &ArgTys) override; 2174c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 218a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CXXDtorType DT) const override { 220a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Itanium does not emit any destructor variant as an inline thunk. 221a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Delegating may occur as an optimization, but all variants are either 222a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // emitted with external linkage or as linkonce if they are inline and used. 223a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner return false; 224a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner } 225a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EmitCXXDestructors(const CXXDestructorDecl *D) override; 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FunctionArgList &Params) override; 230a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override; 2324c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned addImplicitConstructorArgs(CodeGenFunction &CGF, 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXConstructorDecl *D, 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CXXCtorType Type, bool ForVirtualBase, 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Delegating, 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallArgList &Args) override; 2381e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CXXDtorType Type, bool ForVirtualBase, 241a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool Delegating, Address This) override; 2424444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void emitVTableDefinitions(CodeGenVTables &CGVT, 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *RD) override; 245a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 246a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, 247a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction::VPtr Vptr) override; 248a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 249a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override { 250a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 251a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 252a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 253a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Constant * 254a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar getVTableAddressPoint(BaseSubobject Base, 255a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *VTableClass) override; 256a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 257a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::Value *getVTableAddressPointInStructor( 258a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, 259a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar BaseSubobject Base, const CXXRecordDecl *NearestVBase) override; 260a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 261a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *getVTableAddressPointInStructorWithVTT( 262a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, 263a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar BaseSubobject Base, const CXXRecordDecl *NearestVBase); 264a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 265a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::Constant * 266a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov getVTableAddressPointForConstExpr(BaseSubobject Base, 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *VTableClass) override; 268a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 269a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits VPtrOffset) override; 271a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 2728f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, 273a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, llvm::Type *Ty, 274a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SourceLocation Loc) override; 2758f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov 276176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, 277176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXDestructorDecl *Dtor, 278176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXDtorType DtorType, 279a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, 280176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXMemberCallExpr *CE) override; 2810f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override; 2839063302a82423cb83f002257a416741850739a70Reid Kleckner 284a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override; 285a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 286c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, 287c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool ReturnAdjustment) override { 2882cb17a06befb61b1434aaa991652fea4338c95d7Timur Iskhodzhanov // Allow inlining of thunks by emitting them with available_externally 2892cb17a06befb61b1434aaa991652fea4338c95d7Timur Iskhodzhanov // linkage together with vtables when needed. 290a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (ForVTable && !Thunk->hasLocalLinkage()) 2912cb17a06befb61b1434aaa991652fea4338c95d7Timur Iskhodzhanov Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); 2922cb17a06befb61b1434aaa991652fea4338c95d7Timur Iskhodzhanov } 2932cb17a06befb61b1434aaa991652fea4338c95d7Timur Iskhodzhanov 294a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This, 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ThisAdjustment &TA) override; 296c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 297a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret, 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ReturnAdjustment &RA) override; 299c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 300176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, 301176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines FunctionArgList &Args) const override { 302176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(!Args.empty() && "expected the arglist to not be empty!"); 303176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Args.size() - 1; 304176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 305176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; } 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef GetDeletedVirtualCallName() override 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines { return "__cxa_deleted_virtual"; } 309285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits getArrayCookieSizeImpl(QualType elementType) override; 311a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address InitializeArrayCookie(CodeGenFunction &CGF, 312a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address NewPtr, 313a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *NumElements, 314a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXNewExpr *expr, 315a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar QualType ElementType) override; 316e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 317a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address allocPtr, 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits cookieSize) override; 3195cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 3203030eb82593097502469a8b3fc26112c79c75605John McCall void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::GlobalVariable *DeclPtr, 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool PerformInit) override; 32304e517650569598e847c2ab609672e6df93effe5Richard Smith void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Constant *dtor, llvm::Constant *addr) override; 325b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 326b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD, 327176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Val); 328b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith void EmitThreadLocalInitFuncs( 329176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenModule &CGM, 330a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ArrayRef<const VarDecl *> CXXThreadLocals, 331176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ArrayRef<llvm::Function *> CXXThreadLocalInits, 332a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override; 333176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 334176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool usesThreadWrapperFunction() const override { return true; } 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType LValType) override; 337e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool NeedsVTTParameter(GlobalDecl GD) override; 339c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 340c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /**************************** RTTI Uniqueness ******************************/ 341c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 342c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesprotected: 343c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// Returns true if the ABI requires RTTI type_info objects to be unique 344c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// across a program. 345c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines virtual bool shouldRTTIBeUnique() const { return true; } 346c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 347c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinespublic: 348c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// What sort of unique-RTTI behavior should we use? 349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines enum RTTIUniquenessKind { 350c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// We are guaranteeing, or need to guarantee, that the RTTI string 351c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// is unique. 352c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines RUK_Unique, 353c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 354c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// We are not guaranteeing uniqueness for the RTTI string, so we 355c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// can demote to hidden visibility but must use string comparisons. 356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines RUK_NonUniqueHidden, 357c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 358c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// We are not guaranteeing uniqueness for the RTTI string, so we 359c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// have to use string comparisons, but we also have to emit it with 360c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// non-hidden visibility. 361c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines RUK_NonUniqueVisible 362c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 363c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 364c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// Return the required visibility status for the given type and linkage in 365c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// the current ABI. 366c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines RTTIUniquenessKind 367c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines classifyRTTIUniqueness(QualType CanTy, 368c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalValue::LinkageTypes Linkage) const; 369c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines friend class ItaniumRTTIBuilder; 370176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; 372a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 373a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar private: 374a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool hasAnyUsedVirtualInlineFunction(const CXXRecordDecl *RD) const { 375a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const auto &VtableLayout = 376a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getItaniumVTableContext().getVTableLayout(RD); 377a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 378a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (const auto &VtableComponent : VtableLayout.vtable_components()) { 379a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!VtableComponent.isUsedFunctionPointerKind()) 380a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar continue; 381a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 382a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); 383a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (Method->getCanonicalDecl()->isInlined()) 384a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 385a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 386a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 387a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 388a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 389a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool isVTableHidden(const CXXRecordDecl *RD) const { 390a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const auto &VtableLayout = 391a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getItaniumVTableContext().getVTableLayout(RD); 392a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 393a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (const auto &VtableComponent : VtableLayout.vtable_components()) { 394a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (VtableComponent.isRTTIKind()) { 395a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl(); 396a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (RTTIDecl->getVisibility() == Visibility::HiddenVisibility) 397a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 398a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else if (VtableComponent.isUsedFunctionPointerKind()) { 399a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); 400a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (Method->getVisibility() == Visibility::HiddenVisibility && 401a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar !Method->isDefined()) 402a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return true; 403a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 404a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 405a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 406a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 4073a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis}; 408ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall 409ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCallclass ARMCXXABI : public ItaniumCXXABI { 410ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCallpublic: 41121fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn ARMCXXABI(CodeGen::CodeGenModule &CGM) : 41221fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 41321fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn /* UseARMGuardVarABI = */ true) {} 4144c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasThisReturn(GlobalDecl GD) const override { 4163b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin return (isa<CXXConstructorDecl>(GD.getDecl()) || ( 4173b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin isa<CXXDestructorDecl>(GD.getDecl()) && 4183b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin GD.getDtorType() != Dtor_Deleting)); 4193b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin } 4204c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, 422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType ResTy) override; 4234c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits getArrayCookieSizeImpl(QualType elementType) override; 425a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address InitializeArrayCookie(CodeGenFunction &CGF, 426a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address NewPtr, 427a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *NumElements, 428a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXNewExpr *expr, 429a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar QualType ElementType) override; 430a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr, 431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharUnits cookieSize) override; 432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass iOS64CXXABI : public ARMCXXABI { 435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {} 437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // ARM64 libraries are prepared for non-unique RTTI. 439c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool shouldRTTIBeUnique() const override { return false; } 440ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall}; 441a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 442a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarclass WebAssemblyCXXABI final : public ItaniumCXXABI { 443a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarpublic: 444a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM) 445a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true, 446a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /*UseARMGuardVarABI=*/true) {} 447a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 448a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarprivate: 449a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool HasThisReturn(GlobalDecl GD) const override { 450a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return isa<CXXConstructorDecl>(GD.getDecl()) || 451a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar (isa<CXXDestructorDecl>(GD.getDecl()) && 452a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar GD.getDtorType() != Dtor_Deleting); 453a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 454a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar}; 4553a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis} 4563a811f1f4286ee3fd0c563c1cfe623956f3caa24Charles Davis 457071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { 45864aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall switch (CGM.getTarget().getCXXABI().getKind()) { 45996fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall // For IR-generation purposes, there's no significant difference 46096fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall // between the ARM and iOS ABIs. 46196fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall case TargetCXXABI::GenericARM: 46296fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall case TargetCXXABI::iOS: 463a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case TargetCXXABI::WatchOS: 46496fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall return new ARMCXXABI(CGM); 46596fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall 466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case TargetCXXABI::iOS64: 467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new iOS64CXXABI(CGM); 468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 469c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't 470c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover // include the other 32-bit ARM oddities: constructor/destructor return values 471c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover // and array cookies. 472c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover case TargetCXXABI::GenericAArch64: 47321fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 47421fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn /* UseARMGuardVarABI = */ true); 475c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover 4760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines case TargetCXXABI::GenericMIPS: 4770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true); 4780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 479a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case TargetCXXABI::WebAssembly: 480a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return new WebAssemblyCXXABI(CGM); 481a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 48296fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall case TargetCXXABI::GenericItanium: 48321fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (CGM.getContext().getTargetInfo().getTriple().getArch() 48421fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn == llvm::Triple::le32) { 48521fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn // For PNaCl, use ARM-style method pointers so that PNaCl code 48621fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn // does not assume anything about the alignment of function 48721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn // pointers. 48821fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, 48921fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn /* UseARMGuardVarABI = */ false); 49021fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn } 49196fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall return new ItaniumCXXABI(CGM); 49296fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall 49396fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall case TargetCXXABI::Microsoft: 49496fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall llvm_unreachable("Microsoft ABI is not Itanium-based"); 49596fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall } 49696fcde0b8ed8bdf99d326312ca7be6447b0fe5fcJohn McCall llvm_unreachable("bad ABI kind"); 497ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall} 498ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall 4999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattnerllvm::Type * 5000bab0cdab751248ca389a5592bcb70eac5d39260John McCallItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 5010bab0cdab751248ca389a5592bcb70eac5d39260John McCall if (MPT->isMemberDataPointer()) 50292e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner return CGM.PtrDiffTy; 5030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, nullptr); 504875ab10245d3bf37252dd822aa1616bb0a391095John McCall} 505875ab10245d3bf37252dd822aa1616bb0a391095John McCall 506babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// In the Itanium and ARM ABIs, method pointers have the form: 507babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr; 508babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// 509babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// In the Itanium ABI: 510babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - method pointers are virtual if (memptr.ptr & 1) is nonzero 511babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - the this-adjustment is (memptr.adj) 512babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - the virtual offset is (memptr.ptr - 1) 513babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// 514babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// In the ARM ABI: 515babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - method pointers are virtual if (memptr.adj & 1) is nonzero 516babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - the this-adjustment is (memptr.adj >> 1) 517babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// - the virtual offset is (memptr.ptr) 518babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// ARM uses 'adj' for the virtual flag because Thumb functions 519babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// may be only single-byte aligned. 520babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// 521babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// If the member is virtual, the adjusted 'this' pointer points 522babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// to a vtable pointer from which the virtual offset is applied. 523babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// 524babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// If the member is non-virtual, memptr.ptr is the address of 525babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall/// the function to call. 526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesllvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( 527a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, const Expr *E, Address ThisAddr, 528a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *&ThisPtrForCall, 529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *MemFnPtr, const MemberPointerType *MPT) { 53093d557bc1867b7d7b102f87290194b4be7932c92John McCall CGBuilderTy &Builder = CGF.Builder; 53193d557bc1867b7d7b102f87290194b4be7932c92John McCall 53293d557bc1867b7d7b102f87290194b4be7932c92John McCall const FunctionProtoType *FPT = 53393d557bc1867b7d7b102f87290194b4be7932c92John McCall MPT->getPointeeType()->getAs<FunctionProtoType>(); 53493d557bc1867b7d7b102f87290194b4be7932c92John McCall const CXXRecordDecl *RD = 53593d557bc1867b7d7b102f87290194b4be7932c92John McCall cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); 53693d557bc1867b7d7b102f87290194b4be7932c92John McCall 537a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType( 538a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr)); 53993d557bc1867b7d7b102f87290194b4be7932c92John McCall 54092e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1); 54193d557bc1867b7d7b102f87290194b4be7932c92John McCall 542babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual"); 543babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual"); 544babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end"); 545babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall 546d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // Extract memptr.adj, which is in the second field. 547d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj"); 548babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall 549babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall // Compute the true adjustment. 550babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::Value *Adj = RawAdj; 55121fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) 552babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted"); 55393d557bc1867b7d7b102f87290194b4be7932c92John McCall 55493d557bc1867b7d7b102f87290194b4be7932c92John McCall // Apply the adjustment and cast back to the original struct type 55593d557bc1867b7d7b102f87290194b4be7932c92John McCall // for consistency. 556a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *This = ThisAddr.getPointer(); 557babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 558babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall Ptr = Builder.CreateInBoundsGEP(Ptr, Adj); 559babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 560a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ThisPtrForCall = This; 56193d557bc1867b7d7b102f87290194b4be7932c92John McCall 56293d557bc1867b7d7b102f87290194b4be7932c92John McCall // Load the function pointer. 563d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr"); 56493d557bc1867b7d7b102f87290194b4be7932c92John McCall 56593d557bc1867b7d7b102f87290194b4be7932c92John McCall // If the LSB in the function pointer is 1, the function pointer points to 56693d557bc1867b7d7b102f87290194b4be7932c92John McCall // a virtual function. 567babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::Value *IsVirtual; 56821fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) 569babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1); 570babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall else 571babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1); 572babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual"); 57393d557bc1867b7d7b102f87290194b4be7932c92John McCall Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual); 57493d557bc1867b7d7b102f87290194b4be7932c92John McCall 57593d557bc1867b7d7b102f87290194b4be7932c92John McCall // In the virtual path, the adjustment left 'This' pointing to the 57693d557bc1867b7d7b102f87290194b4be7932c92John McCall // vtable of the correct base subobject. The "function pointer" is an 577babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall // offset within the vtable (+1 for the virtual flag on non-ARM). 57893d557bc1867b7d7b102f87290194b4be7932c92John McCall CGF.EmitBlock(FnVirtual); 57993d557bc1867b7d7b102f87290194b4be7932c92John McCall 58093d557bc1867b7d7b102f87290194b4be7932c92John McCall // Cast the adjusted this to a pointer to vtable pointer and load. 5812acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VTableTy = Builder.getInt8PtrTy(); 582a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits VTablePtrAlign = 583a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD, 584a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.getPointerAlign()); 585a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTable = 586a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.GetVTablePtr(Address(This, VTablePtrAlign), VTableTy, RD); 58793d557bc1867b7d7b102f87290194b4be7932c92John McCall 58893d557bc1867b7d7b102f87290194b4be7932c92John McCall // Apply the offset. 589babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall llvm::Value *VTableOffset = FnAsInt; 59021fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (!UseARMMethodPtrABI) 59121fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1); 592babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall VTable = Builder.CreateGEP(VTable, VTableOffset); 59393d557bc1867b7d7b102f87290194b4be7932c92John McCall 59493d557bc1867b7d7b102f87290194b4be7932c92John McCall // Load the virtual function to call. 59593d557bc1867b7d7b102f87290194b4be7932c92John McCall VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo()); 596a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VirtualFn = 597a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateAlignedLoad(VTable, CGF.getPointerAlign(), 598a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar "memptr.virtualfn"); 59993d557bc1867b7d7b102f87290194b4be7932c92John McCall CGF.EmitBranch(FnEnd); 60093d557bc1867b7d7b102f87290194b4be7932c92John McCall 60193d557bc1867b7d7b102f87290194b4be7932c92John McCall // In the non-virtual path, the function pointer is actually a 60293d557bc1867b7d7b102f87290194b4be7932c92John McCall // function pointer. 60393d557bc1867b7d7b102f87290194b4be7932c92John McCall CGF.EmitBlock(FnNonVirtual); 60493d557bc1867b7d7b102f87290194b4be7932c92John McCall llvm::Value *NonVirtualFn = 605babc9a9ecc3fbc04edaac5a1f4fb3e869815b25cJohn McCall Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn"); 60693d557bc1867b7d7b102f87290194b4be7932c92John McCall 60793d557bc1867b7d7b102f87290194b4be7932c92John McCall // We're done. 60893d557bc1867b7d7b102f87290194b4be7932c92John McCall CGF.EmitBlock(FnEnd); 609bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2); 61093d557bc1867b7d7b102f87290194b4be7932c92John McCall Callee->addIncoming(VirtualFn, FnVirtual); 61193d557bc1867b7d7b102f87290194b4be7932c92John McCall Callee->addIncoming(NonVirtualFn, FnNonVirtual); 61293d557bc1867b7d7b102f87290194b4be7932c92John McCall return Callee; 61393d557bc1867b7d7b102f87290194b4be7932c92John McCall} 6143023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 6156c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall/// Compute an l-value by applying the given pointer-to-member to a 6166c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall/// base object. 617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesllvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( 618a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, 619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberPointerType *MPT) { 62092e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner assert(MemPtr->getType() == CGM.PtrDiffTy); 6216c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 6226c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall CGBuilderTy &Builder = CGF.Builder; 6236c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 6246c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall // Cast to char*. 625a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Base = Builder.CreateElementBitCast(Base, CGF.Int8Ty); 6266c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 6276c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall // Apply the offset, which we assume is non-null. 628a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Addr = 629a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateInBoundsGEP(Base.getPointer(), MemPtr, "memptr.offset"); 6306c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 6316c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall // Cast the address to the appropriate pointer type, adopting the 6326c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall // address space of the base pointer. 633a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Type *PType = CGF.ConvertTypeForMem(MPT->getPointeeType()) 634a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ->getPointerTo(Base.getAddressSpace()); 6356c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall return Builder.CreateBitCast(Addr, PType); 6366c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall} 6376c2ab1d578c6cc1f3ddcc948532cd625f1092ef2John McCall 6384d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall/// Perform a bitcast, derived-to-base, or base-to-derived member pointer 6394d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall/// conversion. 6404d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall/// 6414d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall/// Bitcast conversions are always a no-op under Itanium. 6420bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// 6430bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// Obligatory offset/adjustment diagram: 6440bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// <-- offset --> <-- adjustment --> 6450bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// |--------------------------|----------------------|--------------------| 6460bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// ^Derived address point ^Base address point ^Member address point 6470bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// 6480bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// So when converting a base member pointer to a derived member pointer, 6490bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// we add the offset to the adjustment because the address point has 6500bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// decreased; and conversely, when converting a derived MP to a base MP 6510bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// we subtract the offset from the adjustment because the address point 6520bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// has increased. 6530bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// 6540bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// The standard forbids (at compile time) conversion to and from 6550bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// virtual bases, which is why we don't have to consider them here. 6560bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// 6570bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// The standard forbids (at run time) casting a derived MP to a base 6580bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// MP when the derived MP does not point to a member of the base. 6590bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// This is why -1 is a reasonable choice for null data member 6600bab0cdab751248ca389a5592bcb70eac5d39260John McCall/// pointers. 661d608cdb7c044365cf4e8764ade1e11e99c176078John McCallllvm::Value * 6620bab0cdab751248ca389a5592bcb70eac5d39260John McCallItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 6630bab0cdab751248ca389a5592bcb70eac5d39260John McCall const CastExpr *E, 6644d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *src) { 6652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 6664d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getCastKind() == CK_BaseToDerivedMemberPointer || 6674d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getCastKind() == CK_ReinterpretMemberPointer); 6684d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 6694d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // Under Itanium, reinterprets don't require any additional processing. 6704d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; 6714d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 6724d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // Use constant emission if we can. 6734d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (isa<llvm::Constant>(src)) 6744d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return EmitMemberPointerConversion(E, cast<llvm::Constant>(src)); 6754d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 6764d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *adj = getMemberPointerAdjustment(E); 6774d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (!adj) return src; 6783023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 6793023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall CGBuilderTy &Builder = CGF.Builder; 6804d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 6814d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 6824d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall const MemberPointerType *destTy = 6834d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getType()->castAs<MemberPointerType>(); 6843023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 6854d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // For member data pointers, this is just a matter of adding the 6864d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // offset if the source is non-null. 6874d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (destTy->isMemberDataPointer()) { 6884d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *dst; 6894d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (isDerivedToBase) 6904d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dst = Builder.CreateNSWSub(src, adj, "adj"); 6914d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall else 6924d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dst = Builder.CreateNSWAdd(src, adj, "adj"); 6933023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 6944d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // Null check. 6954d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType()); 6964d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull"); 6974d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return Builder.CreateSelect(isNull, src, dst); 6984d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall } 6993023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 7004d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // The this-adjustment is left-shifted by 1 on ARM. 70121fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) { 7024d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); 7034d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall offset <<= 1; 7044d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall adj = llvm::ConstantInt::get(adj->getType(), offset); 7054d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall } 7063023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 7074d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj"); 7084d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Value *dstAdj; 7094d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (isDerivedToBase) 7104d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj"); 7113023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall else 7124d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj"); 7134d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 7144d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return Builder.CreateInsertValue(src, dstAdj, 1); 7154d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall} 7164d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 7174d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCallllvm::Constant * 7184d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCallItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, 7194d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *src) { 7204d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 7214d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getCastKind() == CK_BaseToDerivedMemberPointer || 7224d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getCastKind() == CK_ReinterpretMemberPointer); 7233023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall 7244d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // Under Itanium, reinterprets don't require any additional processing. 7254d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; 7264d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 7274d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // If the adjustment is trivial, we don't need to do anything. 7284d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *adj = getMemberPointerAdjustment(E); 7294d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (!adj) return src; 7304d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 7314d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 7324d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall 7334d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall const MemberPointerType *destTy = 7344d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall E->getType()->castAs<MemberPointerType>(); 735875ab10245d3bf37252dd822aa1616bb0a391095John McCall 7360bab0cdab751248ca389a5592bcb70eac5d39260John McCall // For member data pointers, this is just a matter of adding the 7370bab0cdab751248ca389a5592bcb70eac5d39260John McCall // offset if the source is non-null. 7384d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (destTy->isMemberDataPointer()) { 7394d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall // null maps to null. 7404d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (src->isAllOnesValue()) return src; 7410bab0cdab751248ca389a5592bcb70eac5d39260John McCall 7424d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (isDerivedToBase) 7434d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return llvm::ConstantExpr::getNSWSub(src, adj); 7444d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall else 7454d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return llvm::ConstantExpr::getNSWAdd(src, adj); 7460bab0cdab751248ca389a5592bcb70eac5d39260John McCall } 7470bab0cdab751248ca389a5592bcb70eac5d39260John McCall 748d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // The this-adjustment is left-shifted by 1 on ARM. 74921fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) { 7504d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue(); 7514d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall offset <<= 1; 7524d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall adj = llvm::ConstantInt::get(adj->getType(), offset); 753d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } 754d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 7554d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1); 7564d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall llvm::Constant *dstAdj; 7574d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall if (isDerivedToBase) 7584d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj); 759d608cdb7c044365cf4e8764ade1e11e99c176078John McCall else 7604d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj); 761d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 7624d4e5c1ae83f4510caa486b3ad19de13048f9f04John McCall return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1); 7633023def6bea3af6dbb51eea51f8cb8ea892d26cfJohn McCall} 764cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall 765cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCallllvm::Constant * 7660bab0cdab751248ca389a5592bcb70eac5d39260John McCallItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 7670bab0cdab751248ca389a5592bcb70eac5d39260John McCall // Itanium C++ ABI 2.3: 7680bab0cdab751248ca389a5592bcb70eac5d39260John McCall // A NULL pointer is represented as -1. 7690bab0cdab751248ca389a5592bcb70eac5d39260John McCall if (MPT->isMemberDataPointer()) 77092e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true); 771d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 77292e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0); 773d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Constant *Values[2] = { Zero, Zero }; 774c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantStruct::getAnon(Values); 775cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall} 776cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall 7775808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCallllvm::Constant * 7785808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCallItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 7795808ce43f8d7e71f5acacc9ca320268c4f37565aJohn McCall CharUnits offset) { 7800bab0cdab751248ca389a5592bcb70eac5d39260John McCall // Itanium C++ ABI 2.3: 7810bab0cdab751248ca389a5592bcb70eac5d39260John McCall // A pointer to data member is an offset from the base address of 7820bab0cdab751248ca389a5592bcb70eac5d39260John McCall // the class object containing it, represented as a ptrdiff_t 78392e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()); 7840bab0cdab751248ca389a5592bcb70eac5d39260John McCall} 7850bab0cdab751248ca389a5592bcb70eac5d39260John McCall 786a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarllvm::Constant * 787a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarItaniumCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { 7882d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return BuildMemberPointer(MD, CharUnits::Zero()); 7892d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith} 7902d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 7912d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithllvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, 7922d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CharUnits ThisAdjustment) { 793d608cdb7c044365cf4e8764ade1e11e99c176078John McCall assert(MD->isInstance() && "Member function must not be static!"); 794d608cdb7c044365cf4e8764ade1e11e99c176078John McCall MD = MD->getCanonicalDecl(); 795875ab10245d3bf37252dd822aa1616bb0a391095John McCall 796d608cdb7c044365cf4e8764ade1e11e99c176078John McCall CodeGenTypes &Types = CGM.getTypes(); 797875ab10245d3bf37252dd822aa1616bb0a391095John McCall 798d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // Get the function pointer (or index if this is a virtual function). 799d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Constant *MemPtr[2]; 800d608cdb7c044365cf4e8764ade1e11e99c176078John McCall if (MD->isVirtual()) { 8015f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD); 802875ab10245d3bf37252dd822aa1616bb0a391095John McCall 8031246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck const ASTContext &Context = getContext(); 8041246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck CharUnits PointerWidth = 805bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 8061246ba6f6801390ffc0e1d4b83a2b45e72283b8fKen Dyck uint64_t VTableOffset = (Index * PointerWidth.getQuantity()); 807d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 80821fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) { 809d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // ARM C++ ABI 3.2.1: 810d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // This ABI specifies that adj contains twice the this 811d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // adjustment, plus 1 if the member function is virtual. The 812d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // least significant bit of adj then makes exactly the same 813d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // discrimination as the least significant bit of ptr does for 814d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // Itanium. 81592e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); 81692e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 8172d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 2 * ThisAdjustment.getQuantity() + 1); 818d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } else { 819d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // Itanium C++ ABI 2.3: 820d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // For a virtual function, [the pointer field] is 1 plus the 821d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // virtual table offset (in bytes) of the function, 822d608cdb7c044365cf4e8764ade1e11e99c176078John McCall // represented as a ptrdiff_t. 82392e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1); 82492e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 8252d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith ThisAdjustment.getQuantity()); 826d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } 827d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } else { 828755d8497e39071aa24acc173ff07083e3256b8f8John McCall const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 8292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty; 830755d8497e39071aa24acc173ff07083e3256b8f8John McCall // Check whether the function has a computable LLVM signature. 831f742eb0196e1b25c0b71e91da4a2b856d16a1dabChris Lattner if (Types.isFuncTypeConvertible(FPT)) { 832755d8497e39071aa24acc173ff07083e3256b8f8John McCall // The function has a computable LLVM signature; use the correct type. 833de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 834d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } else { 835755d8497e39071aa24acc173ff07083e3256b8f8John McCall // Use an arbitrary non-function type to tell GetAddrOfFunction that the 836755d8497e39071aa24acc173ff07083e3256b8f8John McCall // function type is incomplete. 83792e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner Ty = CGM.PtrDiffTy; 838d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } 839755d8497e39071aa24acc173ff07083e3256b8f8John McCall llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty); 840d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 84192e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); 84221fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, 84321fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn (UseARMMethodPtrABI ? 2 : 1) * 8442d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith ThisAdjustment.getQuantity()); 845d608cdb7c044365cf4e8764ade1e11e99c176078John McCall } 846d608cdb7c044365cf4e8764ade1e11e99c176078John McCall 847c5cbb909e8a27deb8f1a2b6b7bf56a96051af81aChris Lattner return llvm::ConstantStruct::getAnon(MemPtr); 848875ab10245d3bf37252dd822aa1616bb0a391095John McCall} 849875ab10245d3bf37252dd822aa1616bb0a391095John McCall 8502d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithllvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, 8512d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith QualType MPType) { 8522d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); 8532d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith const ValueDecl *MPD = MP.getMemberPointerDecl(); 8542d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith if (!MPD) 8552d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return EmitNullMemberPointer(MPT); 8562d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 857f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); 8582d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 8592d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) 8602d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return BuildMemberPointer(MD, ThisAdjustment); 8612d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 8622d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CharUnits FieldOffset = 8632d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); 8642d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); 8652d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith} 8662d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 867e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall/// The comparison algorithm is pretty easy: the member pointers are 868e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall/// the same if they're either bitwise identical *or* both null. 869e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall/// 870e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall/// ARM is different here only because null-ness is more complicated. 871e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCallllvm::Value * 8720bab0cdab751248ca389a5592bcb70eac5d39260John McCallItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 8730bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *L, 8740bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *R, 8750bab0cdab751248ca389a5592bcb70eac5d39260John McCall const MemberPointerType *MPT, 8760bab0cdab751248ca389a5592bcb70eac5d39260John McCall bool Inequality) { 877e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall CGBuilderTy &Builder = CGF.Builder; 878e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 879e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::ICmpInst::Predicate Eq; 880e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Instruction::BinaryOps And, Or; 881e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall if (Inequality) { 882e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Eq = llvm::ICmpInst::ICMP_NE; 883e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall And = llvm::Instruction::Or; 884e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Or = llvm::Instruction::And; 885e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall } else { 886e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Eq = llvm::ICmpInst::ICMP_EQ; 887e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall And = llvm::Instruction::And; 888e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Or = llvm::Instruction::Or; 889e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall } 890e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 8910bab0cdab751248ca389a5592bcb70eac5d39260John McCall // Member data pointers are easy because there's a unique null 8920bab0cdab751248ca389a5592bcb70eac5d39260John McCall // value, so it just comes down to bitwise equality. 8930bab0cdab751248ca389a5592bcb70eac5d39260John McCall if (MPT->isMemberDataPointer()) 8940bab0cdab751248ca389a5592bcb70eac5d39260John McCall return Builder.CreateICmp(Eq, L, R); 8950bab0cdab751248ca389a5592bcb70eac5d39260John McCall 8960bab0cdab751248ca389a5592bcb70eac5d39260John McCall // For member function pointers, the tautologies are more complex. 8970bab0cdab751248ca389a5592bcb70eac5d39260John McCall // The Itanium tautology is: 898de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall // (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj)) 8990bab0cdab751248ca389a5592bcb70eac5d39260John McCall // The ARM tautology is: 900de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall // (L == R) <==> (L.ptr == R.ptr && 901de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall // (L.adj == R.adj || 902de719f7131e1ece5c9d6b5ffe21b83286d29f10fJohn McCall // (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0))) 9030bab0cdab751248ca389a5592bcb70eac5d39260John McCall // The inequality tautologies have exactly the same structure, except 9040bab0cdab751248ca389a5592bcb70eac5d39260John McCall // applying De Morgan's laws. 9050bab0cdab751248ca389a5592bcb70eac5d39260John McCall 9060bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr"); 9070bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr"); 9080bab0cdab751248ca389a5592bcb70eac5d39260John McCall 909e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // This condition tests whether L.ptr == R.ptr. This must always be 910e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // true for equality to hold. 911e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr"); 912e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 913e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // This condition, together with the assumption that L.ptr == R.ptr, 914e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // tests whether the pointers are both null. ARM imposes an extra 915e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // condition. 916e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType()); 917e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null"); 918e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 919e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // This condition tests whether L.adj == R.adj. If this isn't 920e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // true, the pointers are unequal unless they're both null. 921d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj"); 922d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj"); 923e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj"); 924e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 925e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // Null member function pointers on ARM clear the low bit of Adj, 926e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // so the zero condition has to check that neither low bit is set. 92721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) { 928e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1); 929e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 930e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // Compute (l.adj | r.adj) & 1 and test it against zero. 931e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj"); 932e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One); 933e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero, 934e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall "cmp.or.adj"); 935e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero); 936e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall } 937e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 938e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall // Tie together all our conditions. 939e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq); 940e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Result = Builder.CreateBinOp(And, PtrEq, Result, 941e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall Inequality ? "memptr.ne" : "memptr.eq"); 942e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall return Result; 943e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall} 944e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 945e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCallllvm::Value * 9460bab0cdab751248ca389a5592bcb70eac5d39260John McCallItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 9470bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *MemPtr, 9480bab0cdab751248ca389a5592bcb70eac5d39260John McCall const MemberPointerType *MPT) { 949e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall CGBuilderTy &Builder = CGF.Builder; 9500bab0cdab751248ca389a5592bcb70eac5d39260John McCall 9510bab0cdab751248ca389a5592bcb70eac5d39260John McCall /// For member data pointers, this is just a check against -1. 9520bab0cdab751248ca389a5592bcb70eac5d39260John McCall if (MPT->isMemberDataPointer()) { 95392e44d911c748f2ef0d578bbf7b0703fb2ed4d9cReid Kleckner assert(MemPtr->getType() == CGM.PtrDiffTy); 9540bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Value *NegativeOne = 9550bab0cdab751248ca389a5592bcb70eac5d39260John McCall llvm::Constant::getAllOnesValue(MemPtr->getType()); 9560bab0cdab751248ca389a5592bcb70eac5d39260John McCall return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool"); 9570bab0cdab751248ca389a5592bcb70eac5d39260John McCall } 958e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 959db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar // In Itanium, a member function pointer is not null if 'ptr' is not null. 960d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr"); 961e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 962e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0); 963e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool"); 964e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 965db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar // On ARM, a member function pointer is also non-null if the low bit of 'adj' 966db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar // (the virtual bit) is set. 96721fe45076c371e9a9f27e15c4e068e77a185fe62Mark Seaborn if (UseARMMethodPtrABI) { 968e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1); 969d608cdb7c044365cf4e8764ade1e11e99c176078John McCall llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj"); 970e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit"); 971db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero, 972db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar "memptr.isvirtual"); 973db27b5fb2d7fc50b8962b2c95e4d43b90c69b1f0Daniel Dunbar Result = Builder.CreateOr(Result, IsVirtual); 974e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall } 975e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall 976e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall return Result; 977e9fd7eb6c67676dc27e84eac429aec4f3be51f26John McCall} 978875ab10245d3bf37252dd822aa1616bb0a391095John McCall 9796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const { 9806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl(); 9816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!RD) 9826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 9836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Return indirectly if we have a non-trivial copy ctor or non-trivial dtor. 9856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared 9866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // special members. 9876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) { 988a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType()); 989a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 9906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 9916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 9926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 9936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 9946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 995f16aa103d3afd42fbca2ab346f191bf745cec092John McCall/// The Itanium ABI requires non-zero initialization only for data 996f16aa103d3afd42fbca2ab346f191bf745cec092John McCall/// member pointers, for which '0' is a valid offset. 997f16aa103d3afd42fbca2ab346f191bf745cec092John McCallbool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 998b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar return MPT->isMemberFunctionPointer(); 999cf2c85e76fdafe7e634810a292321a6c8322483dJohn McCall} 10004c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 1001ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall/// The Itanium ABI always places an offset to the complete object 1002ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall/// at entry -2 in the vtable. 1003176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, 1004176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXDeleteExpr *DE, 1005a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address Ptr, 1006176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines QualType ElementType, 1007176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXDestructorDecl *Dtor) { 1008176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool UseGlobalDelete = DE->isGlobalDelete(); 1009176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (UseGlobalDelete) { 1010176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Derive the complete-object pointer, which is what we need 1011176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // to pass to the deallocation function. 1012176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1013176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Grab the vtable pointer as an intptr_t*. 1014a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *ClassDecl = 1015a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cast<CXXRecordDecl>(ElementType->getAs<RecordType>()->getDecl()); 1016a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTable = 1017a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo(), ClassDecl); 1018176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1019176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Track back to entry -2 and pull out the offset there. 1020176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64( 1021176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VTable, -2, "complete-offset.ptr"); 1022a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Offset = 1023a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(OffsetPtr, CGF.getPointerAlign()); 1024176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1025176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Apply the offset. 1026a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *CompletePtr = 1027a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateBitCast(Ptr.getPointer(), CGF.Int8PtrTy); 1028176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CompletePtr = CGF.Builder.CreateInBoundsGEP(CompletePtr, Offset); 1029176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1030176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If we're supposed to call the global delete, make sure we do so 1031176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // even if the destructor throws. 1032176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.pushCallObjectDeleteCleanup(DE->getOperatorDelete(), CompletePtr, 1033176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ElementType); 1034176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1035ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 1036176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Provide a source location here even though there's no 1037176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // CXXMemberCallExpr for dtor call. 1038176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting; 1039176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr); 1040176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1041176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (UseGlobalDelete) 1042176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.PopCleanupBlock(); 1043ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall} 1044ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 10450e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) { 10460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // void __cxa_rethrow(); 10470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType *FTy = 10490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false); 10500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow"); 10520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (isNoReturn) 10540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, None); 10550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines else 10560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGF.EmitRuntimeCallOrInvoke(Fn); 10570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 10580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getAllocateExceptionFn(CodeGenModule &CGM) { 10603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void *__cxa_allocate_exception(size_t thrown_size); 10613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FTy = 10633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*IsVarArgs=*/false); 10643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception"); 10663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 10673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getThrowFn(CodeGenModule &CGM) { 10693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void __cxa_throw(void *thrown_exception, std::type_info *tinfo, 10703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void (*dest) (void *)); 10713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.Int8PtrTy, CGM.Int8PtrTy }; 10733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FTy = 10743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, Args, /*IsVarArgs=*/false); 10753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FTy, "__cxa_throw"); 10773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 10783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { 10803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType ThrowType = E->getSubExpr()->getType(); 10813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Now allocate the exception object. 10823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *SizeTy = CGF.ConvertType(getContext().getSizeType()); 10833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity(); 10843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(CGM); 10863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::CallInst *ExceptionPtr = CGF.EmitNounwindRuntimeCall( 10873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception"); 10883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1089a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits ExnAlign = getAlignmentOfExnObject(); 1090a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.EmitAnyExprToExn(E->getSubExpr(), Address(ExceptionPtr, ExnAlign)); 10913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Now throw the exception. 10933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, 10943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*ForEH=*/true); 10953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 10963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // The address of the destructor. If the exception type has a 10973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // trivial destructor (or isn't a record), we just pass null. 10983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Constant *Dtor = nullptr; 10993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) { 11003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl()); 11013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!Record->hasTrivialDestructor()) { 11023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CXXDestructorDecl *DtorD = Record->getDestructor(); 11033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Dtor = CGM.getAddrOfCXXStructor(DtorD, StructorType::Complete); 11043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy); 11053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 11063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 11073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy); 11083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 11093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor }; 11103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args); 11113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 11123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1113c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) { 1114c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // void *__dynamic_cast(const void *sub, 1115c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // const abi::__class_type_info *src, 1116c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // const abi::__class_type_info *dst, 1117c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // std::ptrdiff_t src2dst_offset); 1118c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1119c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *Int8PtrTy = CGF.Int8PtrTy; 1120c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *PtrDiffTy = 1121c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1122c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1123c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy }; 1124c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1125c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); 1126c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1127c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Mark the function as nounwind readonly. 1128c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind, 1129c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Attribute::ReadOnly }; 1130c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::AttributeSet Attrs = llvm::AttributeSet::get( 1131c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs); 1132c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1133c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs); 1134c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1135c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1136c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic llvm::Constant *getBadCastFn(CodeGenFunction &CGF) { 1137c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // void __cxa_bad_cast(); 1138c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false); 1139c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast"); 1140c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1141c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1142c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// \brief Compute the src2dst_offset hint as described in the 1143c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// Itanium C++ ABI [2.9.7] 1144c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic CharUnits computeOffsetHint(ASTContext &Context, 1145c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *Src, 1146c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *Dst) { 1147c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 1148c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /*DetectVirtual=*/false); 1149c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1150c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If Dst is not derived from Src we can skip the whole computation below and 1151c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // return that Src is not a public base of Dst. Record all inheritance paths. 1152c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Dst->isDerivedFrom(Src, Paths)) 1153c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CharUnits::fromQuantity(-2ULL); 1154c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1155c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned NumPublicPaths = 0; 1156c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CharUnits Offset; 1157c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1158c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Now walk all possible inheritance paths. 1159a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (const CXXBasePath &Path : Paths) { 1160a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (Path.Access != AS_public) // Ignore non-public inheritance. 1161c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines continue; 1162c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1163c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ++NumPublicPaths; 1164c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1165a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (const CXXBasePathElement &PathElement : Path) { 1166c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If the path contains a virtual base class we can't give any hint. 1167c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // -1: no hint. 1168a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (PathElement.Base->isVirtual()) 1169c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CharUnits::fromQuantity(-1ULL); 1170c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1171c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (NumPublicPaths > 1) // Won't use offsets, skip computation. 1172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines continue; 1173c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Accumulate the base class offsets. 1175a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class); 1176a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Offset += L.getBaseClassOffset( 1177a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar PathElement.Base->getType()->getAsCXXRecordDecl()); 1178c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 1179c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 1180c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1181c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // -2: Src is not a public base of Dst. 1182c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (NumPublicPaths == 0) 1183c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CharUnits::fromQuantity(-2ULL); 1184c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1185c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // -3: Src is a multiple public base type but never a virtual base type. 1186c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (NumPublicPaths > 1) 1187c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CharUnits::fromQuantity(-3ULL); 1188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Otherwise, the Src type is a unique public nonvirtual base type of Dst. 1190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Return the offset of Src from the origin of Dst. 1191c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Offset; 1192c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1193c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1194c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) { 1195c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // void __cxa_bad_typeid(); 1196c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false); 1197c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1198c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); 1199c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1200c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1201c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesbool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref, 1202c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy) { 1203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return IsDeref; 1204c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1205c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) { 1207c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *Fn = getBadTypeidFn(CGF); 1208c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn(); 1209c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.Builder.CreateUnreachable(); 1210c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1211c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1212c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, 1213c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy, 1214a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address ThisPtr, 1215c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *StdTypeInfoPtrTy) { 1216a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *ClassDecl = 1217a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cast<CXXRecordDecl>(SrcRecordTy->getAs<RecordType>()->getDecl()); 1218c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *Value = 1219a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl); 1220c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1221c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Load the type info. 1222c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL); 1223a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateAlignedLoad(Value, CGF.getPointerAlign()); 1224c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1225c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1226c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesbool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, 1227c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy) { 1228c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return SrcIsPtr; 1229c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1230c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1231c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Value *ItaniumCXXABI::EmitDynamicCastCall( 1232a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy, 1233c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) { 1234c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *PtrDiffLTy = 1235c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1236c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *DestLTy = CGF.ConvertType(DestTy); 1237c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1238c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *SrcRTTI = 1239c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType()); 1240c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *DestRTTI = 1241c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType()); 1242c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1243c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Compute the offset hint. 1244c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl(); 1245c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl(); 1246c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *OffsetHint = llvm::ConstantInt::get( 1247c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PtrDiffLTy, 1248c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity()); 1249c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1250c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Emit the call to __dynamic_cast. 1251a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Value = ThisAddr.getPointer(); 1252c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.EmitCastToVoidPtr(Value); 1253c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1254c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint}; 1255c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args); 1256c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.Builder.CreateBitCast(Value, DestLTy); 1257c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1258c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// C++ [expr.dynamic.cast]p9: 1259c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// A failed cast to reference type throws std::bad_cast 1260c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (DestTy->isReferenceType()) { 1261c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::BasicBlock *BadCastBlock = 1262c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.createBasicBlock("dynamic_cast.bad_cast"); 1263c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1264c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value); 1265c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd); 1266c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1267c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.EmitBlock(BadCastBlock); 1268c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EmitBadCastCall(CGF); 1269c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 1270c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1271c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Value; 1272c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1273c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1274c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, 1275a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address ThisAddr, 1276c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SrcRecordTy, 1277c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType DestTy) { 1278c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *PtrDiffLTy = 1279c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1280c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *DestLTy = CGF.ConvertType(DestTy); 1281c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1282a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *ClassDecl = 1283a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cast<CXXRecordDecl>(SrcRecordTy->getAs<RecordType>()->getDecl()); 1284c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Get the vtable pointer. 1285a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTable = CGF.GetVTablePtr(ThisAddr, PtrDiffLTy->getPointerTo(), 1286a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ClassDecl); 1287c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1288c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Get the offset-to-top from the vtable. 1289c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *OffsetToTop = 1290c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL); 1291a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar OffsetToTop = 1292a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(OffsetToTop, CGF.getPointerAlign(), 1293a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar "offset.to.top"); 1294c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1295c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Finally, add the offset to the pointer. 1296a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Value = ThisAddr.getPointer(); 1297c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.EmitCastToVoidPtr(Value); 1298c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop); 1299c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1300c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return CGF.Builder.CreateBitCast(Value, DestLTy); 1301c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1302c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1303c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesbool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) { 1304c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Value *Fn = getBadCastFn(CGF); 1305c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn(); 1306c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGF.Builder.CreateUnreachable(); 1307c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 1308c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 1309c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1310b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Klecknerllvm::Value * 1311b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, 1312a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, 1313b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *ClassDecl, 1314b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *BaseClassDecl) { 1315a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl); 1316b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits VBaseOffsetOffset = 13175f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl, 13185f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov BaseClassDecl); 1319b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 1320b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBaseOffsetPtr = 1321b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 1322b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner "vbase.offset.ptr"); 1323b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr, 1324b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGM.PtrDiffTy->getPointerTo()); 1325b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 1326b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBaseOffset = 1327a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(VBaseOffsetPtr, CGF.getPointerAlign(), 1328a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar "vbase.offset"); 1329b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 1330b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return VBaseOffset; 1331b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 1332b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 1333bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanovvoid ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { 1334bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov // Just make sure we're in sync with TargetCXXABI. 1335bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov assert(CGM.getTarget().getCXXABI().hasConstructorVariants()); 1336bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov 1337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The constructor used for constructing this as a base class; 1338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // ignores virtual bases. 1339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.EmitGlobal(GlobalDecl(D, Ctor_Base)); 1340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1341bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov // The constructor used for constructing this as a complete class; 13420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // constructs the virtual bases, then calls the base constructor. 1343bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov if (!D->getParent()->isAbstract()) { 1344bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov // We don't need to emit the complete ctor if the class is abstract. 1345bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); 1346bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov } 1347bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov} 1348bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov 1349176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid 1350176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T, 1351176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallVectorImpl<CanQualType> &ArgTys) { 13529cb2cee212d708220c52249ceac4cdd9f2b8aeb0John McCall ASTContext &Context = getContext(); 13534c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 1354176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // All parameters are already in place except VTT, which goes after 'this'. 1355176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // These are Clang types, so we don't need to worry about sret yet. 13564c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 13574c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall // Check if we need to add a VTT parameter (which has type void **). 1358176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0) 1359176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ArgTys.insert(ArgTys.begin() + 1, 1360176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Context.getPointerType(Context.VoidPtrTy)); 13614c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall} 13624c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 1363a4130baad9d10b7feabb7e003da53424e986d269Reid Klecknervoid ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { 1364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The destructor used for destructing this as a base class; ignores 1365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // virtual bases. 1366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.EmitGlobal(GlobalDecl(D, Dtor_Base)); 1367a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 1368a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // The destructor used for destructing this as a most-derived class; 1369a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // call the base destructor and then destructs any virtual bases. 1370a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete)); 1371a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 1372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // The destructor in a virtual table is always a 'deleting' 1373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // destructor, which calls the complete destructor and then uses the 1374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // appropriate operator delete. 1375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (D->isVirtual()) 1376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting)); 1377a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner} 1378a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 1379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF, 1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType &ResTy, 1381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FunctionArgList &Params) { 13824c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 1383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)); 13844c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 13854c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall // Check if we need a VTT parameter as well. 1386e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (NeedsVTTParameter(CGF.CurGD)) { 13879cb2cee212d708220c52249ceac4cdd9f2b8aeb0John McCall ASTContext &Context = getContext(); 13884c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 13894c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall // FIXME: avoid the fake decl 13904c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall QualType T = Context.getPointerType(Context.VoidPtrTy); 13914c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall ImplicitParamDecl *VTTDecl 13926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines = ImplicitParamDecl::Create(Context, nullptr, MD->getLocation(), 13934c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall &Context.Idents.get("vtt"), T); 1394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Params.insert(Params.begin() + 1, VTTDecl); 1395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getStructorImplicitParamDecl(CGF) = VTTDecl; 13964c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall } 13974c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall} 13984c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 13994c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallvoid ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 14004c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall /// Initialize the 'this' slot. 14014c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall EmitThisParam(CGF); 14024c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 14034c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall /// Initialize the 'vtt' slot if needed. 1404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getStructorImplicitParamDecl(CGF)) { 1405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getStructorImplicitParamValue(CGF) = CGF.Builder.CreateLoad( 1406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), "vtt"); 14074c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall } 14084c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 14093b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// If this is a function that the ABI specifies returns 'this', initialize 14103b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// the return slot to 'this' at the start of the function. 14113b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 14123b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// Unlike the setting of return types, this is done within the ABI 14133b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// implementation instead of by clients of CGCXXABI because: 14143b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 1) getThisValue is currently protected 14153b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 2) in theory, an ABI could implement 'this' returns some other way; 14163b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// HasThisReturn only specifies a contract, not the implementation 14174c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall if (HasThisReturn(CGF.CurGD)) 1418cec5ebd4a6a89a7023d04cec728fd340b541ed61Eli Friedman CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 14194c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall} 14204c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 1421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunsigned ItaniumCXXABI::addImplicitConstructorArgs( 1422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, 1423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ForVirtualBase, bool Delegating, CallArgList &Args) { 1424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!NeedsVTTParameter(GlobalDecl(D, Type))) 1425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return 0; 1426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Insert the implicit 'vtt' argument as the second argument. 1428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *VTT = 1429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating); 14301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); 1431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.insert(Args.begin() + 1, 1432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false)); 1433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return 1; // Added one arg. 1434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, 1437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXDestructorDecl *DD, 1438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CXXDtorType Type, bool ForVirtualBase, 1439a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool Delegating, Address This) { 1440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines GlobalDecl GD(DD, Type); 1441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); 1442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); 1443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *Callee = nullptr; 1445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getContext().getLangOpts().AppleKext) 1446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent()); 1447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Callee) 1449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Callee = CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)); 14501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1451a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(), 1452a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar This.getPointer(), VTT, VTTTy, nullptr); 14531d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 14541d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1455a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanovvoid ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, 1456a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov const CXXRecordDecl *RD) { 1457a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits()); 1458a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov if (VTable->hasInitializer()) 1459a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov return; 1460a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 14615f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); 1462a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov const VTableLayout &VTLayout = VTContext.getVTableLayout(RD); 1463a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); 1464c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *RTTI = 1465c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD)); 1466a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1467a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // Create and set the initializer. 1468a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::Constant *Init = CGVT.CreateVTableInitializer( 1469a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(), 1470c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI); 1471a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov VTable->setInitializer(Init); 1472a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1473a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // Set the correct linkage. 1474a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov VTable->setLinkage(Linkage); 1475a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 14760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (CGM.supportsCOMDAT() && VTable->isWeakForLinker()) 14770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName())); 14780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 1479a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // Set the right visibility. 1480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.setGlobalVisibility(VTable, RD); 1481a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Use pointer alignment for the vtable. Otherwise we would align them based 1483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // on the size of the initializer which doesn't make sense as only single 1484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // values are read. 1485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned PAlign = CGM.getTarget().getPointerAlign(0); 1486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity()); 1487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1488a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // If this is the magic class __cxxabiv1::__fundamental_type_info, 1489a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // we will emit the typeinfo for the fundamental types. This is the 1490a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // same behaviour as GCC. 1491a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov const DeclContext *DC = RD->getDeclContext(); 1492a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov if (RD->getIdentifier() && 1493a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov RD->getIdentifier()->isStr("__fundamental_type_info") && 1494a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() && 1495a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && 1496a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov DC->getParent()->isTranslationUnit()) 1497c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EmitFundamentalRTTIDescriptors(); 14980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 14990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGM.EmitVTableBitSetEntries(VTable, VTLayout); 1500a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov} 1501a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1502a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarbool ItaniumCXXABI::isVirtualOffsetNeededForVTableField( 1503a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) { 1504a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (Vptr.NearestVBase == nullptr) 1505a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 1506a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return NeedsVTTParameter(CGF.CurGD); 1507a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 1508a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1509a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanovllvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor( 1510a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, 1511a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *NearestVBase) { 1512a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1513a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) && 1514a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NeedsVTTParameter(CGF.CurGD)) { 1515a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base, 1516a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NearestVBase); 1517a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1518a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return getVTableAddressPoint(Base, VTableClass); 1519a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov} 1520a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1521a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarllvm::Constant * 1522a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, 1523a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *VTableClass) { 1524a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits()); 1525a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1526a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // Find the appropriate vtable within the vtable group. 15275f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov uint64_t AddressPoint = CGM.getItaniumVTableContext() 15285f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov .getVTableLayout(VTableClass) 15295f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov .getAddressPoint(Base); 1530a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::Value *Indices[] = { 1531a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::ConstantInt::get(CGM.Int64Ty, 0), 1532a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint) 1533a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov }; 1534a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 153558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(), 153658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar VTable, Indices); 1537a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov} 1538a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1539a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarllvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( 1540a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, 1541a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *NearestVBase) { 1542a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert((Base.getBase()->getNumVBases() || NearestVBase != nullptr) && 1543a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NeedsVTTParameter(CGF.CurGD) && "This class doesn't have VTT"); 1544a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1545a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Get the secondary vpointer index. 1546a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar uint64_t VirtualPointerIndex = 1547a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 1548a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1549a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar /// Load the VTT. 1550a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTT = CGF.LoadCXXVTT(); 1551a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (VirtualPointerIndex) 1552a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 1553a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1554a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // And load the address point from the VTT. 1555a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateAlignedLoad(VTT, CGF.getPointerAlign()); 1556a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 1557a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1558a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarllvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( 1559a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar BaseSubobject Base, const CXXRecordDecl *VTableClass) { 1560a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return getVTableAddressPoint(Base, VTableClass); 1561a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 1562a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1563a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanovllvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, 1564a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CharUnits VPtrOffset) { 1565a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); 1566a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1567a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::GlobalVariable *&VTable = VTables[RD]; 1568a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov if (VTable) 1569a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov return VTable; 1570a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1571a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov // Queue up this v-table for possible deferred emission. 1572a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CGM.addDeferredVTable(RD); 1573a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1574a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SmallString<256> Name; 1575a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::raw_svector_ostream Out(Name); 157611f22a35b7f08a8d017f6ab26e440edffc930f96Timur Iskhodzhanov getMangleContext().mangleCXXVTable(RD, Out); 1577a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 15785f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); 1579a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::ArrayType *ArrayType = llvm::ArrayType::get( 1580a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents()); 1581a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 1582a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov VTable = CGM.CreateOrReplaceCXXRuntimeVariable( 1583a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov Name, ArrayType, llvm::GlobalValue::ExternalLinkage); 1584a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov VTable->setUnnamedAddr(true); 1585c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1586c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (RD->hasAttr<DLLImportAttr>()) 1587c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); 1588c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else if (RD->hasAttr<DLLExportAttr>()) 1589c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 1590c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 1591a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov return VTable; 1592a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov} 1593a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov 15948f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovllvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, 15958f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov GlobalDecl GD, 1596a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, 1597a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Type *Ty, 1598a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SourceLocation Loc) { 15998f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov GD = GD.getCanonicalDecl(); 16008f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov Ty = Ty->getPointerTo()->getPointerTo(); 1601a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl()); 1602a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent()); 16038f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov 160458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar if (CGF.SanOpts.has(SanitizerKind::CFIVCall)) 1605a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.EmitVTablePtrCheckForCall(MethodDecl, VTable, 1606a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenFunction::CFITCK_VCall, Loc); 16070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 16085f0db587078b5af32fc9ac41fe4276b80918fd8dTimur Iskhodzhanov uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); 16098f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov llvm::Value *VFuncPtr = 16108f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); 1611a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); 16128f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov} 16138f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov 1614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesllvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( 1615176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, 1616a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, const CXXMemberCallExpr *CE) { 1617176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); 16180f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 16190f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 1620176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration( 1621176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Dtor, getFromDtorType(DtorType)); 16220f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 16238f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov llvm::Value *Callee = 1624a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty, 1625a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CE ? CE->getLocStart() : SourceLocation()); 16260f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 1627a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.EmitCXXMemberOrOperatorCall(Dtor, Callee, ReturnValueSlot(), 1628a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar This.getPointer(), /*ImplicitParam=*/nullptr, 1629a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar QualType(), CE); 1630176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return nullptr; 16310f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov} 16320f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 1633a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanovvoid ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { 16349063302a82423cb83f002257a416741850739a70Reid Kleckner CodeGenVTables &VTables = CGM.getVTables(); 16359063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD); 1636a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD); 16379063302a82423cb83f002257a416741850739a70Reid Kleckner} 16389063302a82423cb83f002257a416741850739a70Reid Kleckner 1639a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarbool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const { 1640a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // We don't emit available_externally vtables if we are in -fapple-kext mode 1641a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // because kext mode does not permit devirtualization. 1642a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (CGM.getLangOpts().AppleKext) 1643a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return false; 1644a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1645a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // If we don't have any inline virtual functions, and if vtable is not hidden, 1646a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // then we are safe to emit available_externally copy of vtable. 1647a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // FIXME we can still emit a copy of the vtable if we 1648a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // can emit definition of the inline functions. 1649a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return !hasAnyUsedVirtualInlineFunction(RD) && !isVTableHidden(RD); 1650a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar} 1651c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanovstatic llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, 1652a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address InitialPtr, 1653c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov int64_t NonVirtualAdjustment, 1654c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov int64_t VirtualAdjustment, 1655c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov bool IsReturnAdjustment) { 1656c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov if (!NonVirtualAdjustment && !VirtualAdjustment) 1657a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return InitialPtr.getPointer(); 1658c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1659a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address V = CGF.Builder.CreateElementBitCast(InitialPtr, CGF.Int8Ty); 1660c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1661a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // In a base-to-derived cast, the non-virtual adjustment is applied first. 1662c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov if (NonVirtualAdjustment && !IsReturnAdjustment) { 1663a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar V = CGF.Builder.CreateConstInBoundsByteGEP(V, 1664a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits::fromQuantity(NonVirtualAdjustment)); 1665c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov } 1666c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1667a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Perform the virtual adjustment if we have one. 1668a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *ResultPtr; 1669c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov if (VirtualAdjustment) { 1670c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov llvm::Type *PtrDiffTy = 1671c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1672c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1673a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address VTablePtrPtr = CGF.Builder.CreateElementBitCast(V, CGF.Int8PtrTy); 1674c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); 1675c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1676c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov llvm::Value *OffsetPtr = 1677c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); 1678c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1679c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); 1680c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1681c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov // Load the adjustment offset from the vtable. 1682a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Offset = 1683a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateAlignedLoad(OffsetPtr, CGF.getPointerAlign()); 1684c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1685c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov // Adjust our pointer. 1686a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ResultPtr = CGF.Builder.CreateInBoundsGEP(V.getPointer(), Offset); 1687a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 1688a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ResultPtr = V.getPointer(); 1689c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov } 1690c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1691a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // In a derived-to-base conversion, the non-virtual adjustment is 1692a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // applied second. 1693c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov if (NonVirtualAdjustment && IsReturnAdjustment) { 1694a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ResultPtr = CGF.Builder.CreateConstInBoundsGEP1_64(ResultPtr, 1695a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NonVirtualAdjustment); 1696c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov } 1697c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1698c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov // Cast back to the original type. 1699a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateBitCast(ResultPtr, InitialPtr.getType()); 1700c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov} 1701c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1702c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanovllvm::Value *ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, 1703a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address This, 1704c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov const ThisAdjustment &TA) { 170558b6db76adab8dee2e64fbc300360f9b46c561baTimur Iskhodzhanov return performTypeAdjustment(CGF, This, TA.NonVirtual, 170658b6db76adab8dee2e64fbc300360f9b46c561baTimur Iskhodzhanov TA.Virtual.Itanium.VCallOffsetOffset, 1707c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov /*IsReturnAdjustment=*/false); 1708c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov} 1709c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 1710c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanovllvm::Value * 1711a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret, 1712c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov const ReturnAdjustment &RA) { 1713c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov return performTypeAdjustment(CGF, Ret, RA.NonVirtual, 1714c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov RA.Virtual.Itanium.VBaseOffsetOffset, 1715c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov /*IsReturnAdjustment=*/true); 1716c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov} 1717c70cc5d90403f99ccce5cab3a6c022ad9cdcb66cTimur Iskhodzhanov 17184c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallvoid ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, 17194c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall RValue RV, QualType ResultType) { 17204c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl())) 17214c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType); 17224c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 17234c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall // Destructor thunks in the ARM ABI have indeterminate results. 1724a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Type *T = CGF.ReturnValue.getElementType(); 17254c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall RValue Undef = RValue::get(llvm::UndefValue::get(T)); 17264c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType); 17274c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall} 17281e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17291e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall/************************** Array allocation cookies **************************/ 17301e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1731e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallCharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) { 1732e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The array cookie is a size_t; pad that up to the element alignment. 1733e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The cookie is actually right-justified in that space. 1734e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes), 1735e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGM.getContext().getTypeAlignInChars(elementType)); 17361e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 17371e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1738a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarAddress ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 1739a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address NewPtr, 1740a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *NumElements, 1741a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXNewExpr *expr, 1742a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar QualType ElementType) { 1743e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(requiresArrayCookie(expr)); 17441e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1745a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar unsigned AS = NewPtr.getAddressSpace(); 17461e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17479cb2cee212d708220c52249ceac4cdd9f2b8aeb0John McCall ASTContext &Ctx = getContext(); 1748a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits SizeSize = CGF.getSizeSize(); 17491e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17501e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // The size of the cookie. 17511e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall CharUnits CookieSize = 17521e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType)); 1753e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(CookieSize == getArrayCookieSizeImpl(ElementType)); 17541e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17551e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // Compute an offset to the cookie. 1756a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address CookiePtr = NewPtr; 17571e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall CharUnits CookieOffset = CookieSize - SizeSize; 17581e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall if (!CookieOffset.isZero()) 1759a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CookiePtr = CGF.Builder.CreateConstInBoundsByteGEP(CookiePtr, CookieOffset); 17601e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17611e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // Write the number of elements into the appropriate slot. 1762a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address NumElementsPtr = 1763a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateElementBitCast(CookiePtr, CGF.SizeTy); 1764176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr); 1765a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1766a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Handle the array cookie specially in ASan. 1767176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 && 1768176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines expr->getOperatorNew()->isReplaceableGlobalAllocationFunction()) { 1769176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // The store to the CookiePtr does not need to be instrumented. 1770176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI); 1771176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FTy = 1772a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false); 1773176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Constant *F = 1774176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie"); 1775a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateCall(F, NumElementsPtr.getPointer()); 1776176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 17771e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 17781e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // Finally, compute a pointer to the actual data buffer by skipping 17791e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // over the cookie completely. 1780a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateConstInBoundsByteGEP(NewPtr, CookieSize); 17811e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 17821e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1783e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 1784a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address allocPtr, 1785e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize) { 1786e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The element size is right-justified in the cookie. 1787a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address numElementsPtr = allocPtr; 1788a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits numElementsOffset = cookieSize - CGF.getSizeSize(); 1789e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall if (!numElementsOffset.isZero()) 1790e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall numElementsPtr = 1791a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.Builder.CreateConstInBoundsByteGEP(numElementsPtr, numElementsOffset); 17921e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1793a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar unsigned AS = allocPtr.getAddressSpace(); 1794a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar numElementsPtr = CGF.Builder.CreateElementBitCast(numElementsPtr, CGF.SizeTy); 1795176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0) 1796176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return CGF.Builder.CreateLoad(numElementsPtr); 1797176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // In asan mode emit a function call instead of a regular load and let the 1798176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // run-time deal with it: if the shadow is properly poisoned return the 1799176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // cookie, otherwise return 0 to avoid an infinite loop calling DTORs. 1800176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // We can't simply ignore this load using nosanitize metadata because 1801176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the metadata may be lost. 1802176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FTy = 1803176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGF.SizeTy, CGF.SizeTy->getPointerTo(0), false); 1804176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Constant *F = 1805176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie"); 1806a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateCall(F, numElementsPtr.getPointer()); 18071e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 18081e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1809e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallCharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { 1810f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall // ARM says that the cookie is always: 18111e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // struct array_cookie { 18121e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // std::size_t element_size; // element_size != 0 18131e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // std::size_t element_count; 18141e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // }; 1815f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall // But the base ABI doesn't give anything an alignment greater than 1816f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall // 8, so we can dismiss this as typical ABI-author blindness to 1817f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall // actual language complexity and round up to the element alignment. 1818f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes), 1819f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall CGM.getContext().getTypeAlignInChars(elementType)); 18201e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 18211e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1822a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarAddress ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 1823a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address newPtr, 1824a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *numElements, 1825a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXNewExpr *expr, 1826a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar QualType elementType) { 1827e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(requiresArrayCookie(expr)); 18281e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 18291e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // The cookie is always at the start of the buffer. 1830a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address cookie = newPtr; 18311e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 18321e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // The first element is the element size. 1833a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cookie = CGF.Builder.CreateElementBitCast(cookie, CGF.SizeTy); 1834f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy, 1835f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall getContext().getTypeSizeInChars(elementType).getQuantity()); 1836f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall CGF.Builder.CreateStore(elementSize, cookie); 18371e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 18381e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // The second element is the element count. 1839a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cookie = CGF.Builder.CreateConstInBoundsGEP(cookie, 1, CGF.getSizeSize()); 1840f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall CGF.Builder.CreateStore(numElements, cookie); 18411e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 18421e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // Finally, compute a pointer to the actual data buffer by skipping 18431e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall // over the cookie completely. 1844f3bbb155beb69cdad1c6b0472bc0ca20cece6c50John McCall CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType); 1845a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return CGF.Builder.CreateConstInBoundsByteGEP(newPtr, cookieSize); 18461e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 18471e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1848e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 1849a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address allocPtr, 1850e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize) { 1851e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The number of elements is at offset sizeof(size_t) relative to 1852e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // the allocated pointer. 1853a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address numElementsPtr 1854a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar = CGF.Builder.CreateConstInBoundsByteGEP(allocPtr, CGF.getSizeSize()); 18551e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 1856a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar numElementsPtr = CGF.Builder.CreateElementBitCast(numElementsPtr, CGF.SizeTy); 1857e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateLoad(numElementsPtr); 18581e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall} 18591e7fe751466ea82665fd21e9162fd7cc9c5f412dJohn McCall 18605cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/*********************** Static local initialization **************************/ 18615cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 18625cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCallstatic llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM, 18639cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType *GuardPtrTy) { 18645cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // int __cxa_guard_acquire(__guard *guard_object); 18652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 18665cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy), 1867da549e8995c447542d5631b8b67fcc3a9582797aJay Foad GuardPtrTy, /*isVarArg=*/false); 1868e76872e81ea32fbc863d8d7ef6eadc91a8f8673bNick Lewycky return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire", 1869c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::get(CGM.getLLVMContext(), 1870c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::FunctionIndex, 187172390b39c545426023ec104afe8706395d732badBill Wendling llvm::Attribute::NoUnwind)); 18725cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 18735cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 18745cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCallstatic llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM, 18759cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType *GuardPtrTy) { 18765cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // void __cxa_guard_release(__guard *guard_object); 18772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 18788b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); 1879e76872e81ea32fbc863d8d7ef6eadc91a8f8673bNick Lewycky return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release", 1880c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::get(CGM.getLLVMContext(), 1881c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::FunctionIndex, 188272390b39c545426023ec104afe8706395d732badBill Wendling llvm::Attribute::NoUnwind)); 18835cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 18845cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 18855cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCallstatic llvm::Constant *getGuardAbortFn(CodeGenModule &CGM, 18869cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::PointerType *GuardPtrTy) { 18875cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // void __cxa_guard_abort(__guard *guard_object); 18882acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 18898b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false); 1890e76872e81ea32fbc863d8d7ef6eadc91a8f8673bNick Lewycky return CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort", 1891c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::get(CGM.getLLVMContext(), 1892c4c62fd78a4728c9e4d4df14911a2ced9bdd2031Bill Wendling llvm::AttributeSet::FunctionIndex, 189372390b39c545426023ec104afe8706395d732badBill Wendling llvm::Attribute::NoUnwind)); 18945cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 18955cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 18965cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCallnamespace { 1897a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar struct CallGuardAbort final : EHScopeStack::Cleanup { 18985cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::GlobalVariable *Guard; 18990f30a12ce7b3d4d86c9ca9072f587da77c8eef34Chandler Carruth CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} 19005cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 1901651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 1902bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()), 1903bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall Guard); 19045cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall } 19055cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall }; 19065cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 19075cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 19085cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// The ARM code here follows the Itanium code closely enough that we 19095cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// just special-case it at particular places. 19103030eb82593097502469a8b3fc26112c79c75605John McCallvoid ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, 19113030eb82593097502469a8b3fc26112c79c75605John McCall const VarDecl &D, 1912355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::GlobalVariable *var, 1913355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall bool shouldPerformInit) { 19145cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall CGBuilderTy &Builder = CGF.Builder; 19153030eb82593097502469a8b3fc26112c79c75605John McCall 191604e517650569598e847c2ab609672e6df93effe5Richard Smith // We only need to use thread-safe statics for local non-TLS variables; 19173030eb82593097502469a8b3fc26112c79c75605John McCall // global initialization is always single-threaded. 191804e517650569598e847c2ab609672e6df93effe5Richard Smith bool threadsafe = getContext().getLangOpts().ThreadsafeStatics && 191904e517650569598e847c2ab609672e6df93effe5Richard Smith D.isLocalVarDecl() && !D.getTLSKind(); 1920173d51286bcaff4b6b76eebf6542d3b1311142e2Anders Carlsson 1921173d51286bcaff4b6b76eebf6542d3b1311142e2Anders Carlsson // If we have a global variable with internal linkage and thread-safe statics 1922173d51286bcaff4b6b76eebf6542d3b1311142e2Anders Carlsson // are disabled, we can just let the guard variable be of type i8. 1923355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage(); 1924355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall 1925355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::IntegerType *guardTy; 1926a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits guardAlignment; 19270502a224984a26087ea4d64e8e5d2dd4dca432f6John McCall if (useInt8GuardVariable) { 1928355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall guardTy = CGF.Int8Ty; 1929a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardAlignment = CharUnits::One(); 19300502a224984a26087ea4d64e8e5d2dd4dca432f6John McCall } else { 1931c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover // Guard variables are 64 bits in the generic ABI and size width on ARM 1932c264e16a42b3f6c36521857a29ea0949d9781c22Tim Northover // (i.e. 32-bit on AArch32, 64-bit on AArch64). 1933a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (UseARMGuardVarABI) { 1934a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardTy = CGF.SizeTy; 1935a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardAlignment = CGF.getSizeAlign(); 1936a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 1937a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardTy = CGF.Int64Ty; 1938a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardAlignment = CharUnits::fromQuantity( 1939a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getDataLayout().getABITypeAlignment(guardTy)); 1940a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1941355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall } 1942355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::PointerType *guardPtrTy = guardTy->getPointerTo(); 1943355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall 1944355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall // Create the guard variable if we don't already have it (as we 1945355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall // might if we're double-emitting this function body). 1946355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D); 1947355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall if (!guard) { 1948355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall // Mangle the name for the guard. 1949355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall SmallString<256> guardName; 1950355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall { 1951355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::raw_svector_ostream out(guardName); 1952942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner getMangleContext().mangleStaticGuardVariable(&D, out); 1953355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall } 1954355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall 1955355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall // Create the guard variable with a zero-initializer. 1956355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall // Just absorb linkage and visibility from the guarded variable. 1957355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall guard = new llvm::GlobalVariable(CGM.getModule(), guardTy, 1958355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall false, var->getLinkage(), 1959355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall llvm::ConstantInt::get(guardTy, 0), 1960355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall guardName.str()); 1961355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall guard->setVisibility(var->getVisibility()); 196204e517650569598e847c2ab609672e6df93effe5Richard Smith // If the variable is thread-local, so is its guard variable. 196304e517650569598e847c2ab609672e6df93effe5Richard Smith guard->setThreadLocalMode(var->getThreadLocalMode()); 1964a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guard->setAlignment(guardAlignment.getQuantity()); 1965355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall 1966a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // The ABI says: "It is suggested that it be emitted in the same COMDAT 1967a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // group as the associated data object." In practice, this doesn't work for 1968a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // non-ELF object formats, so only do it for ELF. 19690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Comdat *C = var->getComdat(); 1970a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!D.isLocalVarDecl() && C && 1971a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getTarget().getTriple().isOSBinFormatELF()) { 1972176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines guard->setComdat(C); 1973176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGF.CurFn->setComdat(C); 19740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) { 19750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName())); 1976176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1977176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1978355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall CGM.setStaticLocalDeclGuardAddress(&D, guard); 1979173d51286bcaff4b6b76eebf6542d3b1311142e2Anders Carlsson } 19805cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 1981a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address guardAddr = Address(guard, guardAlignment); 1982a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 19835cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Test whether the variable has completed initialization. 19846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // 19855cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Itanium C++ ABI 3.3.2: 19865cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // The following is pseudo-code showing how these functions can be used: 19875cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // if (obj_guard.first_byte == 0) { 19885cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // if ( __cxa_guard_acquire (&obj_guard) ) { 19895cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // try { 19905cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // ... initialize the object ...; 19915cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // } catch (...) { 19925cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // __cxa_guard_abort (&obj_guard); 19935cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // throw; 19945cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // } 19955cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // ... queue object destructor with __cxa_atexit() ...; 19965cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // __cxa_guard_release (&obj_guard); 19975cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // } 19985cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // } 1999651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 20006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Load the first byte of the guard variable. 20016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::LoadInst *LI = 2002a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateLoad(Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty)); 20036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 20046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Itanium ABI: 20056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // An implementation supporting thread-safety on multiprocessor 20066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // systems must also guarantee that references to the initialized 20076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // object do not occur before the load of the initialization flag. 20086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // 20096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // In LLVM, we do this by marking the load Acquire. 20106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (threadsafe) 20116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LI->setAtomic(llvm::Acquire); 20126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 20136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // For ARM, we should only check the first bit, rather than the entire byte: 20146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // 20156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // ARM C++ ABI 3.2.3.1: 20166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // To support the potential use of initialization guard variables 20176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // as semaphores that are the target of ARM SWP and LDREX/STREX 20186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // synchronizing instructions we define a static initialization 20196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // guard variable to be a 4-byte aligned, 4-byte word with the 20206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // following inline access protocol. 20216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // #define INITIALIZED 1 20226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // if ((obj_guard & INITIALIZED) != INITIALIZED) { 20236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // if (__cxa_guard_acquire(&obj_guard)) 20246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // ... 20256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // } 20266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // 20276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // and similarly for ARM64: 20286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // 20296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // ARM64 C++ ABI 3.2.2: 20306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // This ABI instead only specifies the value bit 0 of the static guard 20316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // variable; all other bits are platform defined. Bit 0 shall be 0 when the 20326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // variable is not initialized and 1 when it is. 20336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *V = 20346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines (UseARMGuardVarABI && !useInt8GuardVariable) 20356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1)) 20366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : LI; 20376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *isInitialized = Builder.CreateIsNull(V, "guard.uninitialized"); 20385cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20395cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check"); 20405cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end"); 20415cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20425cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Check if the first byte of the guard variable is zero. 2043355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock); 20445cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20455cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall CGF.EmitBlock(InitCheckBlock); 20465cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20475cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Variables used when coping with thread-safe statics and exceptions. 20480502a224984a26087ea4d64e8e5d2dd4dca432f6John McCall if (threadsafe) { 20495cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Call __cxa_guard_acquire. 20505cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::Value *V 2051bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard); 20525cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20535cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); 20545cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20555cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 20565cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall InitBlock, EndBlock); 20575cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20585cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Call __cxa_guard_abort along the exceptional edge. 2059355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard); 20605cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20615cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall CGF.EmitBlock(InitBlock); 20625cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall } 20635cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20645cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Emit the initializer and add a global destructor if appropriate. 2065355bba72ca52c4a70ca3c3802412c03a6ec31f24John McCall CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit); 20665cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20670502a224984a26087ea4d64e8e5d2dd4dca432f6John McCall if (threadsafe) { 20685cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Pop the guard-abort cleanup if we pushed one. 20695cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall CGF.PopCleanupBlock(); 20705cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20715cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall // Call __cxa_guard_release. This cannot throw. 2072a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), 2073a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar guardAddr.getPointer()); 20745cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall } else { 2075a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr); 20765cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall } 20775cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 20785cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall CGF.EmitBlock(EndBlock); 20795cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 208020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 208120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall/// Register a global destructor using __cxa_atexit. 208220bb175cb8ae5844034828db094fb948c0e3454aJohn McCallstatic void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, 208320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *dtor, 208404e517650569598e847c2ab609672e6df93effe5Richard Smith llvm::Constant *addr, 208504e517650569598e847c2ab609672e6df93effe5Richard Smith bool TLS) { 20864e3b54b4acb4dd926ca50d7f06c8265d1d24ba79Bill Wendling const char *Name = "__cxa_atexit"; 20874e3b54b4acb4dd926ca50d7f06c8265d1d24ba79Bill Wendling if (TLS) { 20884e3b54b4acb4dd926ca50d7f06c8265d1d24ba79Bill Wendling const llvm::Triple &T = CGF.getTarget().getTriple(); 2089a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Name = T.isOSDarwin() ? "_tlv_atexit" : "__cxa_thread_atexit"; 20904e3b54b4acb4dd926ca50d7f06c8265d1d24ba79Bill Wendling } 209104e517650569598e847c2ab609672e6df93effe5Richard Smith 209220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // We're assuming that the destructor function is something we can 209320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // reasonably call with the default CC. Go ahead and cast it to the 209420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // right prototype. 209520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Type *dtorTy = 209620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo(); 209720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 209820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d); 209920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy }; 210020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::FunctionType *atexitTy = 210120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::FunctionType::get(CGF.IntTy, paramTys, false); 210220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 210320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Fetch the actual function. 210404e517650569598e847c2ab609672e6df93effe5Richard Smith llvm::Constant *atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name); 210520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit)) 210620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall fn->setDoesNotThrow(); 210720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 210820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Create a variable that binds the atexit to this shared object. 210920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *handle = 211020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle"); 211120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 211220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Value *args[] = { 211320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::ConstantExpr::getBitCast(dtor, dtorTy), 211420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy), 211520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall handle 211620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall }; 2117bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall CGF.EmitNounwindRuntimeCall(atexit, args); 211820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall} 211920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 212020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall/// Register a global destructor as best as we know how. 212120bb175cb8ae5844034828db094fb948c0e3454aJohn McCallvoid ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, 212204e517650569598e847c2ab609672e6df93effe5Richard Smith const VarDecl &D, 212320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *dtor, 212420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *addr) { 212520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Use __cxa_atexit if available. 212604e517650569598e847c2ab609672e6df93effe5Richard Smith if (CGM.getCodeGenOpts().CXAAtExit) 212704e517650569598e847c2ab609672e6df93effe5Richard Smith return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind()); 212804e517650569598e847c2ab609672e6df93effe5Richard Smith 212904e517650569598e847c2ab609672e6df93effe5Richard Smith if (D.getTLSKind()) 213004e517650569598e847c2ab609672e6df93effe5Richard Smith CGM.ErrorUnsupported(&D, "non-trivial TLS destruction"); 213120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 213220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // In Apple kexts, we want to add a global destructor entry. 213320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // FIXME: shouldn't this be guarded by some variable? 21347edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (CGM.getLangOpts().AppleKext) { 213520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Generate a global destructor entry. 213620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall return CGM.AddCXXDtorEntry(dtor, addr); 213720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall } 213820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 2139c7971a9efdf9880448a69aabb5182c3c27eecf6dDavid Blaikie CGF.registerGlobalDtorWithAtExit(D, dtor, addr); 214020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall} 2141b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2142176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic bool isThreadWrapperReplaceable(const VarDecl *VD, 2143176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGen::CodeGenModule &CGM) { 2144176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!"); 2145a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Darwin prefers to have references to thread local variables to go through 2146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the thread wrapper instead of directly referencing the backing variable. 2147176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return VD->getTLSKind() == VarDecl::TLS_Dynamic && 2148a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGM.getTarget().getTriple().isOSDarwin(); 2149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 2150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2151b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith/// Get the appropriate linkage for the wrapper function. This is essentially 2152c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// the weak form of the variable's linkage; every translation unit which needs 2153b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith/// the wrapper emits a copy, and we want the linker to merge them. 2154c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic llvm::GlobalValue::LinkageTypes 2155c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesgetThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) { 2156c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalValue::LinkageTypes VarLinkage = 2157c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false); 2158c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2159b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // For internal linkage variables, we don't need an external or weak wrapper. 2160b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (llvm::GlobalValue::isLocalLinkage(VarLinkage)) 2161b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith return VarLinkage; 2162c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If the thread wrapper is replaceable, give it appropriate linkage. 2164a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (isThreadWrapperReplaceable(VD, CGM)) 2165a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) && 2166a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage)) 2167a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return VarLinkage; 2168b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith return llvm::GlobalValue::WeakODRLinkage; 2169b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith} 2170b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2171b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smithllvm::Function * 2172b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard SmithItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, 2173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Value *Val) { 2174b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // Mangle the name for the thread_local wrapper function. 2175b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith SmallString<256> WrapperName; 2176b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith { 2177b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::raw_svector_ostream Out(WrapperName); 2178b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out); 2179b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2180b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2181176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName)) 2182b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith return cast<llvm::Function>(V); 2183b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Type *RetTy = Val->getType(); 2185b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (VD->getType()->isReferenceType()) 2186b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith RetTy = RetTy->getPointerElementType(); 2187b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2188b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false); 2189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Function *Wrapper = 2190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM), 2191c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines WrapperName.str(), &CGM.getModule()); 2192b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // Always resolve references to the wrapper at link time. 2193a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) && 2194a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) && 2195a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()))) 21966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); 2197a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2198a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (isThreadWrapperReplaceable(VD, CGM)) { 2199a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); 2200a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Wrapper->addFnAttr(llvm::Attribute::NoUnwind); 2201a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 2202b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith return Wrapper; 2203b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith} 2204b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2205b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smithvoid ItaniumCXXABI::EmitThreadLocalInitFuncs( 2206a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals, 2207a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ArrayRef<llvm::Function *> CXXThreadLocalInits, 2208a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ArrayRef<const VarDecl *> CXXThreadLocalInitVars) { 2209176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Function *InitFunc = nullptr; 2210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!CXXThreadLocalInits.empty()) { 2211176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Generate a guarded initialization function. 2212176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType *FTy = 2213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); 2214a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction(); 2215a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar InitFunc = CGM.CreateGlobalInitOrDestructFunction(FTy, "__tls_init", FI, 2216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceLocation(), 2217176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*TLS=*/true); 2218176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalVariable *Guard = new llvm::GlobalVariable( 2219176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false, 2220176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalVariable::InternalLinkage, 2221176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::ConstantInt::get(CGM.Int8Ty, 0), "__tls_guard"); 2222176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Guard->setThreadLocal(true); 2223a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2224a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits GuardAlign = CharUnits::One(); 2225a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Guard->setAlignment(GuardAlign.getQuantity()); 2226a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2227176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CodeGenFunction(CGM) 2228a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar .GenerateCXXGlobalInitFunc(InitFunc, CXXThreadLocalInits, 2229a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address(Guard, GuardAlign)); 2230176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 2231a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (const VarDecl *VD : CXXThreadLocals) { 2232a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::GlobalVariable *Var = 2233a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar cast<llvm::GlobalVariable>(CGM.GetGlobalValue(CGM.getMangledName(VD))); 2234176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2235176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Some targets require that all access to thread local variables go through 2236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the thread wrapper. This means that we cannot attempt to create a thread 2237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // wrapper or a thread helper. 2238176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (isThreadWrapperReplaceable(VD, CGM) && !VD->hasDefinition()) 2239176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines continue; 2240b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2241b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // Mangle the name for the thread_local initialization function. 2242b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith SmallString<256> InitFnName; 2243b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith { 2244b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::raw_svector_ostream Out(InitFnName); 2245b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith getMangleContext().mangleItaniumThreadLocalInit(VD, Out); 2246b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2247b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2248b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // If we have a definition for the variable, emit the initialization 2249b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // function as an alias to the global Init function (if any). Otherwise, 2250b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // produce a declaration of the initialization function. 22516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::GlobalValue *Init = nullptr; 2252b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith bool InitIsInitFunc = false; 2253b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (VD->hasDefinition()) { 2254b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith InitIsInitFunc = true; 2255b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (InitFunc) 22566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(), 22576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines InitFunc); 2258b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } else { 2259b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // Emit a weak global function referring to the initialization function. 2260b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // This function will not exist if the TU defining the thread_local 2261b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // variable in question does not need any dynamic initialization for 2262b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // its thread_local variables. 2263b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false); 2264b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Init = llvm::Function::Create( 2265b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(), 2266b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith &CGM.getModule()); 2267b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2268b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2269b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (Init) 2270b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Init->setVisibility(Var->getVisibility()); 2271b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2272b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var); 2273b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::LLVMContext &Context = CGM.getModule().getContext(); 2274b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper); 2275a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGBuilderTy Builder(CGM, Entry); 2276b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (InitIsInitFunc) { 2277b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (Init) 2278a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateCall(Init); 2279b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } else { 2280b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // Don't know whether we have an init function. Call it if it exists. 2281b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::Value *Have = Builder.CreateIsNotNull(Init); 2282b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper); 2283b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper); 2284b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Builder.CreateCondBr(Have, InitBB, ExitBB); 2285b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2286b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Builder.SetInsertPoint(InitBB); 2287a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Builder.CreateCall(Init); 2288b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Builder.CreateBr(ExitBB); 2289b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2290b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Builder.SetInsertPoint(ExitBB); 2291b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2292b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2293b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // For a reference, the result of the wrapper function is a pointer to 2294b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // the referenced object. 2295b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith llvm::Value *Val = Var; 2296b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (VD->getType()->isReferenceType()) { 2297a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits Align = CGM.getContext().getDeclAlign(VD); 2298a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Val = Builder.CreateAlignedLoad(Val, Align); 2299b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2300176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Val->getType() != Wrapper->getReturnType()) 2301176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Val = Builder.CreatePointerBitCastOrAddrSpaceCast( 2302176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Val, Wrapper->getReturnType(), ""); 2303b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith Builder.CreateRet(Val); 2304b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith } 2305b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith} 2306b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2307651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesLValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, 2308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VarDecl *VD, 2309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType LValType) { 2310a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD); 2311176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val); 2312b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2313a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::CallInst *CallVal = CGF.Builder.CreateCall(Wrapper); 2314a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (isThreadWrapperReplaceable(VD, CGF.CGM)) 2315a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); 2316b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith 2317b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith LValue LV; 2318b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith if (VD->getType()->isReferenceType()) 2319a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar LV = CGF.MakeNaturalAlignAddrLValue(CallVal, LValType); 2320b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith else 2321a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar LV = CGF.MakeAddrLValue(CallVal, LValType, 2322a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.getContext().getDeclAlign(VD)); 2323b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith // FIXME: need setObjCGCLValueClass? 2324b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith return LV; 2325b80a16eadd0dacabfc1c32412e243ccb99dd664dRichard Smith} 2326e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 2327e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne/// Return whether the given global decl needs a VTT parameter, which it does 2328e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne/// if it's a base constructor or destructor with virtual bases. 2329e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbournebool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) { 2330e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); 2331e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 2332e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne // We don't have any virtual bases, just return early. 2333e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (!MD->getParent()->getNumVBases()) 2334e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne return false; 2335e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 2336e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne // Check if we have a base constructor. 2337e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) 2338e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne return true; 2339e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 2340e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne // Check if we have a base destructor. 2341e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) 2342e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne return true; 2343e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne 2344e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne return false; 2345e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne} 2346c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2347c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace { 2348c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesclass ItaniumRTTIBuilder { 2349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CodeGenModule &CGM; // Per-module state. 2350c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::LLVMContext &VMContext; 2351c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const ItaniumCXXABI &CXXABI; // Per-module state. 2352c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2353c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// Fields - The fields of the RTTI descriptor currently being built. 2354c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SmallVector<llvm::Constant *, 16> Fields; 2355c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// GetAddrOfTypeName - Returns the mangled type name of the given type. 2357c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable * 2358c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage); 2359c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2360c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 2361c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// descriptor of the given type. 2362c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty); 2363c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2364c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildVTablePointer - Build the vtable pointer for the given type. 2365c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildVTablePointer(const Type *Ty); 2366c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2367c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single 2368c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b. 2369c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildSIClassTypeInfo(const CXXRecordDecl *RD); 2370c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2371c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for 2372c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// classes with bases that do not satisfy the abi::__si_class_type_info 2373c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c. 2374c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildVMIClassTypeInfo(const CXXRecordDecl *RD); 2375c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2376c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used 2377c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// for pointer types. 2378c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildPointerTypeInfo(QualType PointeeTy); 2379c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2380c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildObjCObjectTypeInfo - Build the appropriate kind of 2381c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// type_info for an object type. 2382c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty); 2383c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2384c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 2385c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// struct, used for member pointer types. 2386c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty); 2387c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2388c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinespublic: 2389c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(const ItaniumCXXABI &ABI) 2390c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {} 2391c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2392c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Pointer type info flags. 2393c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines enum { 2394c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// PTI_Const - Type has const qualifier. 2395c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PTI_Const = 0x1, 2396c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2397c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// PTI_Volatile - Type has volatile qualifier. 2398c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PTI_Volatile = 0x2, 2399c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2400c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// PTI_Restrict - Type has restrict qualifier. 2401c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PTI_Restrict = 0x4, 2402c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2403c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// PTI_Incomplete - Type is incomplete. 2404c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PTI_Incomplete = 0x8, 2405c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2406c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// PTI_ContainingClassIncomplete - Containing class is incomplete. 2407c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// (in pointer to member). 2408c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PTI_ContainingClassIncomplete = 0x10 2409c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 2410c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2411c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // VMI type info flags. 2412c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines enum { 2413c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance. 2414c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VMI_NonDiamondRepeat = 0x1, 2415c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2416c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// VMI_DiamondShaped - Class is diamond shaped. 2417c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VMI_DiamondShaped = 0x2 2418c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 2419c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2420c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Base class type info flags. 2421c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines enum { 2422c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BCTI_Virtual - Base class is virtual. 2423c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BCTI_Virtual = 0x1, 2424c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2425c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BCTI_Public - Base class is public. 2426c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BCTI_Public = 0x2 2427c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 2428c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2429c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// BuildTypeInfo - Build the RTTI type info struct for the given type. 2430c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// 2431c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// \param Force - true to force the creation of this RTTI value 2432c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false); 2433c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}; 2434c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2435c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2436c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName( 2437c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) { 2438a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SmallString<256> Name; 2439a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::raw_svector_ostream Out(Name); 2440c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out); 2441c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2442c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // We know that the mangled name of the type starts at index 4 of the 2443c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // mangled name of the typename, so we can just index into it in order to 2444c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // get the mangled name of the type. 2445c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext, 2446c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Name.substr(4)); 2447c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2448c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable *GV = 2449c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage); 2450c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2451c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines GV->setInitializer(Init); 2452c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2453c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return GV; 2454c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2455c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2456c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Constant * 2457c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) { 2458c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Mangle the RTTI name. 2459a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SmallString<256> Name; 2460a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::raw_svector_ostream Out(Name); 2461c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out); 2462c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2463c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Look for an existing global. 2464c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name); 2465c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2466c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!GV) { 2467c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Create a new global variable. 2468c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy, 2469c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /*Constant=*/true, 2470c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalValue::ExternalLinkage, nullptr, 2471c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Name); 2472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { 2473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); 2474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (RD->hasAttr<DLLImportAttr>()) 2475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); 2476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 2477c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2478c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2479c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); 2480c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2481c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2482c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type 2483c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// info for that type is defined in the standard library. 2484c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { 2485c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.2: 2486c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Basic type information (e.g. for "int", "bool", etc.) will be kept in 2487c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // the run-time support library. Specifically, the run-time support 2488c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // library should contain type_info objects for the types X, X* and 2489c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char, 2490c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // unsigned char, signed char, short, unsigned short, int, unsigned int, 2491c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // long, unsigned long, long long, unsigned long long, float, double, 2492c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // long double, char16_t, char32_t, and the IEEE 754r decimal and 2493c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // half-precision floating point types. 2494c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines switch (Ty->getKind()) { 2495c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Void: 2496c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::NullPtr: 2497c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Bool: 2498c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::WChar_S: 2499c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::WChar_U: 2500c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Char_U: 2501c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Char_S: 2502c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::UChar: 2503c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::SChar: 2504c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Short: 2505c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::UShort: 2506c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Int: 2507c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::UInt: 2508c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Long: 2509c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::ULong: 2510c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::LongLong: 2511c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::ULongLong: 2512c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Half: 2513c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Float: 2514c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Double: 2515c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::LongDouble: 2516c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Char16: 2517c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Char32: 2518c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Int128: 2519c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::UInt128: 2520c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage1d: 2521c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage1dArray: 2522c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage1dBuffer: 2523c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage2d: 2524c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage2dArray: 2525a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dDepth: 2526a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dArrayDepth: 2527a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dMSAA: 2528a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dArrayMSAA: 2529a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dMSAADepth: 2530a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLImage2dArrayMSAADepth: 2531c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLImage3d: 2532c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLSampler: 2533c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::OCLEvent: 2534a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLClkEvent: 2535a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLQueue: 2536a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLNDRange: 2537a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case BuiltinType::OCLReserveID: 2538c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 2539c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2540c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Dependent: 2541c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define BUILTIN_TYPE(Id, SingletonId) 2542c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define PLACEHOLDER_TYPE(Id, SingletonId) \ 2543c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::Id: 2544c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include "clang/AST/BuiltinTypes.def" 2545c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("asking for RRTI for a placeholder type!"); 2546c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2547c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::ObjCId: 2548c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::ObjCClass: 2549c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case BuiltinType::ObjCSel: 2550c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("FIXME: Objective-C types are unsupported!"); 2551c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2552c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2553c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Invalid BuiltinType Kind!"); 2554c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2555c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2556c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) { 2557c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType PointeeTy = PointerTy->getPointeeType(); 2558c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy); 2559c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!BuiltinTy) 2560c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2561c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2562c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check the qualifiers. 2563c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Qualifiers Quals = PointeeTy.getQualifiers(); 2564c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Quals.removeConst(); 2565c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2566c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Quals.empty()) 2567c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2568c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2569c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return TypeInfoIsInStandardLibrary(BuiltinTy); 2570c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2571c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2572c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// IsStandardLibraryRTTIDescriptor - Returns whether the type 2573c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// information for the given type exists in the standard library. 2574c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool IsStandardLibraryRTTIDescriptor(QualType Ty) { 2575c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Type info for builtin types is defined in the standard library. 2576c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty)) 2577c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return TypeInfoIsInStandardLibrary(BuiltinTy); 2578c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2579c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Type info for some pointer types to builtin types is defined in the 2580c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // standard library. 2581c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) 2582c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return TypeInfoIsInStandardLibrary(PointerTy); 2583c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2584c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2585c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2586c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2587c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for 2588c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// the given type exists somewhere else, and that we should not emit the type 2589c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// information in this translation unit. Assumes that it is not a 2590c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// standard-library type. 2591c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, 2592c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType Ty) { 2593c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ASTContext &Context = CGM.getContext(); 2594c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2595c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If RTTI is disabled, assume it might be disabled in the 2596c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // translation unit that defines any potential key function, too. 2597c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Context.getLangOpts().RTTI) return false; 2598c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2599c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { 2600c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); 2601c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!RD->hasDefinition()) 2602c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2603c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2604c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!RD->isDynamicClass()) 2605c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2606c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2607c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // FIXME: this may need to be reconsidered if the key function 2608c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // changes. 2609a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // N.B. We must always emit the RTTI data ourselves if there exists a key 2610a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // function. 2611a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool IsDLLImport = RD->hasAttr<DLLImportAttr>(); 2612176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGM.getVTables().isVTableExternal(RD)) 2613a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return IsDLLImport ? false : true; 2614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2615a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (IsDLLImport) 2616176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 2617c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2618c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2619c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2620c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2621c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2622c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// IsIncompleteClassType - Returns whether the given record type is incomplete. 2623c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool IsIncompleteClassType(const RecordType *RecordTy) { 2624c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return !RecordTy->getDecl()->isCompleteDefinition(); 2625c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2626c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2627c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// ContainsIncompleteClassType - Returns whether the given type contains an 2628c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// incomplete class type. This is true if 2629c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// 2630c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// * The given type is an incomplete class type. 2631c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// * The given type is a pointer type whose pointee type contains an 2632c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// incomplete class type. 2633c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// * The given type is a member pointer type whose class is an incomplete 2634c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// class type. 2635c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// * The given type is a member pointer type whoise pointee type contains an 2636c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// incomplete class type. 2637c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// is an indirect or direct pointer to an incomplete class type. 2638c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool ContainsIncompleteClassType(QualType Ty) { 2639c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { 2640c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (IsIncompleteClassType(RecordTy)) 2641c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 2642c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2643c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2644c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) 2645c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return ContainsIncompleteClassType(PointerTy->getPointeeType()); 2646c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2647c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const MemberPointerType *MemberPointerTy = 2648c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines dyn_cast<MemberPointerType>(Ty)) { 2649c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check if the class type is incomplete. 2650c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass()); 2651c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (IsIncompleteClassType(ClassType)) 2652c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 2653c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2654c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return ContainsIncompleteClassType(MemberPointerTy->getPointeeType()); 2655c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2656c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2657c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2658c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2659c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2660c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CanUseSingleInheritance - Return whether the given record decl has a "single, 2661c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// public, non-virtual base at offset zero (i.e. the derived class is dynamic 2662c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// iff the base is)", according to Itanium C++ ABI, 2.95p6b. 2663c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic bool CanUseSingleInheritance(const CXXRecordDecl *RD) { 2664c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check the number of bases. 2665c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (RD->getNumBases() != 1) 2666c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2667c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2668c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Get the base. 2669c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(); 2670c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2671c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check that the base is not virtual. 2672c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base->isVirtual()) 2673c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2674c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2675c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check that the base is public. 2676c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base->getAccessSpecifier() != AS_public) 2677c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2678c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2679c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check that the class is dynamic iff the base is. 2680c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *BaseDecl = 2681c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 2682c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!BaseDecl->isEmpty() && 2683c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BaseDecl->isDynamicClass() != RD->isDynamicClass()) 2684c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return false; 2685c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2686c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return true; 2687c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2688c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2689c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) { 2690c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__class_type_info. 2691c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines static const char * const ClassTypeInfo = 2692c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "_ZTVN10__cxxabiv117__class_type_infoE"; 2693c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__si_class_type_info. 2694c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines static const char * const SIClassTypeInfo = 2695c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "_ZTVN10__cxxabiv120__si_class_type_infoE"; 2696c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__vmi_class_type_info. 2697c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines static const char * const VMIClassTypeInfo = 2698c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "_ZTVN10__cxxabiv121__vmi_class_type_infoE"; 2699c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2700c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const char *VTableName = nullptr; 2701c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2702c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines switch (Ty->getTypeClass()) { 2703c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define TYPE(Class, Base) 2704c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define ABSTRACT_TYPE(Class, Base) 2705c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 2706c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 2707c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define DEPENDENT_TYPE(Class, Base) case Type::Class: 2708c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include "clang/AST/TypeNodes.def" 2709c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Non-canonical and dependent types shouldn't get here"); 2710c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2711c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::LValueReference: 2712c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::RValueReference: 2713c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("References shouldn't get here"); 2714c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2715c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Auto: 2716c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Undeduced auto type shouldn't get here"); 2717c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2718c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Builtin: 2719c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // GCC treats vector and complex types as fundamental types. 2720c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Vector: 2721c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ExtVector: 2722c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Complex: 2723c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Atomic: 2724c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // FIXME: GCC treats block pointers as fundamental types?! 2725c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::BlockPointer: 2726c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__fundamental_type_info. 2727c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE"; 2728c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2729c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2730c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ConstantArray: 2731c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::IncompleteArray: 2732c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::VariableArray: 2733c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__array_type_info. 2734c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv117__array_type_infoE"; 2735c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2736c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2737c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::FunctionNoProto: 2738c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::FunctionProto: 2739c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__function_type_info. 2740c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv120__function_type_infoE"; 2741c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2742c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2743c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Enum: 2744c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__enum_type_info. 2745c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE"; 2746c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2747c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2748c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Record: { 2749c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *RD = 2750c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()); 2751c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2752c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!RD->hasDefinition() || !RD->getNumBases()) { 2753c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = ClassTypeInfo; 2754c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else if (CanUseSingleInheritance(RD)) { 2755c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = SIClassTypeInfo; 2756c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 2757c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = VMIClassTypeInfo; 2758c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2759c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2760c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2761c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2762c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2763c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCObject: 2764c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Ignore protocol qualifiers. 2765c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr(); 2766c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2767c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Handle id and Class. 2768c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (isa<BuiltinType>(Ty)) { 2769c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = ClassTypeInfo; 2770c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2771c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2772c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2773c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(isa<ObjCInterfaceType>(Ty)); 2774c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Fall through. 2775c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2776c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCInterface: 2777c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) { 2778c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = SIClassTypeInfo; 2779c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 2780c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = ClassTypeInfo; 2781c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2782c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2783c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2784c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCObjectPointer: 2785c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Pointer: 2786c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__pointer_type_info. 2787c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE"; 2788c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2789c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2790c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::MemberPointer: 2791c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__pointer_to_member_type_info. 2792c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE"; 2793c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2794c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2795c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2796c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *VTable = 2797c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy); 2798c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2799c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *PtrDiffTy = 2800c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 2801c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2802c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The vtable address point is 2. 2803c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2); 280458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar VTable = 280558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.Int8PtrTy, VTable, Two); 2806c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy); 2807c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2808c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(VTable); 2809c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2810c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2811c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// \brief Return the linkage that the type info and type info name constants 2812c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// should have for the given type. 2813c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, 2814c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType Ty) { 2815c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 2816c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // In addition, it and all of the intermediate abi::__pointer_type_info 2817c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // structs in the chain down to the abi::__class_type_info for the 2818c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // incomplete class type must be prevented from resolving to the 2819c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // corresponding type_info structs for the complete class type, possibly 2820c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // by making them local static objects. Finally, a dummy class RTTI is 2821c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // generated for the incomplete type that will not resolve to the final 2822c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // complete class RTTI (because the latter need not exist), possibly by 2823c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // making it a local static object. 2824c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (ContainsIncompleteClassType(Ty)) 2825c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::GlobalValue::InternalLinkage; 2826c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2827c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines switch (Ty->getLinkage()) { 2828c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case NoLinkage: 2829c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case InternalLinkage: 2830c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case UniqueExternalLinkage: 2831c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::GlobalValue::InternalLinkage; 2832c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2833c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case VisibleNoLinkage: 2834c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case ExternalLinkage: 2835c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!CGM.getLangOpts().RTTI) { 2836c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // RTTI is not enabled, which means that this type info struct is going 2837c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // to be used for exception handling. Give it linkonce_odr linkage. 2838c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::GlobalValue::LinkOnceODRLinkage; 2839c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2840c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2841c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { 2842c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); 2843c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (RD->hasAttr<WeakAttr>()) 2844c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::GlobalValue::WeakODRLinkage; 2845a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (RD->isDynamicClass()) { 2846a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::GlobalValue::LinkageTypes LT = CGM.getVTableLinkage(RD); 2847a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // MinGW won't export the RTTI information when there is a key function. 2848a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Make sure we emit our own copy instead of attempting to dllimport it. 2849a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (RD->hasAttr<DLLImportAttr>() && 2850a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::GlobalValue::isAvailableExternallyLinkage(LT)) 2851a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar LT = llvm::GlobalValue::LinkOnceODRLinkage; 2852a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return LT; 2853a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 2854c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2855c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2856c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::GlobalValue::LinkOnceODRLinkage; 2857c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2858c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2859c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Invalid linkage!"); 2860c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 2861c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2862c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { 2863c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // We want to operate on the canonical type. 2864c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Ty = CGM.getContext().getCanonicalType(Ty); 2865c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2866c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check if we've already emitted an RTTI descriptor for this type. 2867a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SmallString<256> Name; 2868a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::raw_svector_ostream Out(Name); 2869c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out); 2870c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2871c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name); 2872c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (OldGV && !OldGV->isDeclaration()) { 2873c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(!OldGV->hasAvailableExternallyLinkage() && 2874c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines "available_externally typeinfos not yet implemented"); 2875c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2876c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy); 2877c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2878c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2879c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Check if there is already an external RTTI descriptor for this type. 2880c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty); 2881c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty))) 2882c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return GetAddrOfExternalRTTIDescriptor(Ty); 2883c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2884c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Emit the standard library with external linkage. 2885c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable::LinkageTypes Linkage; 2886c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (IsStdLib) 2887c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Linkage = llvm::GlobalValue::ExternalLinkage; 2888c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else 2889c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Linkage = getTypeInfoLinkage(CGM, Ty); 2890c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2891c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Add the vtable pointer. 2892c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildVTablePointer(cast<Type>(Ty)); 2893c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2894c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // And the name. 2895c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage); 2896c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *TypeNameField; 2897c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2898c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If we're supposed to demote the visibility, be sure to set a flag 2899c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // to use a string comparison for type_info comparisons. 2900c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness = 2901c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CXXABI.classifyRTTIUniqueness(Ty, Linkage); 2902c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) { 2903c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The flag is the sign bit, which on ARM64 is defined to be clear 2904c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // for global pointers. This is very ARM64-specific. 2905c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty); 2906c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *flag = 2907c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63); 2908c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag); 2909c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines TypeNameField = 2910c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy); 2911c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 2912c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy); 2913c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2914c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(TypeNameField); 2915c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2916c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines switch (Ty->getTypeClass()) { 2917c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define TYPE(Class, Base) 2918c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define ABSTRACT_TYPE(Class, Base) 2919c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 2920c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 2921c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#define DEPENDENT_TYPE(Class, Base) case Type::Class: 2922c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#include "clang/AST/TypeNodes.def" 2923c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Non-canonical and dependent types shouldn't get here"); 2924c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2925c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // GCC treats vector types as fundamental types. 2926c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Builtin: 2927c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Vector: 2928c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ExtVector: 2929c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Complex: 2930c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::BlockPointer: 2931c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p4: 2932c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__fundamental_type_info adds no data members to std::type_info. 2933c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2934c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2935c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::LValueReference: 2936c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::RValueReference: 2937c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("References shouldn't get here"); 2938c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2939c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Auto: 2940c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm_unreachable("Undeduced auto type shouldn't get here"); 2941c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2942c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ConstantArray: 2943c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::IncompleteArray: 2944c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::VariableArray: 2945c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p5: 2946c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__array_type_info adds no data members to std::type_info. 2947c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2948c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2949c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::FunctionNoProto: 2950c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::FunctionProto: 2951c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p5: 2952c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__function_type_info adds no data members to std::type_info. 2953c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2954c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2955c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Enum: 2956c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p5: 2957c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // abi::__enum_type_info adds no data members to std::type_info. 2958c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2959c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2960c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Record: { 2961c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *RD = 2962c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()); 2963c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!RD->hasDefinition() || !RD->getNumBases()) { 2964c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // We don't need to emit any fields. 2965c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2966c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2967c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2968c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (CanUseSingleInheritance(RD)) 2969c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildSIClassTypeInfo(RD); 2970c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else 2971c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildVMIClassTypeInfo(RD); 2972c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2973c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2974c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2975c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2976c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCObject: 2977c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCInterface: 2978c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty)); 2979c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2980c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2981c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::ObjCObjectPointer: 2982c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType()); 2983c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2984c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2985c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Pointer: 2986c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType()); 2987c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2988c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2989c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::MemberPointer: 2990c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty)); 2991c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2992c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2993c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Type::Atomic: 2994c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // No fields, at least for the moment. 2995c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines break; 2996c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 2997c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 2998c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields); 2999c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 30000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines llvm::Module &M = CGM.getModule(); 3001c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalVariable *GV = 30020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines new llvm::GlobalVariable(M, Init->getType(), 30030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /*Constant=*/true, Linkage, Init, Name); 30040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3005c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If there's already an old global variable, replace it with the new one. 3006c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (OldGV) { 3007c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines GV->takeName(OldGV); 3008c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *NewPtr = 3009c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); 3010c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OldGV->replaceAllUsesWith(NewPtr); 3011c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OldGV->eraseFromParent(); 3012c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 3013c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3014a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (CGM.supportsCOMDAT() && GV->isWeakForLinker()) 3015a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar GV->setComdat(M.getOrInsertComdat(GV->getName())); 3016a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 3017c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The Itanium ABI specifies that type_info objects must be globally 3018c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // unique, with one exception: if the type is an incomplete class 3019c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // type or a (possibly indirect) pointer to one. That exception 3020c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // affects the general case of comparing type_info objects produced 3021c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // by the typeid operator, which is why the comparison operators on 3022c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // std::type_info generally use the type_info name pointers instead 3023c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // of the object addresses. However, the language's built-in uses 3024c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // of RTTI generally require class types to be complete, even when 3025c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // manipulating pointers to those class types. This allows the 3026c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // implementation of dynamic_cast to rely on address equality tests, 3027c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // which is much faster. 3028c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3029c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // All of this is to say that it's important that both the type_info 3030c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // object and the type_info name be uniqued when weakly emitted. 3031c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3032c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Give the type_info object and name the formal visibility of the 3033c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // type itself. 3034c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::GlobalValue::VisibilityTypes llvmVisibility; 3035c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (llvm::GlobalValue::isLocalLinkage(Linkage)) 3036c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If the linkage is local, only default visibility makes sense. 3037c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvmVisibility = llvm::GlobalValue::DefaultVisibility; 3038c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden) 3039c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvmVisibility = llvm::GlobalValue::HiddenVisibility; 3040c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else 3041c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); 3042c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines TypeName->setVisibility(llvmVisibility); 3043c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines GV->setVisibility(llvmVisibility); 3044c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3045c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); 3046c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3047c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3048c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// ComputeQualifierFlags - Compute the pointer type info flags from the 3049c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// given qualifier. 3050c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic unsigned ComputeQualifierFlags(Qualifiers Quals) { 3051c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = 0; 3052c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3053c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Quals.hasConst()) 3054c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::PTI_Const; 3055c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Quals.hasVolatile()) 3056c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::PTI_Volatile; 3057c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Quals.hasRestrict()) 3058c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::PTI_Restrict; 3059c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3060c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Flags; 3061c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3062c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3063c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info 3064c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// for the given Objective-C object type. 3065c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) { 3066c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Drop qualifiers. 3067c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const Type *T = OT->getBaseType().getTypePtr(); 3068c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T)); 3069c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3070c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The builtin types are abi::__class_type_infos and don't require 3071c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // extra fields. 3072c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (isa<BuiltinType>(T)) return; 3073c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3074c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl(); 3075c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ObjCInterfaceDecl *Super = Class->getSuperClass(); 3076c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3077c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Root classes are also __class_type_info. 3078c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Super) return; 3079c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3080c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super); 3081c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3082c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Everything else is single inheritance. 3083c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *BaseTypeInfo = 3084c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy); 3085c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(BaseTypeInfo); 3086c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3087c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3088c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single 3089c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// inheritance, according to the Itanium C++ ABI, 2.95p6b. 3090c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) { 3091c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p6b: 3092c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // It adds to abi::__class_type_info a single member pointing to the 3093c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // type_info structure for the base type, 3094c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *BaseTypeInfo = 3095c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType()); 3096c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(BaseTypeInfo); 3097c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3098c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3099c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace { 3100c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// SeenBases - Contains virtual and non-virtual bases seen when traversing 3101c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines /// a class hierarchy. 3102c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines struct SeenBases { 3103c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases; 3104c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases; 3105c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 3106c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3107c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3108c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in 3109c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// abi::__vmi_class_type_info. 3110c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// 3111c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 3112c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SeenBases &Bases) { 3113c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3114c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = 0; 3115c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3116c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *BaseDecl = 3117c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 3118c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3119c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base->isVirtual()) { 3120c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Mark the virtual base as seen. 3121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Bases.VirtualBases.insert(BaseDecl).second) { 3122c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If this virtual base has been seen before, then the class is diamond 3123c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // shaped. 3124c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped; 3125c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 3126c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Bases.NonVirtualBases.count(BaseDecl)) 3127c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; 3128c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 3129c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 3130c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Mark the non-virtual base as seen. 3131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Bases.NonVirtualBases.insert(BaseDecl).second) { 3132c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If this non-virtual base has been seen before, then the class has non- 3133c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // diamond shaped repeated inheritance. 3134c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; 3135c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } else { 3136c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Bases.VirtualBases.count(BaseDecl)) 3137c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat; 3138c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 3139c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 3140c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3141c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Walk all bases. 3142c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const auto &I : BaseDecl->bases()) 3143c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases); 3144c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3145c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Flags; 3146c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3147c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3148c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstatic unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) { 3149c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = 0; 3150c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SeenBases Bases; 3151c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3152c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Walk all bases. 3153c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const auto &I : RD->bases()) 3154c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases); 3155c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3156c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return Flags; 3157c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3158c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3159c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for 3160c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// classes with bases that do not satisfy the abi::__si_class_type_info 3161c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c. 3162c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { 3163c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *UnsignedIntLTy = 3164c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); 3165c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3166c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p6c: 3167c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __flags is a word with flags describing details about the class 3168c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // structure, which may be referenced by using the __flags_masks 3169c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // enumeration. These flags refer to both direct and indirect bases. 3170c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = ComputeVMIClassTypeInfoFlags(RD); 3171c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); 3172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3173c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p6c: 3174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __base_count is a word with the number of direct proper base class 3175c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // descriptions that follow. 3176c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases())); 3177c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3178c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!RD->getNumBases()) 3179c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return; 3180c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3181c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *LongLTy = 3182c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getTypes().ConvertType(CGM.getContext().LongTy); 3183c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3184c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Now add the base class descriptions. 3185c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3186c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p6c: 3187c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __base_info[] is an array of base class descriptions -- one for every 3188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // direct proper base. Each description is of the type: 3189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // 3190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // struct abi::__base_class_type_info { 3191c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // public: 3192c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // const __class_type_info *__base_type; 3193c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // long __offset_flags; 3194c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // 3195c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // enum __offset_flags_masks { 3196c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __virtual_mask = 0x1, 3197c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __public_mask = 0x2, 3198c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __offset_shift = 8 3199c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // }; 3200c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // }; 3201c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const auto &Base : RD->bases()) { 3202c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The __base_type member points to the RTTI for the base type. 3203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); 3204c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3205c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const CXXRecordDecl *BaseDecl = 3206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 3207c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3208c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines int64_t OffsetFlags = 0; 3209c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3210c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // All but the lower 8 bits of __offset_flags are a signed offset. 3211c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // For a non-virtual base, this is the offset in the object of the base 3212c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // subobject. For a virtual base, this is the offset in the virtual table of 3213c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // the virtual base offset for the virtual base referenced (negative). 3214c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CharUnits Offset; 3215c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base.isVirtual()) 3216c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Offset = 3217c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl); 3218c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines else { 3219c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 3220c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Offset = Layout.getBaseClassOffset(BaseDecl); 3221c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 3222c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3223c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OffsetFlags = uint64_t(Offset.getQuantity()) << 8; 3224c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3225c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // The low-order byte of __offset_flags contains flags, as given by the 3226c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // masks from the enumeration __offset_flags_masks. 3227c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base.isVirtual()) 3228c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OffsetFlags |= BCTI_Virtual; 3229c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Base.getAccessSpecifier() == AS_public) 3230c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines OffsetFlags |= BCTI_Public; 3231c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3232c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags)); 3233c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 3234c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3235c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3236c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, 3237c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// used for pointer types. 3238c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) { 3239c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Qualifiers Quals; 3240c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType UnqualifiedPointeeTy = 3241c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals); 3242c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3243c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3244c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __flags is a flag word describing the cv-qualification and other 3245c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // attributes of the type pointed to 3246c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = ComputeQualifierFlags(Quals); 3247c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3248c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3249c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // When the abi::__pbase_type_info is for a direct or indirect pointer to an 3250c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // incomplete class type, the incomplete target type flag is set. 3251c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (ContainsIncompleteClassType(UnqualifiedPointeeTy)) 3252c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= PTI_Incomplete; 3253c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3254c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *UnsignedIntLTy = 3255c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); 3256c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); 3257c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3258c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3259c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __pointee is a pointer to the std::type_info derivation for the 3260c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // unqualified type being pointed to. 3261c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *PointeeTypeInfo = 3262c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy); 3263c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(PointeeTypeInfo); 3264c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3265c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3266c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 3267c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// struct, used for member pointer types. 3268c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid 3269c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { 3270c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType PointeeTy = Ty->getPointeeType(); 3271c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3272c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Qualifiers Quals; 3273c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType UnqualifiedPointeeTy = 3274c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals); 3275c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3276c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3277c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __flags is a flag word describing the cv-qualification and other 3278c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // attributes of the type pointed to. 3279c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines unsigned Flags = ComputeQualifierFlags(Quals); 3280c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3281c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines const RecordType *ClassType = cast<RecordType>(Ty->getClass()); 3282c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3283c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3284c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // When the abi::__pbase_type_info is for a direct or indirect pointer to an 3285c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // incomplete class type, the incomplete target type flag is set. 3286c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (ContainsIncompleteClassType(UnqualifiedPointeeTy)) 3287c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= PTI_Incomplete; 3288c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3289c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (IsIncompleteClassType(ClassType)) 3290c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Flags |= PTI_ContainingClassIncomplete; 3291c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3292c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Type *UnsignedIntLTy = 3293c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); 3294c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags)); 3295c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3296c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p7: 3297c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __pointee is a pointer to the std::type_info derivation for the 3298c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // unqualified type being pointed to. 3299c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines llvm::Constant *PointeeTypeInfo = 3300c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy); 3301c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back(PointeeTypeInfo); 3302c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3303c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // Itanium C++ ABI 2.9.5p9: 3304c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // __context is a pointer to an abi::__class_type_info corresponding to the 3305c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // class type containing the member pointed to 3306c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // (e.g., the "A" in "int A::*"). 3307c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Fields.push_back( 3308c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0))); 3309c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3310c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3311c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesllvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) { 3312c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty); 3313c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3314c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3315c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type) { 3316c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType PointerType = getContext().getPointerType(Type); 3317c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType PointerTypeConst = getContext().getPointerType(Type.withConst()); 3318c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true); 3319c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true); 3320c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true); 3321c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3322c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3323c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid ItaniumCXXABI::EmitFundamentalRTTIDescriptors() { 3324c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType FundamentalTypes[] = { 3325c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().VoidTy, getContext().NullPtrTy, 3326c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().BoolTy, getContext().WCharTy, 3327c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().CharTy, getContext().UnsignedCharTy, 3328c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().SignedCharTy, getContext().ShortTy, 3329c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().UnsignedShortTy, getContext().IntTy, 3330c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().UnsignedIntTy, getContext().LongTy, 3331c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().UnsignedLongTy, getContext().LongLongTy, 3332c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().UnsignedLongLongTy, getContext().HalfTy, 3333c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().FloatTy, getContext().DoubleTy, 3334c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().LongDoubleTy, getContext().Char16Ty, 3335c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines getContext().Char32Ty, 3336c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines }; 3337c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const QualType &FundamentalType : FundamentalTypes) 3338c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines EmitFundamentalRTTIDescriptor(FundamentalType); 3339c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3340c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3341c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// What sort of uniqueness rules should we use for the RTTI for the 3342c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines/// given type? 3343c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness( 3344c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const { 3345c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (shouldRTTIBeUnique()) 3346c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return RUK_Unique; 3347c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3348c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // It's only necessary for linkonce_odr or weak_odr linkage. 3349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage && 3350c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Linkage != llvm::GlobalValue::WeakODRLinkage) 3351c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return RUK_Unique; 3352c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3353c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // It's only necessary with default visibility. 3354c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (CanTy->getVisibility() != DefaultVisibility) 3355c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return RUK_Unique; 3356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3357c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If we're not required to publish this symbol, hide it. 3358c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage) 3359c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return RUK_NonUniqueHidden; 3360c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 3361c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // If we're required to publish this symbol, as we might be under an 3362c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // explicit instantiation, leave it with default visibility but 3363c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines // enable string-comparisons. 3364c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(Linkage == llvm::GlobalValue::WeakODRLinkage); 3365c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return RUK_NonUniqueVisible; 3366c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 3367176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3368176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Find out how to codegen the complete destructor and constructor 3369176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace { 3370176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesenum class StructorCodegen { Emit, RAUW, Alias, COMDAT }; 3371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 3372176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic StructorCodegen getCodegenToUse(CodeGenModule &CGM, 3373176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXMethodDecl *MD) { 3374176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!CGM.getCodeGenOpts().CXXCtorDtorAliases) 3375176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::Emit; 3376176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3377176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // The complete and base structors are not equivalent if there are any virtual 3378176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // bases, so emit separate functions. 3379176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (MD->getParent()->getNumVBases()) 3380176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::Emit; 3381176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3382176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalDecl AliasDecl; 3383176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) { 3384176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AliasDecl = GlobalDecl(DD, Dtor_Complete); 3385176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else { 3386176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const auto *CD = cast<CXXConstructorDecl>(MD); 3387176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AliasDecl = GlobalDecl(CD, Ctor_Complete); 3388176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3389176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl); 3390176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3391176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) 3392176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::RAUW; 3393176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3394176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Should we allow available_externally aliases? 3395176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!llvm::GlobalAlias::isValidLinkage(Linkage)) 3396176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::RAUW; 3397176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3398176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (llvm::GlobalValue::isWeakForLinker(Linkage)) { 3399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Only ELF supports COMDATs with arbitrary names (C5/D5). 3400176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGM.getTarget().getTriple().isOSBinFormatELF()) 3401176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::COMDAT; 3402176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::Emit; 3403176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3404176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3405176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return StructorCodegen::Alias; 3406176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 3407176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3408176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic void emitConstructorDestructorAlias(CodeGenModule &CGM, 3409176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalDecl AliasDecl, 3410176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalDecl TargetDecl) { 3411176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl); 3412176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3413176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StringRef MangledName = CGM.getMangledName(AliasDecl); 3414176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::GlobalValue *Entry = CGM.GetGlobalValue(MangledName); 3415176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Entry && !Entry->isDeclaration()) 3416176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 3417176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3418176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto *Aliasee = cast<llvm::GlobalValue>(CGM.GetAddrOfGlobal(TargetDecl)); 3419176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3420176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Create the alias with no name. 3421a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *Alias = llvm::GlobalAlias::create(Linkage, "", Aliasee); 3422176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3423176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Switch any previous uses to the alias. 3424176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Entry) { 3425a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert(Entry->getType() == Aliasee->getType() && 3426176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "declaration exists with different type"); 3427176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Alias->takeName(Entry); 3428176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Entry->replaceAllUsesWith(Alias); 3429176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Entry->eraseFromParent(); 3430176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else { 3431176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Alias->setName(MangledName); 3432176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3433176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3434176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Finally, set up the alias with its proper name and attributes. 3435176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.setAliasAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias); 3436176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 3437176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3438176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD, 3439176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StructorType Type) { 3440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto *CD = dyn_cast<CXXConstructorDecl>(MD); 3441176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CXXDestructorDecl *DD = CD ? nullptr : cast<CXXDestructorDecl>(MD); 3442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3443176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StructorCodegen CGType = getCodegenToUse(CGM, MD); 3444176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3445176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Type == StructorType::Complete) { 3446176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalDecl CompleteDecl; 3447176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalDecl BaseDecl; 3448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CD) { 3449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CompleteDecl = GlobalDecl(CD, Ctor_Complete); 3450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines BaseDecl = GlobalDecl(CD, Ctor_Base); 3451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else { 3452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CompleteDecl = GlobalDecl(DD, Dtor_Complete); 3453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines BaseDecl = GlobalDecl(DD, Dtor_Base); 3454176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3455176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3456176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) { 3457176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines emitConstructorDestructorAlias(CGM, CompleteDecl, BaseDecl); 3458176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 3459176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3460176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3461176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGType == StructorCodegen::RAUW) { 3462176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StringRef MangledName = CGM.getMangledName(CompleteDecl); 3463a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto *Aliasee = CGM.GetAddrOfGlobal(BaseDecl); 3464176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CGM.addReplacement(MangledName, Aliasee); 3465176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 3466176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3467176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3468176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // The base destructor is equivalent to the base destructor of its 3470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // base class if there is exactly one non-virtual base class with a 3471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // non-trivial destructor, there are no fields with a non-trivial 3472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // destructor, and the body of the destructor is trivial. 3473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (DD && Type == StructorType::Base && CGType != StructorCodegen::COMDAT && 3474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines !CGM.TryEmitBaseDestructorAsAlias(DD)) 3475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 3476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Function *Fn = CGM.codegenCXXStructor(MD, Type); 3478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3479176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CGType == StructorCodegen::COMDAT) { 3480176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallString<256> Buffer; 3481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::raw_svector_ostream Out(Buffer); 3482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (DD) 3483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getMangleContext().mangleCXXDtorComdat(DD, Out); 3484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines else 3485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getMangleContext().mangleCXXCtorComdat(CD, Out); 3486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::Comdat *C = CGM.getModule().getOrInsertComdat(Out.str()); 3487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Fn->setComdat(C); 34880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } else { 34890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines CGM.maybeSetTrivialComdat(*MD, *Fn); 3490176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3491176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 34923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 34933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) { 34943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void *__cxa_begin_catch(void*); 34953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FTy = llvm::FunctionType::get( 34963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false); 34973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 34983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); 34993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 35003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getEndCatchFn(CodeGenModule &CGM) { 35023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void __cxa_end_catch(); 35033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FTy = 35043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false); 35053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch"); 35073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 35083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) { 35103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // void *__cxa_get_exception_ptr(void*); 35113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *FTy = llvm::FunctionType::get( 35123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false); 35133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr"); 35153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 35163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarnamespace { 35183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// A cleanup to call __cxa_end_catch. In many cases, the caught 35193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// exception type lets us state definitively that the thrown exception 35203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// type does not have a destructor. In particular: 35213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// - Catch-alls tell us nothing, so we have to conservatively 35223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// assume that the thrown exception might have a destructor. 35233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// - Catches by reference behave according to their base types. 35243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// - Catches of non-record types will only trigger for exceptions 35253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// of non-record types, which never have destructors. 35263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// - Catches of record types can trigger for arbitrary subclasses 35273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// of the caught type, so we have to assume the actual thrown 35283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// exception type might have a throwing destructor, even if the 35293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /// caught type's destructor is trivial or nothrow. 3530a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar struct CallEndCatch final : EHScopeStack::Cleanup { 35313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {} 35323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool MightThrow; 35333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void Emit(CodeGenFunction &CGF, Flags flags) override { 35353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!MightThrow) { 35363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM)); 35373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 35383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 35393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM)); 35413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 35423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar }; 35433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 35443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// Emits a call to __cxa_begin_catch and enters a cleanup to call 35463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// __cxa_end_catch. 35473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// 35483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// \param EndMightThrow - true if __cxa_end_catch might throw 35493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Value *CallBeginCatch(CodeGenFunction &CGF, 35503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Exn, 35513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool EndMightThrow) { 35523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::CallInst *call = 35533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn); 35543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow); 35563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return call; 35583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 35593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// A "special initializer" callback for initializing a catch 35613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// parameter during catch initialization. 35623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic void InitCatchParam(CodeGenFunction &CGF, 35633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const VarDecl &CatchParam, 3564a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address ParamAddr, 35653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SourceLocation Loc) { 35663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Load the exception from where the landing pad saved it. 35673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Exn = CGF.getExceptionFromSlot(); 35683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CanQualType CatchType = 35703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.CGM.getContext().getCanonicalType(CatchParam.getType()); 35713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType); 35723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // If we're catching by reference, we can just cast the object 35743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // pointer to the appropriate pointer. 35753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (isa<ReferenceType>(CatchType)) { 35763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType(); 35773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar bool EndCatchMightThrow = CaughtType->isRecordType(); 35783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // __cxa_begin_catch returns the adjusted object pointer. 35803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow); 35813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // We have no way to tell the personality function that we're 35833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // catching by reference, so if we're catching a pointer, 35843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // __cxa_begin_catch will actually return that pointer by value. 35853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) { 35863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar QualType PointeeType = PT->getPointeeType(); 35873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // When catching by reference, generally we should just ignore 35893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // this by-value pointer and use the exception object instead. 35903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!PointeeType->isRecordType()) { 35913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Exn points to the struct _Unwind_Exception header, which 35933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // we have to skip past in order to reach the exception data. 35943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned HeaderSize = 35953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException(); 35963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize); 35973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 35983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // However, if we're catching a pointer-to-record type that won't 35993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // work, because the personality function might have adjusted 36003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // the pointer. There's actually no way for us to fully satisfy 36013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // the language/ABI contract here: we can't use Exn because it 36023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // might have the wrong adjustment, but we can't use the by-value 36033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // pointer because it's off by a level of abstraction. 36043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 36053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // The current solution is to dump the adjusted pointer into an 36063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // alloca, which breaks language semantics (because changing the 36073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // pointer doesn't change the exception) but at least works. 36083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // The better solution would be to filter out non-exact matches 36093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // and rethrow them, but this is tricky because the rethrow 36103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // really needs to be catchable by other sites at this landing 36113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // pad. The best solution is to fix the personality function. 36123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } else { 36133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Pull the pointer for the reference type off. 36143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *PtrTy = 36153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar cast<llvm::PointerType>(LLVMCatchTy)->getElementType(); 36163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Create the temporary and write the adjusted pointer into it. 3618a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address ExnPtrTmp = 3619a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp"); 36203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); 36213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateStore(Casted, ExnPtrTmp); 36223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Bind the reference to the temporary. 3624a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar AdjustedExn = ExnPtrTmp.getPointer(); 36253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *ExnCast = 36293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); 36303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateStore(ExnCast, ParamAddr); 36313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 36323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Scalars and complexes. 36353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType); 36363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (TEK != TEK_Aggregate) { 36373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false); 36383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // If the catch type is a pointer type, __cxa_begin_catch returns 36403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // the pointer by value. 36413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (CatchType->hasPointerRepresentation()) { 36423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *CastExn = 36433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); 36443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar switch (CatchType.getQualifiers().getObjCLifetime()) { 36463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case Qualifiers::OCL_Strong: 36473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CastExn = CGF.EmitARCRetainNonBlock(CastExn); 36483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // fallthrough 36493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case Qualifiers::OCL_None: 36513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case Qualifiers::OCL_ExplicitNone: 36523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case Qualifiers::OCL_Autoreleasing: 36533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.Builder.CreateStore(CastExn, ParamAddr); 36543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 36553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case Qualifiers::OCL_Weak: 36573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitARCInitWeak(ParamAddr, CastExn); 36583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 36593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm_unreachable("bad ownership qualifier!"); 36613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Otherwise, it returns a pointer into the exception object. 36643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok 36663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); 36673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar LValue srcLV = CGF.MakeNaturalAlignAddrLValue(Cast, CatchType); 3669a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType); 36703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar switch (TEK) { 36713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case TEK_Complex: 36723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV, 36733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar /*init*/ true); 36743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 36753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case TEK_Scalar: { 36763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc); 36773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true); 36783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 36793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar case TEK_Aggregate: 36813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm_unreachable("evaluation kind filtered out!"); 36823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm_unreachable("bad evaluation kind"); 36843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 36853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(isa<RecordType>(CatchType) && "unexpected catch type!"); 3687a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar auto catchRD = CatchType->getAsCXXRecordDecl(); 3688a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CharUnits caughtExnAlignment = CGF.CGM.getClassPointerAlignment(catchRD); 36893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok 36913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 36923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Check for a copy expression. If we don't have a copy expression, 36933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // that means a trivial copy is okay. 36943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const Expr *copyExpr = CatchParam.getInit(); 36953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!copyExpr) { 36963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true); 3697a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy), 3698a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar caughtExnAlignment); 36993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType); 37003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 37013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 37023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // We have to call __cxa_get_exception_ptr to get the adjusted 37043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // pointer before copying. 37053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::CallInst *rawAdjustedExn = 37063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn); 37073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Cast that to the appropriate type. 3709a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy), 3710a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar caughtExnAlignment); 37113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // The copy expression is defined in terms of an OpaqueValueExpr. 37133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Find it and map it to the adjusted expression. 37143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction::OpaqueValueMapping 37153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr), 37163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.MakeAddrLValue(adjustedExn, CatchParam.getType())); 37173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call the copy ctor in a terminate scope. 37193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EHStack.pushTerminate(); 37203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Perform the copy construction. 37223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitAggExpr(copyExpr, 3723a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar AggValueSlot::forAddr(ParamAddr, Qualifiers(), 37243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar AggValueSlot::IsNotDestructed, 37253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar AggValueSlot::DoesNotNeedGCBarriers, 37263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar AggValueSlot::IsNotAliased)); 37273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Leave the terminate scope. 37293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EHStack.popTerminate(); 37303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Undo the opaque value mapping. 37323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar opaque.pop(); 37333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Finally we can call __cxa_begin_catch. 37353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CallBeginCatch(CGF, Exn, true); 37363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 37373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// Begins a catch statement by initializing the catch variable and 37393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// calling __cxa_begin_catch. 37403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarvoid ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF, 37413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const CXXCatchStmt *S) { 37423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // We have to be very careful with the ordering of cleanups here: 37433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // C++ [except.throw]p4: 37443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // The destruction [of the exception temporary] occurs 37453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // immediately after the destruction of the object declared in 37463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // the exception-declaration in the handler. 37473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 37483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // So the precise ordering is: 37493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 1. Construct catch variable. 37503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 2. __cxa_begin_catch 37513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 3. Enter __cxa_end_catch cleanup 37523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 4. Enter dtor cleanup 37533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 37543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // We do this by using a slightly abnormal initialization process. 37553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Delegation sequence: 37563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - ExitCXXTryStmt opens a RunCleanupsScope 37573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - EmitAutoVarAlloca creates the variable and debug info 37583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - InitCatchParam initializes the variable from the exception 37593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - CallBeginCatch calls __cxa_begin_catch 37603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - CallBeginCatch enters the __cxa_end_catch cleanup 37613ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - EmitAutoVarCleanups enters the variable destructor cleanup 37623ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - EmitCXXTryStmt emits the code for the catch body 37633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // - EmitCXXTryStmt close the RunCleanupsScope 37643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar VarDecl *CatchParam = S->getExceptionDecl(); 37663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!CatchParam) { 37673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Exn = CGF.getExceptionFromSlot(); 37683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CallBeginCatch(CGF, Exn, true); 37693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return; 37703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 37713ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37723ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Emit the local. 37733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam); 37743ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getLocStart()); 37753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGF.EmitAutoVarCleanups(var); 37763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 37773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// Get or define the following function: 37793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// void @__clang_call_terminate(i8* %exn) nounwind noreturn 37803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar/// This code is used only in C++. 37813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarstatic llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) { 37823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType *fnTy = 37833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false); 37843ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Constant *fnRef = 37853ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CGM.CreateRuntimeFunction(fnTy, "__clang_call_terminate"); 37863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Function *fn = dyn_cast<llvm::Function>(fnRef); 37883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (fn && fn->empty()) { 37893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->setDoesNotThrow(); 37903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->setDoesNotReturn(); 37913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // What we really want is to massively penalize inlining without 37933ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // forbidding it completely. The difference between that and 37943ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // 'noinline' is negligible. 37953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->addFnAttr(llvm::Attribute::NoInline); 37963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 37973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Allow this function to be shared across translation units, but 37983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // we don't want it to turn into an exported symbol. 37993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->setLinkage(llvm::Function::LinkOnceODRLinkage); 38003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->setVisibility(llvm::Function::HiddenVisibility); 38013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (CGM.supportsCOMDAT()) 38023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar fn->setComdat(CGM.getModule().getOrInsertComdat(fn->getName())); 38033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Set up the function. 38053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::BasicBlock *entry = 38063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn); 3807a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CGBuilderTy builder(CGM, entry); 38083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Pull the exception pointer out of the parameter list. 38103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *exn = &*fn->arg_begin(); 38113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call __cxa_begin_catch(exn). 38133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn); 38143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar catchCall->setDoesNotThrow(); 38153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar catchCall->setCallingConv(CGM.getRuntimeCC()); 38163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // Call std::terminate(). 3818a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::CallInst *termCall = builder.CreateCall(CGM.getTerminateFn()); 38193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar termCall->setDoesNotThrow(); 38203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar termCall->setDoesNotReturn(); 38213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar termCall->setCallingConv(CGM.getRuntimeCC()); 38223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // std::terminate cannot return. 38243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar builder.CreateUnreachable(); 38253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 38263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return fnRef; 38283ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 38293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 38303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarllvm::CallInst * 38313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF, 38323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::Value *Exn) { 38333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar // In C++, we want to call __cxa_begin_catch() before terminating. 38343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (Exn) { 38353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(CGF.CGM.getLangOpts().CPlusPlus); 38363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGF.EmitNounwindRuntimeCall(getClangCallTerminateFn(CGF.CGM), Exn); 38373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 38383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn()); 38393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar} 3840