15b955920c1d8f2cd35aae3c85b656578286a8bc1Anders Carlsson//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===// 25d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 35d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// The LLVM Compiler Infrastructure 45d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 55d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is distributed under the University of Illinois Open Source 65d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// License. See LICENSE.TXT for details. 75d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 85d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===// 95d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 105d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This contains code dealing with C++ code generation of classes 115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 125d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===// 135d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman#include "CGBlocks.h" 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "CGCXXABI.h" 16d67ef0eed463b43980f04a444155f423114be34bDevang Patel#include "CGDebugInfo.h" 1756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#include "CGRecordLayout.h" 185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 192f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 20d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali#include "clang/AST/DeclTemplate.h" 217e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "clang/AST/EvaluatedExprVisitor.h" 225d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "clang/AST/StmtCXX.h" 2456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#include "clang/Basic/TargetBuiltins.h" 258b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/CodeGen/CGFunctionInfo.h" 263ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include "clang/Frontend/CodeGenOptions.h" 272f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 285d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 295d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 305d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 3155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyckstatic CharUnits 3234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, 3334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *DerivedClass, 34f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start, 35f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator End) { 3655c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = CharUnits::Zero(); 3734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *RD = DerivedClass; 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 40f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXBaseSpecifier *Base = *I; 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson assert(!Base->isVirtual() && "Should not see virtual bases here!"); 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the layout. 4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *BaseDecl = 4834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Add the offset. 5155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RD = BaseDecl; 5434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 5534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5655c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return Offset; 5734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 585d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 5984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 60a04efdf635d35d88e65041fad007225d8c8d64a5Anders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 61f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 62f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd) { 63f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 64a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = 66f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 67f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall PathBegin, PathEnd); 6855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (Offset.isZero()) 696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 712acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 72a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 73a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 7455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 7584080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 778561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// Gets the address of a direct base class within a complete object. 78bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 79bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 80bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 81bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 82bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 838561a8666c70f924c8f0209c41b9b77bbbf90607Anders CarlssonCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 848561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 858561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Base, 868561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson bool BaseIsVirtual) { 87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 90bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 91bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 92bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 935fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck CharUnits Offset; 94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 958561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (BaseIsVirtual) 965fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getVBaseClassOffset(Base); 97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 985fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getBaseClassOffset(Base); 99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 100bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 101bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 102bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 1035fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck if (Offset.isPositive()) { 104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1055fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); 106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall } 107bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 109bff225ecf77fb891596ecb1b27196310d268365eJohn McCall return V; 110d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 111bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1129dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlssonstatic llvm::Value * 1137916c997127fe616ba255ba4cade10e5de0c8812John McCallApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ptr, 1147916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits nonVirtualOffset, 1157916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *virtualOffset) { 1167916c997127fe616ba255ba4cade10e5de0c8812John McCall // Assert that we have something to do. 1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr); 1187916c997127fe616ba255ba4cade10e5de0c8812John McCall 1197916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the offset from the static and dynamic components. 1207916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *baseOffset; 1217916c997127fe616ba255ba4cade10e5de0c8812John McCall if (!nonVirtualOffset.isZero()) { 1227916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy, 1237916c997127fe616ba255ba4cade10e5de0c8812John McCall nonVirtualOffset.getQuantity()); 1247916c997127fe616ba255ba4cade10e5de0c8812John McCall if (virtualOffset) { 1257916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 1267916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1277916c997127fe616ba255ba4cade10e5de0c8812John McCall } else { 1287916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = virtualOffset; 1297916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1309dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1319dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson // Apply the base offset. 1327916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); 1337916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); 1347916c997127fe616ba255ba4cade10e5de0c8812John McCall return ptr; 1359dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson} 1369dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1375d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 13834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 1398561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 140f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 141f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 14234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson bool NullCheckValue) { 143f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 145f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start = PathBegin; 1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const CXXRecordDecl *VBase = nullptr; 1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1487916c997127fe616ba255ba4cade10e5de0c8812John McCall // Sema has done some convenient canonicalization here: if the 1497916c997127fe616ba255ba4cade10e5de0c8812John McCall // access path involved any virtual steps, the conversion path will 1507916c997127fe616ba255ba4cade10e5de0c8812John McCall // *start* with a step down to the correct virtual base subobject, 1517916c997127fe616ba255ba4cade10e5de0c8812John McCall // and hence will not require any further steps. 15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if ((*Start)->isVirtual()) { 15334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VBase = 15434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 15534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson ++Start; 15634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 1577916c997127fe616ba255ba4cade10e5de0c8812John McCall 1587916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the static offset of the ultimate destination within its 1597916c997127fe616ba255ba4cade10e5de0c8812John McCall // allocating subobject (the virtual base, if there is one, or else 1607916c997127fe616ba255ba4cade10e5de0c8812John McCall // the "complete" object that we see). 16155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits NonVirtualOffset = 1628561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 163f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall Start, PathEnd); 16434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1657916c997127fe616ba255ba4cade10e5de0c8812John McCall // If there's a virtual step, we can sometimes "devirtualize" it. 1667916c997127fe616ba255ba4cade10e5de0c8812John McCall // For now, that's limited to when the derived type is final. 1677916c997127fe616ba255ba4cade10e5de0c8812John McCall // TODO: "devirtualize" this for accesses to known-complete objects. 1687916c997127fe616ba255ba4cade10e5de0c8812John McCall if (VBase && Derived->hasAttr<FinalAttr>()) { 1697916c997127fe616ba255ba4cade10e5de0c8812John McCall const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 1707916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 1717916c997127fe616ba255ba4cade10e5de0c8812John McCall NonVirtualOffset += vBaseOffset; 1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VBase = nullptr; // we no longer have a virtual step 1737916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1747916c997127fe616ba255ba4cade10e5de0c8812John McCall 17534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the base pointer type. 1762acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtrTy = 177f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ConvertType((PathEnd[-1])->getType())->getPointerTo(); 1787916c997127fe616ba255ba4cade10e5de0c8812John McCall 1797916c997127fe616ba255ba4cade10e5de0c8812John McCall // If the static offset is zero and we don't have a virtual step, 1807916c997127fe616ba255ba4cade10e5de0c8812John McCall // just do a bitcast; null checks are unnecessary. 18155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (NonVirtualOffset.isZero() && !VBase) { 18234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *origBB = nullptr; 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *endBB = nullptr; 1877916c997127fe616ba255ba4cade10e5de0c8812John McCall 1887916c997127fe616ba255ba4cade10e5de0c8812John McCall // Skip over the offset (and the vtable load) if we're supposed to 1897916c997127fe616ba255ba4cade10e5de0c8812John McCall // null-check the pointer. 19034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 1917916c997127fe616ba255ba4cade10e5de0c8812John McCall origBB = Builder.GetInsertBlock(); 1927916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 1937916c997127fe616ba255ba4cade10e5de0c8812John McCall endBB = createBasicBlock("cast.end"); 19434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1957916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *isNull = Builder.CreateIsNull(Value); 1967916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateCondBr(isNull, endBB, notNullBB); 1977916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(notNullBB); 19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 19934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2007916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the virtual offset. 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *VirtualOffset = nullptr; 202336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (VBase) { 203b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VirtualOffset = 204b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); 205336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } 20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2077916c997127fe616ba255ba4cade10e5de0c8812John McCall // Apply both offsets. 20855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 2099a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset, 21034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VirtualOffset); 21134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2127916c997127fe616ba255ba4cade10e5de0c8812John McCall // Cast to the destination type. 21334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 2147916c997127fe616ba255ba4cade10e5de0c8812John McCall 2157916c997127fe616ba255ba4cade10e5de0c8812John McCall // Build a phi if we needed a null check. 21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 2177916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 2187916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateBr(endBB); 2197916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(endBB); 22034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2217916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); 2227916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(Value, notNullBB); 2237916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); 22434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = PHI; 22534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 22634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Value; 22834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 22934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 23034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonllvm::Value * 231a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 2328561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 233f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 234f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 236f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 237a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 2398561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 2402acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 241c764830bdb6de82baed068889096bd3e52d4cbdaRichard Smith 242a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 243f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 244a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 245a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 246a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 247a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 248a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 2496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *CastNull = nullptr; 2516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *CastNotNull = nullptr; 2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *CastEnd = nullptr; 2536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 259b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 261a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 262a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 263a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 265c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateBitCast(Value, Int8PtrTy); 266c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateGEP(Value, Builder.CreateNeg(NonVirtualOffset), 267c5685438df6105052b02c9e02f01c34489606308Eli Friedman "sub.ptr"); 268a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 269a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 270a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 274a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 277a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 278bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 279a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 280a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 28132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 282a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 28332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2845d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 285a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2865d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 2871d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2881d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanovllvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 2891d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool ForVirtualBase, 2901d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating) { 291e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (!CGM.getCXXABI().NeedsVTTParameter(GD)) { 292c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 2936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 294c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 295c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 296f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent(); 297c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 299c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 300c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 3013b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall uint64_t SubVTTIndex; 3023b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor if (Delegating) { 304378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If this is a delegating constructor call, just load the VTT. 3051d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov return LoadCXXVTT(); 306378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor } else if (RD == Base) { 307378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If the record matches the base, this is the complete ctor/dtor 308378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // variant calling the base variant in a class with virtual bases. 309e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) && 3103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "doing no-op VTT offset in base dtor/ctor?"); 311314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson assert(!ForVirtualBase && "Can't have same class as virtual base!"); 3123b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall SubVTTIndex = 0; 3133b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } else { 3141d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 3154230d529a8797bbeef2328b60abeae333f7e143fKen Dyck CharUnits BaseOffset = ForVirtualBase ? 3164230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getVBaseClassOffset(Base) : 3174230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getBaseClassOffset(Base); 318c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 319c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson SubVTTIndex = 3201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 3213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 3223b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 323c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 324e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 325c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 3261d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = LoadCXXVTT(); 3271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 328c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 329c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 3301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = CGM.getVTables().GetAddrOfVTT(RD); 3311d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 332c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 333c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 334c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 335c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 336c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 337182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 33850da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the destructor for a direct base class. 3391f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallBaseDtor : EHScopeStack::Cleanup { 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *BaseClass; 34150da2cadcc6da86abff6772de65280ace2cabc94John McCall bool BaseIsVirtual; 34250da2cadcc6da86abff6772de65280ace2cabc94John McCall CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 34350da2cadcc6da86abff6772de65280ace2cabc94John McCall : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 344182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 34650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *DerivedClass = 34750da2cadcc6da86abff6772de65280ace2cabc94John McCall cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 34850da2cadcc6da86abff6772de65280ace2cabc94John McCall 34950da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *D = BaseClass->getDestructor(); 35050da2cadcc6da86abff6772de65280ace2cabc94John McCall llvm::Value *Addr = 35150da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 35250da2cadcc6da86abff6772de65280ace2cabc94John McCall DerivedClass, BaseClass, 35350da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseIsVirtual); 354378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 355378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 356182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 357182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// A visitor which checks whether an initializer uses 'this' in a 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// way which requires the vtable to be properly set. 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool UsesThis; 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 3677e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3687e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Black-list all explicit and implicit references to 'this'. 3697e1dff7a68a4d00e71debafa7f5c259473091746John McCall // 3707e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Do we need to worry about external references to 'this' derived 3717e1dff7a68a4d00e71debafa7f5c259473091746John McCall // from arbitrary code? If so, then anything which runs arbitrary 3727e1dff7a68a4d00e71debafa7f5c259473091746John McCall // external code might potentially access the vtable. 3737e1dff7a68a4d00e71debafa7f5c259473091746John McCall void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 3747e1dff7a68a4d00e71debafa7f5c259473091746John McCall }; 3757e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3767e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3777e1dff7a68a4d00e71debafa7f5c259473091746John McCallstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 3787e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker Checker(C); 3797e1dff7a68a4d00e71debafa7f5c259473091746John McCall Checker.Visit(const_cast<Expr*>(Init)); 3807e1dff7a68a4d00e71debafa7f5c259473091746John McCall return Checker.UsesThis; 381182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 382182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 385cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *BaseInit, 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 39680638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson bool isBaseVirtual = BaseInit->isBaseVirtual(); 397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 4027e1dff7a68a4d00e71debafa7f5c259473091746John McCall // If the initializer for the base (other than the constructor 4037e1dff7a68a4d00e71debafa7f5c259473091746John McCall // itself) accesses 'this' in any way, we need to initialize the 4047e1dff7a68a4d00e71debafa7f5c259473091746John McCall // vtables. 4057e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 4067e1dff7a68a4d00e71debafa7f5c259473091746John McCall CGF.InitializeVTablePointers(ClassDecl); 4077e1dff7a68a4d00e71debafa7f5c259473091746John McCall 408bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 409bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 4108561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson llvm::Value *V = 4118561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 41250da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseClassDecl, 41350da2cadcc6da86abff6772de65280ace2cabc94John McCall isBaseVirtual); 414d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = CGF.getContext().getTypeAlignInChars(BaseType); 4157c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot AggSlot = 416f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(V, Alignment, Qualifiers(), 4177c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 418410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 419649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 420558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 421558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 422594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 4234e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGF.CGM.getLangOpts().Exceptions && 424c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson !BaseClassDecl->hasTrivialDestructor()) 4251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 4261f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall isBaseVirtual); 427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 428607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregorstatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 430fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue LHS, 4310bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Expr *Init, 432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar, 433fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType T, 4340bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes, 435fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned Index) { 4360bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Index == ArrayIndexes.size()) { 437f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman LValue LV = LHS; 4387c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 4397c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith if (ArrayIndexVar) { 4407c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith // If we have an array index variable, load it and use it as an offset. 4417c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith // Then, increment the value. 4427c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith llvm::Value *Dest = LHS.getAddress(); 4437c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 4447c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 4457c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 4467c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 4477c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith CGF.Builder.CreateStore(Next, ArrayIndexVar); 4487c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 4497c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith // Update the LValue. 4507c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith LV.setAddress(Dest); 4517c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith CharUnits Align = CGF.getContext().getTypeAlignInChars(T); 4527c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith LV.setAlignment(std::min(Align, LV.getAlignment())); 453fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 454558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 4557c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith switch (CGF.getEvaluationKind(T)) { 4567c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith case TEK_Scalar: 4576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGF.EmitScalarInit(Init, /*decl*/ nullptr, LV, false); 4587c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith break; 4597c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith case TEK_Complex: 4607c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); 4617c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith break; 4627c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith case TEK_Aggregate: { 4637c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith AggValueSlot Slot = 4647c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith AggValueSlot::forLValue(LV, 4657c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith AggValueSlot::IsDestructed, 4667c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith AggValueSlot::DoesNotNeedGCBarriers, 4677c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith AggValueSlot::IsNotAliased); 4687c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 4697c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith CGF.EmitAggExpr(Init, Slot); 4707c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith break; 4717c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith } 4727c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith } 473924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 474fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 475fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 4767c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 477fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(Array && "Array initialization without the array type?"); 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IndexVar 4800bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]); 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(IndexVar && "Array index variable not loaded"); 482fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Initialize this index variable to zero. 484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value* Zero 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = llvm::Constant::getNullValue( 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.ConvertType(CGF.getContext().getSizeType())); 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, IndexVar); 488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 489fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Start the loop with a block that tests the condition. 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(CondBlock); 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Generate: if (loop-index < number-of-elements) fall to the loop body, 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // otherwise, go to the block after the for-loop. 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor uint64_t NumElements = Array->getSize().getZExtValue(); 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 500985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::Value *NumElementsPtr = 501985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::ConstantInt::get(Counter->getType(), NumElements); 502fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 503fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "isless"); 504fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 505fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If the condition is true, execute the body. 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ForBody); 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 5107c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 5117c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith // Inside the loop body recurse to emit the inner loop or, eventually, the 5127c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith // constructor call. 5137c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, 5147c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith Array->getElementType(), ArrayIndexes, Index + 1); 5157c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith 516fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ContinueBlock); 517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 518fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the increment of the loop counter. 519fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 520fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Counter = CGF.Builder.CreateLoad(IndexVar); 521fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 522fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(NextVal, IndexVar); 523fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 524fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Finally, branch back up to the condition for the next iteration. 525fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBranch(CondBlock); 526fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 527fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the fall-through block. 528fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(AfterFor, true); 529fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor} 530182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 531607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 532607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 533cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 534fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const CXXConstructorDecl *Constructor, 535fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 53600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet assert(MemberInit->isAnyMemberInitializer() && 537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 5387a614d8380297fcd2bc23986241905d97222948cRichard Smith assert(MemberInit->getInit() && "Must have initializer!"); 539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 54100eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldDecl *Field = MemberInit->getAnyMember(); 5420bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 544607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 545377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 546859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 547377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman 54800eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (MemberInit->isIndirectMemberInitializer()) { 549859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // If we are initializing an anonymous union field, drill down to 550859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // the field. 551859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : IndirectField->chain()) 553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I)); 55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 555a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall } else { 556859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 558607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 5590bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Special case: if we are in a copy or move constructor, and we are copying 5600bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // an array of PODs or classes with trivial copy constructors, ignore the 5610bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // AST and perform the copy we know is equivalent. 5620bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // FIXME: This is hacky at best... if we had a bit more explicit information 5630bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // in the AST, we could generalize it more easily. 5640bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman const ConstantArrayType *Array 5650bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.getContext().getAsConstantArrayType(FieldType); 566a7b879723d3989d85b9492fd8218e7d745367fe3Jordan Rose if (Array && Constructor->isDefaulted() && 5670bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Constructor->isCopyOrMoveConstructor()) { 5680bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 569e9385363069388d8e3536052a138f17332e00620Richard Smith CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (BaseElementTy.isPODType(CGF.getContext()) || 571e9385363069388d8e3536052a138f17332e00620Richard Smith (CE && CE->getConstructor()->isTrivial())) { 572e9385363069388d8e3536052a138f17332e00620Richard Smith // Find the source pointer. We know it's the last argument because 573e9385363069388d8e3536052a138f17332e00620Richard Smith // we know we're in an implicit copy constructor. 5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned SrcArgIndex = Args.size() - 1; 5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman llvm::Value *SrcPtr 5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 577377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 578377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 5790bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5800bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Copy the aggregate. 5810bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 582649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier LHS.isVolatileQualified()); 5830bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman return; 5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5850bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5860bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5870bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes; 5880bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (MemberInit->getNumArrayIndices()) 5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes = MemberInit->getArrayIndexes(); 590b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes); 5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman} 5920bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 593b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid CodeGenFunction::EmitInitializerForField(FieldDecl *Field, 594b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LValue LHS, Expr *Init, 595b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayRef<VarDecl *> ArrayIndexes) { 5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 5979d232c884ea9872d6555df0fd7359699819bc1f1John McCall switch (getEvaluationKind(FieldType)) { 5989d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Scalar: 599f85e193739c953358c865005855253af4f68a497John McCall if (LHS.isSimple()) { 600b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitExprAsInit(Init, Field, LHS, false); 601f85e193739c953358c865005855253af4f68a497John McCall } else { 602b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman RValue RHS = RValue::get(EmitScalarExpr(Init)); 603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitStoreThroughLValue(RHS, LHS); 604f85e193739c953358c865005855253af4f68a497John McCall } 6059d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 6069d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Complex: 6079d232c884ea9872d6555df0fd7359699819bc1f1John McCall EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); 6089d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 6099d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Aggregate: { 6106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *ArrayIndexVar = nullptr; 6110bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (ArrayIndexes.size()) { 612b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 613fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 614fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // The LHS is a pointer to the first object we'll be constructing, as 615fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // a flat array. 616b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman QualType BaseElementTy = getContext().getBaseElementType(FieldType); 617b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *BasePtr = ConvertType(BaseElementTy); 618fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr = llvm::PointerType::getUnqual(BasePtr); 619b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), 620b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman BasePtr); 621b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy); 622fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 623fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Create an array index that will be used to walk over all of the 624fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // objects we're constructing. 625b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index"); 626fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 627b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman Builder.CreateStore(Zero, ArrayIndexVar); 628fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 629fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 630fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the block variables for the array indices, if any. 6310bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I) 632b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAutoVarDecl(*ArrayIndexes[I]); 633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 634fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 635b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, 6360bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes, 0); 637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 6389d232c884ea9872d6555df0fd7359699819bc1f1John McCall } 639074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall 640074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // Ensure that we destroy this object if an exception is thrown 641074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // later in the constructor. 642074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 643074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall if (needsEHCleanup(dtorKind)) 644074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 645607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 646607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 647c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Checks whether the given constructor is a valid subject for the 648c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// complete-to-base constructor delegation optimization, i.e. 649c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// emitting the complete constructor as a simple call to the base 650c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// constructor. 651c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallstatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 652c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 653c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Currently we disable the optimization for classes with virtual 654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // bases because (1) the addresses of parameter variables need to be 655c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // consistent across all initializers but (2) the delegate function 656c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // call necessarily creates a second copy of the parameter variable. 657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // 658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // The limiting example (purely theoretical AFAIK): 659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct A { A(int &c) { c++; } }; 660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct B : virtual A { 661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // B(int count) : A(count) { printf("%d\n", count); } 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // }; 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // ...although even this example could in principle be emitted as a 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation since the address of the parameter doesn't escape. 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getParent()->getNumVBases()) { 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list trivial vbase initializers. This case wouldn't 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // be subject to the restrictions below. 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list cases where: 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - there are no non-reference parameters to the constructor 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't access any non-reference parameters 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't take the address of non-reference 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // parameters 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - etc. 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // If we ever add any of the above cases, remember that: 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - function-try-blocks will always blacklist this optimization 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - we need to perform the constructor prologue and cleanup in 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // EmitConstructorBody. 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // We also disable the optimization for variadic functions because 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // it's impossible to "re-pass" varargs. 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 688059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt // FIXME: Decide if we can do a delegation of a delegating constructor. 689059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (Ctor->isDelegatingConstructor()) 690059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return false; 691059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 692c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return true; 693c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 694c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 6959fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitConstructorBody - Emits the body of the current constructor. 6969fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 6979fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 6989fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXCtorType CtorType = CurGD.getCtorType(); 6999fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert((CGM.getTarget().getCXXABI().hasConstructorVariants() || 701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CtorType == Ctor_Complete) && 702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "can only generate complete ctor for this ABI"); 703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Before we go any further, try the complete->base constructor 705c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation optimization. 7068560791791e7b33249feb0ffafeca427076b37b4Timur Iskhodzhanov if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 70764aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall CGM.getTarget().getCXXABI().hasConstructorVariants()) { 708d67ef0eed463b43980f04a444155f423114be34bDevang Patel if (CGDebugInfo *DI = getDebugInfo()) 70973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, Ctor->getLocEnd()); 7104ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getLocEnd()); 711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return; 712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 713c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Ctor->getBody(); 7159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Enter the function-try-block before the constructor prologue if 717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // applicable. 718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 72059a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RegionCounter Cnt = getPGORegionCounter(Body); 723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Cnt.beginRegion(Builder); 724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 7257c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith RunCleanupsScope RunCleanups(*this); 7269fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 72756ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // TODO: in restricted cases, we can emit the vbase initializers of 72856ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // a complete ctor and then delegate to the base ctor. 72956ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall 730c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Emit the constructor prologue, i.e. the base and member 731c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // initializers. 732fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitCtorPrologue(Ctor, CtorType, Args); 7339fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7349fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit the body of the statement. 735c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 7369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall else if (Body) 7389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(Body); 7399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit any cleanup blocks associated with the member or base 7419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // initializers, which includes (along the exceptional path) the 7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // destructors for those members and bases that were fully 7439fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // constructed. 7447c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith RunCleanups.ForceCleanup(); 7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 746c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 74759a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7489fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 7499fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 75056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesnamespace { 75162a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky /// RAII object to indicate that codegen is copying the value representation 75262a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky /// instead of the object representation. Useful when copying a struct or 75362a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky /// class which has uninitialized members and we're only performing 75462a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky /// lvalue-to-rvalue conversion on the object but not its members. 75562a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky class CopyingValueRepresentation { 75662a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky public: 75762a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky explicit CopyingValueRepresentation(CodeGenFunction &CGF) 75862a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky : CGF(CGF), SO(*CGF.SanOpts), OldSanOpts(CGF.SanOpts) { 75962a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky SO.Bool = false; 76062a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky SO.Enum = false; 76162a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CGF.SanOpts = &SO; 76262a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky } 76362a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky ~CopyingValueRepresentation() { 76462a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CGF.SanOpts = OldSanOpts; 76562a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky } 76662a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky private: 76762a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CodeGenFunction &CGF; 76862a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky SanitizerOptions SO; 76962a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky const SanitizerOptions *OldSanOpts; 77062a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky }; 77162a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky} 77262a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky 77362a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewyckynamespace { 77456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class FieldMemcpyizer { 77556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 77656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 77756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec) 77856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 77956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 7806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0), 7816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LastFieldOffset(0), LastAddedFieldIndex(0) {} 78256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 78356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static bool isMemcpyableField(FieldDecl *F) { 78456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Qualifiers Qual = F->getType().getQualifiers(); 78556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 78656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 78756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 78856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 78956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 79056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemcpyableField(FieldDecl *F) { 7916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FirstField) 79256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addInitialField(F); 79356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames else 79456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addNextField(F); 79556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 79656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 79756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits getMemcpySize() const { 79856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastFieldSize = 79956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->isBitField() ? 80056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->getBitWidthValue(CGF.getContext()) : 80156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getTypeSize(LastField->getType()); 80256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t MemcpySizeBits = 80356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset + LastFieldSize - FirstFieldOffset + 80456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getCharWidth() - 1; 80556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = 80656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().toCharUnitsFromBits(MemcpySizeBits); 80756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return MemcpySize; 80856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 80956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 81056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpy() { 81156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Give the subclass a chance to bail out if it feels the memcpy isn't 81256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // worth it (e.g. Hasn't aggregated enough data). 8136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FirstField) { 81456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 81556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 81656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 8175e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames CharUnits Alignment; 81856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 81956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField->isBitField()) { 82056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGRecordLayout &RL = 82156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 82256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 8235e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment); 8245e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } else { 82523742cd8c6416c6c777904fb837b2021361c4f38Lang Hames Alignment = CGF.getContext().getDeclAlign(FirstField); 8265e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } 8275e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 8285e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames assert((CGF.getContext().toCharUnitsFromBits(FirstFieldOffset) % 8295e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment) == 0 && "Bad field alignment."); 83056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = getMemcpySize(); 83256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 83356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 83456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue DestLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 83556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 83656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 83756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 83856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 83956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddr() : Dest.getAddress(), 84156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Src.isBitField() ? Src.getBitFieldAddr() : Src.getAddress(), 84256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemcpySize, Alignment); 84356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 84456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 84556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void reset() { 8476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FirstField = nullptr; 84856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 84956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 85056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames protected: 85156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CodeGenFunction &CGF; 85256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXRecordDecl *ClassDecl; 85356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 85456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 85556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 85656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpyIR(llvm::Value *DestPtr, llvm::Value *SrcPtr, 85756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits Size, CharUnits Alignment) { 85856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); 85956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *DBP = 86056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), DPT->getAddressSpace()); 86156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DestPtr = CGF.Builder.CreateBitCast(DestPtr, DBP); 86256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 86356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); 86456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *SBP = 86556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), SPT->getAddressSpace()); 86656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, SBP); 86756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 86856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity(), 86956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Alignment.getQuantity()); 87056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 87156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 87256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addInitialField(FieldDecl *F) { 87356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 87456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 87556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 87656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FirstFieldOffset; 87756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 87856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 87956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 88056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 88156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addNextField(FieldDecl *F) { 882402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall // For the most part, the following invariant will hold: 883402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall // F->getFieldIndex() == LastAddedFieldIndex + 1 884402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall // The one exception is that Sema won't add a copy-initializer for an 885402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall // unnamed bitfield, which will show up here as a gap in the sequence. 886402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 && 887402cd22c598b39a272f2b31b52b19d4830954e1aJohn McCall "Cannot aggregate fields out of order."); 88856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 88956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 89056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // The 'first' and 'last' fields are chosen by offset, rather than field 89156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // index. This allows the code to support bitfields, as well as regular 89256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // fields. 89356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 89456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FOffset < FirstFieldOffset) { 89556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 89656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = FOffset; 89756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (FOffset > LastFieldOffset) { 89856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 89956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FOffset; 90056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 90156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 90256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 90356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec; 90456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const ASTRecordLayout &RecLayout; 90556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *FirstField; 90656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *LastField; 90756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FirstFieldOffset, LastFieldOffset; 90856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastAddedFieldIndex; 90956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 91056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class ConstructorMemcpyizer : public FieldMemcpyizer { 91256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 91356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// Get source argument for copy constructor. Returns null if not a copy 91556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// constructor. 91656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD, 91756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) { 918a7b879723d3989d85b9492fd8218e7d745367fe3Jordan Rose if (CD->isCopyOrMoveConstructor() && CD->isDefaulted()) 91956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Args[Args.size() - 1]; 9206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 92156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 92256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 92356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns true if a CXXCtorInitializer represents a member initialization 92456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // that can be rolled into a memcpy. 92556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 92656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!MemcpyableCtor) 92756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 92856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = MemberInit->getMember(); 9296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Field && "No field for member init."); 93056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = Field->getType(); 93156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 93256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 93356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on non-POD, not-trivially-constructable members. 93456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(CE && CE->getConstructor()->isTrivial()) && 93556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 93656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldType->isReferenceType())) 93756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 93856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 93956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on volatile fields. 94056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!isMemcpyableField(Field)) 94156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 94256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 94356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Otherwise we're good. 94456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 94556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 94656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 94756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 94856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 94956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 95056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)), 95156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl(CD), 952a7b879723d3989d85b9492fd8218e7d745367fe3Jordan Rose MemcpyableCtor(CD->isDefaulted() && 95356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CD->isCopyOrMoveConstructor() && 95456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getLangOpts().getGC() == LangOptions::NonGC), 95556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Args(Args) { } 95656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 95756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemberInitializer(CXXCtorInitializer *MemberInit) { 95856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (isMemberInitMemcpyable(MemberInit)) { 95956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.push_back(MemberInit); 96056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(MemberInit->getMember()); 96156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 96256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 96356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 96456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl, Args); 96556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 96656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 96756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 96856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedInits() { 96956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedInits.size() <= 1) { 97056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // This memcpy is too small to be worthwhile. Fall back on default 97156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // codegen. 97262a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky if (!AggregatedInits.empty()) { 97362a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CopyingValueRepresentation CVR(CGF); 97456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 97562a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky AggregatedInits[0], ConstructorDecl, Args); 97656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 97856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 97956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 98056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames pushEHDestructors(); 98256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 98356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.clear(); 98456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 98556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void pushEHDestructors() { 98756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 98856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 98956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 99056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 99156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 99256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = AggregatedInits[i]->getMember()->getType(); 99356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 99456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (CGF.needsEHCleanup(dtorKind)) 99556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 99656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 99756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 99856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 99956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 100056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 100156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 100256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 100356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 100456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXConstructorDecl *ConstructorDecl; 100556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool MemcpyableCtor; 100656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args; 100756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 100856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 100956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 101056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class AssignmentMemcpyizer : public FieldMemcpyizer { 101156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 101256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 101356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns the memcpyable field copied by the given statement, if one 101462a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky // exists. Otherwise returns null. 101562a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky FieldDecl *getMemcpyableField(Stmt *S) { 101656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!AssignmentsMemcpyable) 10176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 101856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 101956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Recognise trivial assignments. 102056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BO->getOpcode() != BO_Assign) 10216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 102256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 102356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 10246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 102556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 102656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 10276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 102856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Stmt *RHS = BO->getRHS(); 102956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 103056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RHS = EC->getSubExpr(); 103156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!RHS) 10326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 103356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS); 103456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field) 10356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 103656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 103756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 103856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 103956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(MD && (MD->isCopyAssignmentOperator() || 104056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isMoveAssignmentOperator()) && 104156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isTrivial())) 10426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 104356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 104456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!IOA) 10456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 104656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 104756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 10486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 104956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 105056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 10516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 105256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 105356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 105456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 105556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 10566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 105756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *DstPtr = CE->getArg(0); 105856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 105956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DstPtr = DC->getSubExpr(); 106056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 106156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!DUO || DUO->getOpcode() != UO_AddrOf) 10626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 106356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 106456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 10656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 106656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 106756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 10686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 106956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *SrcPtr = CE->getArg(1); 107056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 107156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = SC->getSubExpr(); 107256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 107356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!SUO || SUO->getOpcode() != UO_AddrOf) 10746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 107556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 107656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 10776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 107856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 107956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 10816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 108256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool AssignmentsMemcpyable; 108556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<Stmt*, 16> AggregatedStmts; 108656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 108856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 109056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 109156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 109256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 109356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(Args.size() == 2); 109456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 109556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 109656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAssignment(Stmt *S) { 109756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *F = getMemcpyableField(S); 109856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (F) { 109956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(F); 110056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.push_back(S); 110156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 110256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 110356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.EmitStmt(S); 110456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 110556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 110656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 110756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedStmts() { 110856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedStmts.size() <= 1) { 110962a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky if (!AggregatedStmts.empty()) { 111062a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CopyingValueRepresentation CVR(CGF); 111162a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky CGF.EmitStmt(AggregatedStmts[0]); 111262a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky } 111356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 111456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 111556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 111656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 111756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.clear(); 111856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 111956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 112056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 112156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 112256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 112356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 112456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 112556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 112656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 1127607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 1128607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 1129607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 1130fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CXXCtorType CtorType, 1131fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 1132059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (CD->isDelegatingConstructor()) 1133059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return EmitDelegatingCXXConstructorCall(CD, Args); 1134059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1135607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 1136a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 11371d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 11381d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov E = CD->init_end(); 11391d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BasicBlock *BaseCtorContinueBB = nullptr; 11411d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (ClassDecl->getNumVBases() && 11421d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov !CGM.getTarget().getCXXABI().hasConstructorVariants()) { 11431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // The ABIs that don't have constructor variants need to put a branch 11441d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // before the virtual base initialization code. 11459063302a82423cb83f002257a416741850739a70Reid Kleckner BaseCtorContinueBB = 11469063302a82423cb83f002257a416741850739a70Reid Kleckner CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl); 11471d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(BaseCtorContinueBB); 11481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Virtual base initializers first. 11511d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { 11521d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 11531d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11541d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11551d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (BaseCtorContinueBB) { 11561d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Complete object handler should continue to the remaining initializers. 11571d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Builder.CreateBr(BaseCtorContinueBB); 11581d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBlock(BaseCtorContinueBB); 11591d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11601d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Then, non-virtual base initializers. 11621d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E && (*B)->isBaseInitializer(); B++) { 11631d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(!(*B)->isBaseVirtual()); 11641d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 1165607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1166607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1167603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson InitializeVTablePointers(ClassDecl); 1168a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 11691d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // And finally, initialize class members. 1170c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith FieldConstructionScope FCS(*this, CXXThisValue); 117156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer CM(*this, CD, Args); 11721d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E; B++) { 11731d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorInitializer *Member = (*B); 11741d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(!Member->isBaseInitializer()); 11751d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(Member->isAnyMemberInitializer() && 11761d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "Delegating initializer on non-delegating constructor"); 11771d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CM.addMemberInitializer(Member); 11781d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 117956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CM.finish(); 1180607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1181607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1182adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1183adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 1184adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1185adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1186adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonHasTrivialDestructorBody(ASTContext &Context, 1187adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *BaseClassDecl, 1188adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl) 1189adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1190adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // If the destructor is trivial we don't have to check anything else. 1191adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1192adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1193adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1194adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 1195adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1196adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1197adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check fields. 1198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Field : BaseClassDecl->fields()) 1199adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1200adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1201adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1202adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check non-virtual bases. 1203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : BaseClassDecl->bases()) { 1204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I.isVirtual()) 1205adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson continue; 1206adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1207adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *NonVirtualBase = 1208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 1209adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, NonVirtualBase, 1210adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1211adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1212adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1213adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1214adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl == MostDerivedClassDecl) { 1215adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check virtual bases. 1216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : BaseClassDecl->vbases()) { 1217adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *VirtualBase = 1218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 1219adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, VirtualBase, 1220adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1221adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1222adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1223adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1224adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1225adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1226adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1227adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1228adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1229adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, 1230adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field) 1231adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1232adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 1233adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1234adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 1235adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!RT) 1236adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1237adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1238adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1239adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 1240adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1241adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1242ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// CanSkipVTablePointerInitialization - Check whether we need to initialize 1243ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// any vtable pointers before calling this destructor. 1244ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlssonstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 1245e3d6cf2149beb1c215ea6e87023c27b4f37712adAnders Carlsson const CXXDestructorDecl *Dtor) { 1246ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!Dtor->hasTrivialBody()) 1247ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return false; 1248ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1249ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson // Check the fields. 1250ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Field : ClassDecl->fields()) 1252adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1253adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1254ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1255ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return true; 1256ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson} 1257ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 12589fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitDestructorBody - Emits the body of the current destructor. 12599fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 12609fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 12619fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXDtorType DtorType = CurGD.getDtorType(); 12629fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 126350da2cadcc6da86abff6772de65280ace2cabc94John McCall // The call to operator delete in a deleting destructor happens 126450da2cadcc6da86abff6772de65280ace2cabc94John McCall // outside of the function-try-block, which means it's always 126550da2cadcc6da86abff6772de65280ace2cabc94John McCall // possible to delegate the destructor body to the complete 126650da2cadcc6da86abff6772de65280ace2cabc94John McCall // destructor. Do so. 126750da2cadcc6da86abff6772de65280ace2cabc94John McCall if (DtorType == Dtor_Deleting) { 126850da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Deleting); 126950da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 1270378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 127150da2cadcc6da86abff6772de65280ace2cabc94John McCall PopCleanupBlock(); 127250da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 127350da2cadcc6da86abff6772de65280ace2cabc94John McCall } 127450da2cadcc6da86abff6772de65280ace2cabc94John McCall 12759fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Dtor->getBody(); 12769fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 12779fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If the body is a function-try-block, enter the try before 127850da2cadcc6da86abff6772de65280ace2cabc94John McCall // anything else. 127950da2cadcc6da86abff6772de65280ace2cabc94John McCall bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 12809fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 128159a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 12829fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 128350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the epilogue cleanups. 128450da2cadcc6da86abff6772de65280ace2cabc94John McCall RunCleanupsScope DtorEpilogue(*this); 128550da2cadcc6da86abff6772de65280ace2cabc94John McCall 12869fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If this is the complete variant, just invoke the base variant; 12879fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // the epilogue will destruct the virtual bases. But we can't do 12889fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // this optimization if the body is a function-try-block, because 1289a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // we'd introduce *two* handler blocks. In the Microsoft ABI, we 1290a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // always delegate because we might not have a definition in this TU. 129150da2cadcc6da86abff6772de65280ace2cabc94John McCall switch (DtorType) { 129250da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 129350da2cadcc6da86abff6772de65280ace2cabc94John McCall 129450da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Complete: 1295a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner assert((Body || getTarget().getCXXABI().isMicrosoft()) && 1296a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner "can't emit a dtor without a body for non-Microsoft ABIs"); 1297a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 129850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for virtual bases. 129950da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Complete); 130050da2cadcc6da86abff6772de65280ace2cabc94John McCall 1301a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner if (!isTryBody) { 130250da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 1303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 130450da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 130550da2cadcc6da86abff6772de65280ace2cabc94John McCall } 130650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Fallthrough: act like we're in the base variant. 13079fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 130850da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Base: 1309a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner assert(Body); 1310a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 1311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RegionCounter Cnt = getPGORegionCounter(Body); 1312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Cnt.beginRegion(Builder); 1313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 131450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for fields and non-virtual bases. 131550da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Base); 131650da2cadcc6da86abff6772de65280ace2cabc94John McCall 131750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Initialize the vtable pointers before entering the body. 1318ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 1319ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson InitializeVTablePointers(Dtor->getParent()); 13209fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 132150da2cadcc6da86abff6772de65280ace2cabc94John McCall if (isTryBody) 132250da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 132350da2cadcc6da86abff6772de65280ace2cabc94John McCall else if (Body) 132450da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(Body); 132550da2cadcc6da86abff6772de65280ace2cabc94John McCall else { 132650da2cadcc6da86abff6772de65280ace2cabc94John McCall assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 132750da2cadcc6da86abff6772de65280ace2cabc94John McCall // nothing to do besides what's in the epilogue 132850da2cadcc6da86abff6772de65280ace2cabc94John McCall } 13295abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // -fapple-kext must inline any call to this dtor into 13305abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // the caller's body. 13317edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (getLangOpts().AppleKext) 133272390b39c545426023ec104afe8706395d732badBill Wendling CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 133350da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 13349fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } 13359fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 133650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Jump out through the epilogue cleanups. 133750da2cadcc6da86abff6772de65280ace2cabc94John McCall DtorEpilogue.ForceCleanup(); 13389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 13399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Exit the try if applicable. 13409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 134159a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 13429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 13439fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 134456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesvoid CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 134556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 134656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const Stmt *RootS = AssignOp->getBody(); 134756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(isa<CompoundStmt>(RootS) && 134856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Body of an implicit assignment operator should be compound stmt."); 134956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 135056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 135156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LexicalScope Scope(*this, RootCS->getSourceRange()); 135256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 135356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer AM(*this, AssignOp, Args); 1354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : RootCS->body()) 1355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AM.emitAssignment(I); 135656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AM.finish(); 135756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 135856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 135950da2cadcc6da86abff6772de65280ace2cabc94John McCallnamespace { 136050da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the operator delete associated with the current destructor. 13611f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallDtorDelete : EHScopeStack::Cleanup { 136250da2cadcc6da86abff6772de65280ace2cabc94John McCall CallDtorDelete() {} 136350da2cadcc6da86abff6772de65280ace2cabc94John McCall 1364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 136550da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 136650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = Dtor->getParent(); 136750da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 136850da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.getContext().getTagDeclType(ClassDecl)); 136950da2cadcc6da86abff6772de65280ace2cabc94John McCall } 137050da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 137150da2cadcc6da86abff6772de65280ace2cabc94John McCall 137259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov struct CallDtorDeleteConditional : EHScopeStack::Cleanup { 137359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldDeleteCondition; 137459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov public: 137559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 137659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov : ShouldDeleteCondition(ShouldDeleteCondition) { 13776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(ShouldDeleteCondition != nullptr); 137859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 137959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 138159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 138259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 138359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldCallDelete 138459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 138559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 138659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 138759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(callDeleteBB); 138859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 138959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXRecordDecl *ClassDecl = Dtor->getParent(); 139059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 139159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.getContext().getTagDeclType(ClassDecl)); 139259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateBr(continueBB); 139359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 139459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(continueBB); 139559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 139659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov }; 139759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 13989928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall class DestroyField : public EHScopeStack::Cleanup { 13999928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field; 1400516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne CodeGenFunction::Destroyer *destroyer; 14019928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray; 14029928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 14039928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall public: 14049928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 14059928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray) 1406516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne : field(field), destroyer(destroyer), 14079928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall useEHCleanupForArray(useEHCleanupForArray) {} 14089928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 1409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 14109928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall // Find the address of the field. 14119928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall llvm::Value *thisValue = CGF.LoadCXXThis(); 1412377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 1413377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 1414377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue LV = CGF.EmitLValueForField(ThisLV, field); 14159928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall assert(LV.isSimple()); 14169928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 14179928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 1418ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall flags.isForNormalCleanup() && useEHCleanupForArray); 141950da2cadcc6da86abff6772de65280ace2cabc94John McCall } 142050da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 142150da2cadcc6da86abff6772de65280ace2cabc94John McCall} 142250da2cadcc6da86abff6772de65280ace2cabc94John McCall 1423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Emit all code that comes at the end of class's 1424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 1425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 142650da2cadcc6da86abff6772de65280ace2cabc94John McCallvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 142750da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXDtorType DtorType) { 1428ef8225444452a1486bd721f3285301fe84643b00Stephen Hines assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) && 1429ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "Should not emit dtor epilogue for non-exported trivial dtor!"); 1430607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 143150da2cadcc6da86abff6772de65280ace2cabc94John McCall // The deleting-destructor phase just needs to call the appropriate 143250da2cadcc6da86abff6772de65280ace2cabc94John McCall // operator delete that Sema picked up. 14333b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Deleting) { 14343b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DD->getOperatorDelete() && 1435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "operator delete missing - EnterDtorCleanups"); 143659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (CXXStructorImplicitParamValue) { 143759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // If there is an implicit param to the deleting dtor, it's a boolean 143859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // telling whether we should call delete at the end of the dtor. 143959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDeleteConditional>( 144059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov NormalAndEHCleanup, CXXStructorImplicitParamValue); 144159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } else { 144259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 144359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 14443b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14453b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14463b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 144750da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = DD->getParent(); 144850da2cadcc6da86abff6772de65280ace2cabc94John McCall 1449416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith // Unions have no bases and do not call field destructors. 1450416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith if (ClassDecl->isUnion()) 1451416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith return; 1452416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith 145350da2cadcc6da86abff6772de65280ace2cabc94John McCall // The complete-destructor phase just destructs all the virtual bases. 14543b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Complete) { 145550da2cadcc6da86abff6772de65280ace2cabc94John McCall 145650da2cadcc6da86abff6772de65280ace2cabc94John McCall // We push them in the forward order so that they'll be popped in 145750da2cadcc6da86abff6772de65280ace2cabc94John McCall // the reverse order. 1458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &Base : ClassDecl->vbases()) { 14593b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall CXXRecordDecl *BaseClassDecl 14603b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 14613b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14623b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Ignore trivial destructors. 14633b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (BaseClassDecl->hasTrivialDestructor()) 14643b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall continue; 146550da2cadcc6da86abff6772de65280ace2cabc94John McCall 14661f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14671f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14681f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ true); 14693b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 147050da2cadcc6da86abff6772de65280ace2cabc94John McCall 14713b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14723b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14733b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14743b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DtorType == Dtor_Base); 147550da2cadcc6da86abff6772de65280ace2cabc94John McCall 147650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy non-virtual bases. 1477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &Base : ClassDecl->bases()) { 147850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore virtual bases. 147950da2cadcc6da86abff6772de65280ace2cabc94John McCall if (Base.isVirtual()) 148050da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 148150da2cadcc6da86abff6772de65280ace2cabc94John McCall 148250da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 148350da2cadcc6da86abff6772de65280ace2cabc94John McCall 148450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore trivial destructors. 148550da2cadcc6da86abff6772de65280ace2cabc94John McCall if (BaseClassDecl->hasTrivialDestructor()) 148650da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 14873b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14881f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14891f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14901f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ false); 149150da2cadcc6da86abff6772de65280ace2cabc94John McCall } 149250da2cadcc6da86abff6772de65280ace2cabc94John McCall 149350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy direct fields. 1494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Field : ClassDecl->fields()) { 1495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType type = Field->getType(); 14969928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 14979928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall if (!dtorKind) continue; 14989928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 14999a561d539158a30b68fc258b81a994f3fac10212Richard Smith // Anonymous union members do not have their destructors called. 15009a561d539158a30b68fc258b81a994f3fac10212Richard Smith const RecordType *RT = type->getAsUnionType(); 15019a561d539158a30b68fc258b81a994f3fac10212Richard Smith if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; 15029a561d539158a30b68fc258b81a994f3fac10212Richard Smith 15039928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CleanupKind cleanupKind = getCleanupKind(dtorKind); 1504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EHStack.pushCleanup<DestroyField>(cleanupKind, Field, 15059928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall getDestroyer(dtorKind), 15069928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall cleanupKind & EHCleanup); 1507607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1508607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1509607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1510c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1511c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 151259174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor/// 1513c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1514c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayType the type of the array to initialize 1515c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin an arrayType* 1516c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1517c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 15183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1519c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1520c3c0766277cd64bf117450a1519c9cf762d994d4John McCall const ConstantArrayType *arrayType, 1521c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1522c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1523c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1524c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1525c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType elementType; 1526c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements = 1527c3c0766277cd64bf117450a1519c9cf762d994d4John McCall emitArrayLength(arrayType, elementType, arrayBegin); 1528c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1529c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1530c3c0766277cd64bf117450a1519c9cf762d994d4John McCall argBegin, argEnd, zeroInitialize); 15313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 15323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1533c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1534c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 1535c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// 1536c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1537c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param numElements the number of elements in the array; 1538dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall/// may be zero 1539c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin a T*, where T is the type constructed by ctor 1540c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1541c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 15423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1543c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1544c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements, 1545c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1546c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1547c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1548c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1549dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1550dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // It's legal for numElements to be zero. This can happen both 1551dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // dynamically, because x can be zero in 'new A[x]', and statically, 1552dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // because of GCC extensions that permit zero-length arrays. There 1553dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // are probably legitimate places where we could assume that this 1554dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // doesn't happen, but it's not clear that it's worth it. 15556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::BranchInst *zeroCheckBranch = nullptr; 1556dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1557dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Optimize for a constant count. 1558dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::ConstantInt *constantCount 1559dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall = dyn_cast<llvm::ConstantInt>(numElements); 1560dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount) { 1561dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Just skip out if the constant count is zero. 1562dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount->isZero()) return; 1563dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1564dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Otherwise, emit the check. 1565dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } else { 1566dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1567dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1568dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1569dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall EmitBlock(loopBB); 1570dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } 1571dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1572c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Find the end of the array. 1573c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1574c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.end"); 1575c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1576c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Enter the loop, setting up a phi for the current location to initialize. 1577c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1578c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1579c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(loopBB); 1580c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1581c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.cur"); 1582c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(arrayBegin, entryBB); 15833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 15843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 1585c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1586c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType type = getContext().getTypeDeclType(ctor->getParent()); 15873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 158859174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor // Zero initialize the storage, if requested. 1589c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (zeroInitialize) 1590c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitNullInitialization(cur, type); 159159174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor 15923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 15933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 15943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 15953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 15963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 15973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 15983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 15993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 160044ec82b4a1597802f5bf17721481b8c265bc8dc5Anders Carlsson { 1601f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 16023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1603c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Evaluate the constructor and its arguments in a regular 1604c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // partial-destroy cleanup. 16054e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().Exceptions && 1606c3c0766277cd64bf117450a1519c9cf762d994d4John McCall !ctor->getParent()->hasTrivialDestructor()) { 1607c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Destroyer *destroyer = destroyCXXObject; 1608c3c0766277cd64bf117450a1519c9cf762d994d4John McCall pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1609c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 16103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1611c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1612378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, cur, argBegin, argEnd); 1613c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 16143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1615c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Go to the next element. 1616c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *next = 1617c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1618c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.next"); 1619c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(next, Builder.GetInsertBlock()); 16203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1621c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Check whether that's the end of the loop. 1622c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1623c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1624c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateCondBr(done, contBB, loopBB); 16253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1626dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Patch the earlier check to skip over the loop. 1627dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1628dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1629c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(contBB); 16303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 16313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1632bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1633bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall llvm::Value *addr, 1634bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall QualType type) { 1635bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const RecordType *rtype = type->castAs<RecordType>(); 1636bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1637bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXDestructorDecl *dtor = record->getDestructor(); 1638bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall assert(!dtor->isTrivial()); 1639bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1640378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, addr); 1641bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall} 1642bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall 16433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 16443b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1645155ed4a23366f4514befb1c9f5f89d16f8b8b6dbAnders Carlsson CXXCtorType Type, bool ForVirtualBase, 1646378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 16473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 16483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 16493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 16501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // If this is a trivial constructor, just emit what's needed. 16518b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 16528b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 16538b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 16548b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 16558b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 16563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16588b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16598b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 166085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 166185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 16628b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16638b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 16648b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 16658b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 16668b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 16673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // C++11 [class.mfct.non-static]p2: 1671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If a non-static member function of a class X is called for an object that 1672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // is not of type X, or of a type derived from X, the behavior is undefined. 1673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Provide a source location here. 1674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This, 1675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getContext().getRecordType(D->getParent())); 1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallArgList Args; 1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Push the this ptr. 1680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.add(RValue::get(This), D->getThisType(getContext())); 1681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Add the rest of the user-supplied arguments. 1683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 1684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); 1685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Insert any ABI-specific implicit constructor arguments. 1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs( 1688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *this, D, Type, ForVirtualBase, Delegating, Args); 1689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Emit the call. 1691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 1692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CGFunctionInfo &Info = 1693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs); 1694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitCall(Info, Callee, ReturnValueSlot(), Args, D); 16953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 16963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallvoid 169834999876e215b22febc240b1a6dc054215d12f9cFariborz JahanianCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 169934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *This, llvm::Value *Src, 170034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgBeg, 170134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgEnd) { 170234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian if (D->isTrivial()) { 170334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 170485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 170585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 170634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 170734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian return; 170834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 170962a3bbaac79f6e1b242ae3914e3ed4615f09302dNick Lewycky llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, clang::Ctor_Complete); 171034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(D->isInstance() && 171134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Trying to emit a member call expr on a static method!"); 171234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 1713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 171434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 171534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallArgList Args; 171634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 171734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the this ptr. 171804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(This), D->getThisType(getContext())); 171934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 172034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the src ptr. 1721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType QT = *(FPT->param_type_begin()); 17222acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *t = CGM.getTypes().ConvertType(QT); 172334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian Src = Builder.CreateBitCast(Src, t); 172404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(Src), QT); 1725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 172634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Skip over first argument (Src). 1727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitCallArgs(Args, FPT->isVariadic(), FPT->param_type_begin() + 1, 1728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FPT->param_type_end(), ArgBeg + 1, ArgEnd); 1729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 17300f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All), 17310f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Callee, ReturnValueSlot(), Args, D); 173234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian} 173334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 173434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanianvoid 1735c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1736c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CXXCtorType CtorType, 17374ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky const FunctionArgList &Args, 17384ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky SourceLocation Loc) { 1739c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CallArgList DelegateArgs; 1740c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1741c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1742c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "no parameters to constructor"); 1743c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1744c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // this 174504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1746c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1747c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1748c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // vtt 17491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (llvm::Value *VTT = GetVTTParameter(GlobalDecl(Ctor, CtorType), 1750378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1751378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true)) { 1752c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 175304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(VTT), VoidPP); 1754c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1755e1e35f761970fd662696b803a839c1f4a56f61b2Peter Collingbourne if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 1756c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "cannot skip vtt parameter, already done with args"); 1757d26bc76c98006609002d9930f8840490e88ac5b5John McCall assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1758c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1759c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1760c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1761c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1762c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Explicit arguments. 1763c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall for (; I != E; ++I) { 1764413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall const VarDecl *param = *I; 17654ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky // FIXME: per-argument source location 17664ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky EmitDelegateCallArg(DelegateArgs, param, Loc); 1767c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1768c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 176963fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(Ctor, CtorType); 1770de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), 177163fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren Callee, ReturnValueSlot(), DelegateArgs, Ctor); 1772c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 1773c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1774b76af9c969558b4484be87933e89e76e7ee87e21Sean Huntnamespace { 1775b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1776b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXDestructorDecl *Dtor; 1777b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt llvm::Value *Addr; 1778b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type; 1779b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1780b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1781b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type) 1782b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt : Dtor(D), Addr(Addr), Type(Type) {} 1783b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 1785b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1786378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true, Addr); 1787b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1788b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt }; 1789b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1790b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1791059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Huntvoid 1792059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean HuntCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1793059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt const FunctionArgList &Args) { 1794059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt assert(Ctor->isDelegatingConstructor()); 1795059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1796059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt llvm::Value *ThisPtr = LoadCXXThis(); 1797059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1798f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman QualType Ty = getContext().getTagDeclType(Ctor->getParent()); 1799d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = getContext().getTypeAlignInChars(Ty); 1800f85e193739c953358c865005855253af4f68a497John McCall AggValueSlot AggSlot = 1801f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), 18027c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 1803410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 1804649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 1805059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1806059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1807059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1808b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXRecordDecl *ClassDecl = Ctor->getParent(); 18094e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1810b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type = 1811b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1812b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1813b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1814b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ClassDecl->getDestructor(), 1815b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ThisPtr, Type); 1816b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1817b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1818059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 18193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 18203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 18218e6404ca28d6bbb76e97ea2a53a74816c2a74665Anders Carlsson bool ForVirtualBase, 1822378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 18233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase, 1825651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Delegating, This); 18263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 18273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1828291ae949612e371c41bf771a483b407d49372a4fJohn McCallnamespace { 18291f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallLocalDtor : EHScopeStack::Cleanup { 1830291ae949612e371c41bf771a483b407d49372a4fJohn McCall const CXXDestructorDecl *Dtor; 1831291ae949612e371c41bf771a483b407d49372a4fJohn McCall llvm::Value *Addr; 1832291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1833291ae949612e371c41bf771a483b407d49372a4fJohn McCall CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1834291ae949612e371c41bf771a483b407d49372a4fJohn McCall : Dtor(D), Addr(Addr) {} 1835291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void Emit(CodeGenFunction &CGF, Flags flags) override { 1837291ae949612e371c41bf771a483b407d49372a4fJohn McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1838378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1839378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 1840291ae949612e371c41bf771a483b407d49372a4fJohn McCall } 1841291ae949612e371c41bf771a483b407d49372a4fJohn McCall }; 1842291ae949612e371c41bf771a483b407d49372a4fJohn McCall} 1843291ae949612e371c41bf771a483b407d49372a4fJohn McCall 184481407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCallvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 184581407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall llvm::Value *Addr) { 18461f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 184781407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall} 184881407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall 1849f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1850f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1851f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!ClassDecl) return; 1852f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ClassDecl->hasTrivialDestructor()) return; 1853f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1854f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1855642a75f883e644bcfbb82e7af0313776ad1ce33cJohn McCall assert(D && D->isUsed() && "destructor not marked as used!"); 185681407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall PushDestructorCleanup(D, Addr); 1857f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1858f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1859d103f9f9b401b419e756f8c1849683cd77586067Anders Carlssonvoid 1860d103f9f9b401b419e756f8c1849683cd77586067Anders CarlssonCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1861b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1862d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1863d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson const CXXRecordDecl *VTableClass) { 1864d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute the address point. 1865a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov bool NeedsVirtualOffset; 1866a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov llvm::Value *VTableAddressPoint = 1867a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov CGM.getCXXABI().getVTableAddressPointInStructor( 1868a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset); 1869a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov if (!VTableAddressPoint) 1870a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov return; 1871d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1872d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute where to store the address point. 18736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Value *VirtualOffset = nullptr; 18749a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtualOffset = CharUnits::Zero(); 18753e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson 1876a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov if (NeedsVirtualOffset) { 18773e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // We need to use the virtual base offset offset because the virtual base 18783e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // might have a different offset in the most derived class. 1879b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this, 1880b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner LoadCXXThis(), 1881b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VTableClass, 1882b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner NearestVBase); 1883d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck NonVirtualOffset = OffsetFromNearestVBase; 18843e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } else { 18858246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // We can just use the base offset in the complete class. 18864230d529a8797bbeef2328b60abeae333f7e143fKen Dyck NonVirtualOffset = Base.getBaseOffset(); 18873e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } 18888246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 18898246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // Apply the offsets. 18908246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VTableField = LoadCXXThis(); 18918246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 18929a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtualOffset.isZero() || VirtualOffset) 18938246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 18948246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NonVirtualOffset, 18958246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset); 189636fd6beef1ffaf93217d8ce96d900d4ed817e463Anders Carlsson 1897d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Finally, store the address point. 18982acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *AddressPointPtrTy = 1899d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableAddressPoint->getType()->getPointerTo(); 1900d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 19018cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 19028cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); 1903d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 1904d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1905603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid 1906603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders CarlssonCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1907b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1908d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1909603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson bool BaseIsNonVirtualPrimaryBase, 1910603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *VTableClass, 1911603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy& VBases) { 1912603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // If this base is a non-virtual primary base the address point has already 1913603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // been set. 1914603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseIsNonVirtualPrimaryBase) { 1915603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointer for this base. 19164235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 19177f918f960101a83163f63bb1e1d42c3f0787887fTimur Iskhodzhanov VTableClass); 1918603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 19194658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1920603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 19214658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1922603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Traverse bases. 1923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : RD->bases()) { 19240703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson CXXRecordDecl *BaseDecl 1925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); 1926603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1927603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 1928603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseDecl->isDynamicClass()) 1929603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1930603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1931d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffset; 1932d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffsetFromNearestVBase; 193314da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson bool BaseDeclIsNonVirtualPrimaryBase; 1934603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I.isVirtual()) { 1936603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Check if we've visited this virtual base before. 1937603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!VBases.insert(BaseDecl)) 1938603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1939603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1940603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = 1941603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson getContext().getASTRecordLayout(VTableClass); 1942603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1943d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1944d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffsetFromNearestVBase = CharUnits::Zero(); 194514da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = false; 1946603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } else { 1947603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1948603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 19494230d529a8797bbeef2328b60abeae333f7e143fKen Dyck BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 19504235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase = 1951d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 195214da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 1953603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 19540703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson 19554230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 1956651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I.isVirtual() ? BaseDecl : NearestVBase, 19574235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase, 195814da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase, 19597f918f960101a83163f63bb1e1d42c3f0787887fTimur Iskhodzhanov VTableClass, VBases); 19603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 19613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 19623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1963603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 1964603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 19650703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson if (!RD->isDynamicClass()) 19663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 19673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1968603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointers for this class and all of its bases. 1969603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy VBases; 19704230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 19716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*NearestVBase=*/nullptr, 1972d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck /*OffsetFromNearestVBase=*/CharUnits::Zero(), 19737f918f960101a83163f63bb1e1d42c3f0787887fTimur Iskhodzhanov /*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases); 19745bd0d44c8da50f3a629c90fee92ce5cf1e31c9ffTimur Iskhodzhanov 19755bd0d44c8da50f3a629c90fee92ce5cf1e31c9ffTimur Iskhodzhanov if (RD->getNumVBases()) 19765bd0d44c8da50f3a629c90fee92ce5cf1e31c9ffTimur Iskhodzhanov CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD); 19773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1978043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman 1979043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohmanllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 19802acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty) { 1981043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 19828cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 19838cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr()); 19848cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany return VTable; 1985043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman} 1986a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1987a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1988a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 1989a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// quite what we want. 1990a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 1991a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 1992a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 1993a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = PE->getSubExpr(); 1994a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1995a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1996a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1997a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 1998a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_NoOp) { 1999a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 2000a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2001a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2002a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2003a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 2004a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UO->getOpcode() == UO_Extension) { 2005a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = UO->getSubExpr(); 2006a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2007a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2008a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2009a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return E; 2010a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2011a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2012a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 20139581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramerbool 20149581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin KramerCodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base, 20159581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer const CXXMethodDecl *MD) { 20169581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer // When building with -fapple-kext, all calls must go through the vtable since 20179581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer // the kernel linker can do runtime patching of vtables. 20189581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer if (getLangOpts().AppleKext) 20199581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer return false; 20209581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer 2021a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the most derived class is marked final, we know that no subclass can 2022a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // override this member function and so we can devirtualize it. For example: 2023a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2024a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct A { virtual void f(); } 2025a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct B final : A { }; 2026a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2027a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // void f(B *b) { 2028a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // b->f(); 2029a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // } 2030a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 20319581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType(); 2032a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 2033a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2034a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2035a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the member function is marked 'final', we know that it can't be 2036a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // overridden and can therefore devirtualize it. 2037a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->hasAttr<FinalAttr>()) 2038a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2039a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2040a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Similarly, if the class itself is marked 'final' it can't be overridden 2041a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // and we can therefore devirtualize the member function call. 2042a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->getParent()->hasAttr<FinalAttr>()) 2043a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2044a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2045a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson Base = skipNoOpCastsAndParens(Base); 2046a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 2047a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 2048a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // This is a record decl. We know the type and can devirtualize it. 2049a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return VD->getType()->isRecordType(); 2050a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2051a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2052a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2053a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 20549581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer 20559581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer // We can devirtualize calls on an object accessed by a class member access 20569581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer // expression, since by C++11 [basic.life]p6 we know that it can't refer to 20579581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer // a derived class object constructed in the same location. 20589581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) 20599581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) 20609581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer return VD->getType()->isRecordType(); 20619581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer 2062a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can always devirtualize calls on temporary object expressions. 2063a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXConstructExpr>(Base)) 2064a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2065a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2066a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // And calls on bound temporaries. 2067a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXBindTemporaryExpr>(Base)) 2068a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2069a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2070a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Check if this is a call expr that returns a record type. 2071a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 2072a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CE->getCallReturnType()->isRecordType(); 2073a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2074a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can't devirtualize the call. 2075a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2076a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2077a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2078a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonllvm::Value * 2079a2447e0d1e28669cd637204a871f15b1215277fdAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 2080a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD, 2081a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson llvm::Value *This) { 2082de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnType = 2083de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().GetFunctionType( 2084de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(MD)); 2085a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 20869581ed07dee5376002620a0cfb363c6b9e5bdd3eBenjamin Kramer if (MD->isVirtual() && !CanDevirtualizeMemberFunctionCall(E->getArg(0), MD)) 20878f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov return CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, fnType); 2088a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2089de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return CGM.GetAddrOfFunction(MD, fnType); 2090a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2091bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman 2092d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Valivoid CodeGenFunction::EmitForwardingCallToLambda( 2093d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali const CXXMethodDecl *callOperator, 2094d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali CallArgList &callArgs) { 209521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Get the address of the call operator. 20960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const CGFunctionInfo &calleeFnInfo = 20970f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 20980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall llvm::Value *callee = 20990f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.GetAddrOfFunction(GlobalDecl(callOperator), 21000f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().GetFunctionType(calleeFnInfo)); 21010f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21020f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Prepare the return slot. 21030f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const FunctionProtoType *FPT = 21040f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callOperator->getType()->castAs<FunctionProtoType>(); 2105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType resultType = FPT->getReturnType(); 21060f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ReturnValueSlot returnSlot; 21070f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && 21080f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 21099d232c884ea9872d6555df0fd7359699819bc1f1John McCall !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) 21100f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); 21110f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21120f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // We don't need to separately arrange the call arguments because 21130f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // the call can't be variadic anyway --- it's impossible to forward 21140f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // variadic arguments. 211521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 211621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Now emit our call. 21170f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, 21180f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callArgs, callOperator); 211921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 21200f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // If necessary, copy the returned value into the slot. 21210f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && returnSlot.isNull()) 21220f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitReturnOfRValue(RV, resultType); 212350f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman else 212450f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman EmitBranchThroughCleanup(ReturnBlock); 212521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman} 212621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 212764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaBlockInvokeBody() { 212864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const BlockDecl *BD = BlockInfo->getBlockDecl(); 212964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const VarDecl *variable = BD->capture_begin()->getVariable(); 213064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 213164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 213264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 213364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 213464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 213564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 213664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = GetAddrOfBlockDecl(variable, false); 213764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 213864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 213964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 2140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto param : BD->params()) 21414ee7dc2369c1f0257a73b2e83a7d38fdebdd9176Nick Lewycky EmitDelegateCallArg(CallArgs, param, param->getLocStart()); 2142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2143d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali assert(!Lambda->isGenericLambda() && 2144d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali "generic lambda interconversion to block not implemented"); 2145d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali EmitForwardingCallToLambda(Lambda->getLambdaCallOperator(), CallArgs); 214664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 214764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 214864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { 2149f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall if (cast<CXXMethodDecl>(CurCodeDecl)->isVariadic()) { 215064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // FIXME: Making this work correctly is nasty because it requires either 215164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // cloning the body of the call operator or making the call operator forward. 2152f5ebf9bf1df10ac15ba32a4b24dfe171b7848c58John McCall CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function"); 215364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 215464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 215564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 21563cebc73895daccea85984d8881b5b45c8f8df9c6Richard Smith EmitFunctionBody(Args, cast<FunctionDecl>(CurGD.getDecl())->getBody()); 215764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 215864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 215964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 216064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = MD->getParent(); 216164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 216264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 216364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 216464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 216564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 216664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 216764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 216864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 216964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 2170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto Param : MD->params()) 2171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EmitDelegateCallArg(CallArgs, Param, Param->getLocStart()); 2172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2173d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 2174d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali // For a generic lambda, find the corresponding call operator specialization 2175d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali // to which the call to the static-invoker shall be forwarded. 2176d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali if (Lambda->isGenericLambda()) { 2177d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali assert(MD->isFunctionTemplateSpecialization()); 2178d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); 2179d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate(); 21806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void *InsertPos = nullptr; 2181d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali FunctionDecl *CorrespondingCallOpSpecialization = 2182ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos); 2183d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali assert(CorrespondingCallOpSpecialization); 2184d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); 2185d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali } 2186d6992ab33b7113e1bd7af51c0c52d17c23706c01Faisal Vali EmitForwardingCallToLambda(CallOp, CallArgs); 218764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 218864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 218927dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregorvoid CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { 219027dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor if (MD->isVariadic()) { 219121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // FIXME: Making this work correctly is nasty because it requires either 219221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // cloning the body of the call operator or making the call operator forward. 219321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 219464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 219521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman } 219621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 219727dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor EmitLambdaDelegatingInvokeBody(MD); 2198bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman} 2199