CGClass.cpp revision 63fd408a61ae9b94e8d8a986832f526f7cdbfa84
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" 15d67ef0eed463b43980f04a444155f423114be34bDevang Patel#include "CGDebugInfo.h" 1656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#include "CGRecordLayout.h" 175d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 181d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov#include "CGCXXABI.h" 192f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 207e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "clang/AST/EvaluatedExprVisitor.h" 215d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 229fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "clang/AST/StmtCXX.h" 2356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#include "clang/Basic/TargetBuiltins.h" 243ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include "clang/Frontend/CodeGenOptions.h" 252f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 275d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 285d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 2955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyckstatic CharUnits 3034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, 3134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *DerivedClass, 32f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start, 33f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator End) { 3455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = CharUnits::Zero(); 3534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *RD = DerivedClass; 3734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 38f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXBaseSpecifier *Base = *I; 4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson assert(!Base->isVirtual() && "Should not see virtual bases here!"); 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the layout. 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *BaseDecl = 4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Add the offset. 4955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RD = BaseDecl; 5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 5334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return Offset; 5534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 565d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 5784080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 58a04efdf635d35d88e65041fad007225d8c8d64a5Anders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 59f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 60f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd) { 61f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 62a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = 64f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 65f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall PathBegin, PathEnd); 6655c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (Offset.isZero()) 67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson return 0; 68a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 70a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 71a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 7255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 7384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 758561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// Gets the address of a direct base class within a complete object. 76bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 77bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 78bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 79bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 80bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 818561a8666c70f924c8f0209c41b9b77bbbf90607Anders CarlssonCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 828561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 838561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Base, 848561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson bool BaseIsVirtual) { 85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 90bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 915fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck CharUnits Offset; 92bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 938561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (BaseIsVirtual) 945fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getVBaseClassOffset(Base); 95bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 965fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getBaseClassOffset(Base); 97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 98bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 100bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 1015fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck if (Offset.isPositive()) { 102bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1035fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); 104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall } 105bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 107bff225ecf77fb891596ecb1b27196310d268365eJohn McCall return V; 108d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 109bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1109dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlssonstatic llvm::Value * 1117916c997127fe616ba255ba4cade10e5de0c8812John McCallApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ptr, 1127916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits nonVirtualOffset, 1137916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *virtualOffset) { 1147916c997127fe616ba255ba4cade10e5de0c8812John McCall // Assert that we have something to do. 1157916c997127fe616ba255ba4cade10e5de0c8812John McCall assert(!nonVirtualOffset.isZero() || virtualOffset != 0); 1167916c997127fe616ba255ba4cade10e5de0c8812John McCall 1177916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the offset from the static and dynamic components. 1187916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *baseOffset; 1197916c997127fe616ba255ba4cade10e5de0c8812John McCall if (!nonVirtualOffset.isZero()) { 1207916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy, 1217916c997127fe616ba255ba4cade10e5de0c8812John McCall nonVirtualOffset.getQuantity()); 1227916c997127fe616ba255ba4cade10e5de0c8812John McCall if (virtualOffset) { 1237916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 1247916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1257916c997127fe616ba255ba4cade10e5de0c8812John McCall } else { 1267916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = virtualOffset; 1277916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1289dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1299dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson // Apply the base offset. 1307916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); 1317916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); 1327916c997127fe616ba255ba4cade10e5de0c8812John McCall return ptr; 1339dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson} 1349dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1355d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 13634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 1378561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 138f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 139f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 14034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson bool NullCheckValue) { 141f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 14234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 143f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start = PathBegin; 14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *VBase = 0; 14534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1467916c997127fe616ba255ba4cade10e5de0c8812John McCall // Sema has done some convenient canonicalization here: if the 1477916c997127fe616ba255ba4cade10e5de0c8812John McCall // access path involved any virtual steps, the conversion path will 1487916c997127fe616ba255ba4cade10e5de0c8812John McCall // *start* with a step down to the correct virtual base subobject, 1497916c997127fe616ba255ba4cade10e5de0c8812John McCall // and hence will not require any further steps. 15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if ((*Start)->isVirtual()) { 15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VBase = 15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 15334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson ++Start; 15434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 1557916c997127fe616ba255ba4cade10e5de0c8812John McCall 1567916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the static offset of the ultimate destination within its 1577916c997127fe616ba255ba4cade10e5de0c8812John McCall // allocating subobject (the virtual base, if there is one, or else 1587916c997127fe616ba255ba4cade10e5de0c8812John McCall // the "complete" object that we see). 15955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits NonVirtualOffset = 1608561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 161f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall Start, PathEnd); 16234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1637916c997127fe616ba255ba4cade10e5de0c8812John McCall // If there's a virtual step, we can sometimes "devirtualize" it. 1647916c997127fe616ba255ba4cade10e5de0c8812John McCall // For now, that's limited to when the derived type is final. 1657916c997127fe616ba255ba4cade10e5de0c8812John McCall // TODO: "devirtualize" this for accesses to known-complete objects. 1667916c997127fe616ba255ba4cade10e5de0c8812John McCall if (VBase && Derived->hasAttr<FinalAttr>()) { 1677916c997127fe616ba255ba4cade10e5de0c8812John McCall const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 1687916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 1697916c997127fe616ba255ba4cade10e5de0c8812John McCall NonVirtualOffset += vBaseOffset; 1707916c997127fe616ba255ba4cade10e5de0c8812John McCall VBase = 0; // we no longer have a virtual step 1717916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1727916c997127fe616ba255ba4cade10e5de0c8812John McCall 17334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the base pointer type. 1742acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtrTy = 175f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ConvertType((PathEnd[-1])->getType())->getPointerTo(); 1767916c997127fe616ba255ba4cade10e5de0c8812John McCall 1777916c997127fe616ba255ba4cade10e5de0c8812John McCall // If the static offset is zero and we don't have a virtual step, 1787916c997127fe616ba255ba4cade10e5de0c8812John McCall // just do a bitcast; null checks are unnecessary. 17955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (NonVirtualOffset.isZero() && !VBase) { 18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 18134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 1827916c997127fe616ba255ba4cade10e5de0c8812John McCall 1837916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *origBB = 0; 1847916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *endBB = 0; 18534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1867916c997127fe616ba255ba4cade10e5de0c8812John McCall // Skip over the offset (and the vtable load) if we're supposed to 1877916c997127fe616ba255ba4cade10e5de0c8812John McCall // null-check the pointer. 18834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 1897916c997127fe616ba255ba4cade10e5de0c8812John McCall origBB = Builder.GetInsertBlock(); 1907916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 1917916c997127fe616ba255ba4cade10e5de0c8812John McCall endBB = createBasicBlock("cast.end"); 19234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1937916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *isNull = Builder.CreateIsNull(Value); 1947916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateCondBr(isNull, endBB, notNullBB); 1957916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(notNullBB); 19634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 19734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1987916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the virtual offset. 19934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::Value *VirtualOffset = 0; 200336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (VBase) { 2017916c997127fe616ba255ba4cade10e5de0c8812John McCall VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); 202336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } 20334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2047916c997127fe616ba255ba4cade10e5de0c8812John McCall // Apply both offsets. 20555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 2069a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset, 20734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VirtualOffset); 20834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2097916c997127fe616ba255ba4cade10e5de0c8812John McCall // Cast to the destination type. 21034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 2117916c997127fe616ba255ba4cade10e5de0c8812John McCall 2127916c997127fe616ba255ba4cade10e5de0c8812John McCall // Build a phi if we needed a null check. 21334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 2147916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 2157916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateBr(endBB); 2167916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(endBB); 21734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2187916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); 2197916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(Value, notNullBB); 2207916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); 22134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = PHI; 22234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 22334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Value; 22534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 22634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonllvm::Value * 228a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 2298561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 231f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 233f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 234a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 2368561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 2372acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 238c764830bdb6de82baed068889096bd3e52d4cbdaRichard Smith 239a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 240f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 241a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 242a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 243a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 244a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 245a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 246a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 256b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 261a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 262c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateBitCast(Value, Int8PtrTy); 263c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateGEP(Value, Builder.CreateNeg(NonVirtualOffset), 264c5685438df6105052b02c9e02f01c34489606308Eli Friedman "sub.ptr"); 265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 267a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 268a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 274a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 275bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 277a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 27832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 279a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 28032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2815d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 282a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2835d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 2841d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2851d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanovllvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 2861d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool ForVirtualBase, 2871d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating) { 288af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (!CodeGenVTables::needsVTTParameter(GD)) { 289c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 291c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 292c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2931d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurFuncDecl)->getParent(); 294c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2953b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 296c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 297c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall uint64_t SubVTTIndex; 2993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 300378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor if (Delegating) { 301378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If this is a delegating constructor call, just load the VTT. 3021d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov return LoadCXXVTT(); 303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor } else if (RD == Base) { 304378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If the record matches the base, this is the complete ctor/dtor 305378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // variant calling the base variant in a class with virtual bases. 3061d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(!CodeGenVTables::needsVTTParameter(CurGD) && 3073b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "doing no-op VTT offset in base dtor/ctor?"); 308314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson assert(!ForVirtualBase && "Can't have same class as virtual base!"); 3093b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall SubVTTIndex = 0; 3103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } else { 3111d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 3124230d529a8797bbeef2328b60abeae333f7e143fKen Dyck CharUnits BaseOffset = ForVirtualBase ? 3134230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getVBaseClassOffset(Base) : 3144230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getBaseClassOffset(Base); 315c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 316c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson SubVTTIndex = 3171d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 3183b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 3193b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 320c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 3211d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (CodeGenVTables::needsVTTParameter(CurGD)) { 322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 3231d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = LoadCXXVTT(); 3241d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 325c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 326c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 3271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = CGM.getVTables().GetAddrOfVTT(RD); 3281d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov VTT = Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 329c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 330c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 331c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 332c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 333c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 334182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 33550da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the destructor for a direct base class. 3361f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallBaseDtor : EHScopeStack::Cleanup { 33750da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *BaseClass; 33850da2cadcc6da86abff6772de65280ace2cabc94John McCall bool BaseIsVirtual; 33950da2cadcc6da86abff6772de65280ace2cabc94John McCall CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 341182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 342ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 34350da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *DerivedClass = 34450da2cadcc6da86abff6772de65280ace2cabc94John McCall cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 34550da2cadcc6da86abff6772de65280ace2cabc94John McCall 34650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *D = BaseClass->getDestructor(); 34750da2cadcc6da86abff6772de65280ace2cabc94John McCall llvm::Value *Addr = 34850da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 34950da2cadcc6da86abff6772de65280ace2cabc94John McCall DerivedClass, BaseClass, 35050da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseIsVirtual); 351378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 352378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 353182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 354182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 3557e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3567e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// A visitor which checks whether an initializer uses 'this' in a 3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// way which requires the vtable to be properly set. 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool UsesThis; 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Black-list all explicit and implicit references to 'this'. 3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall // 3677e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Do we need to worry about external references to 'this' derived 3687e1dff7a68a4d00e71debafa7f5c259473091746John McCall // from arbitrary code? If so, then anything which runs arbitrary 3697e1dff7a68a4d00e71debafa7f5c259473091746John McCall // external code might potentially access the vtable. 3707e1dff7a68a4d00e71debafa7f5c259473091746John McCall void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 3717e1dff7a68a4d00e71debafa7f5c259473091746John McCall }; 3727e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3737e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3747e1dff7a68a4d00e71debafa7f5c259473091746John McCallstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 3757e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker Checker(C); 3767e1dff7a68a4d00e71debafa7f5c259473091746John McCall Checker.Visit(const_cast<Expr*>(Init)); 3777e1dff7a68a4d00e71debafa7f5c259473091746John McCall return Checker.UsesThis; 378182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 379182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 382cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *BaseInit, 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 39380638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson bool isBaseVirtual = BaseInit->isBaseVirtual(); 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 3997e1dff7a68a4d00e71debafa7f5c259473091746John McCall // If the initializer for the base (other than the constructor 4007e1dff7a68a4d00e71debafa7f5c259473091746John McCall // itself) accesses 'this' in any way, we need to initialize the 4017e1dff7a68a4d00e71debafa7f5c259473091746John McCall // vtables. 4027e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 4037e1dff7a68a4d00e71debafa7f5c259473091746John McCall CGF.InitializeVTablePointers(ClassDecl); 4047e1dff7a68a4d00e71debafa7f5c259473091746John McCall 405bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 406bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 4078561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson llvm::Value *V = 4088561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 40950da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseClassDecl, 41050da2cadcc6da86abff6772de65280ace2cabc94John McCall isBaseVirtual); 411d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = CGF.getContext().getTypeAlignInChars(BaseType); 4127c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot AggSlot = 413f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(V, Alignment, Qualifiers(), 4147c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 415410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 416649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 417558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 418558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 419594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 4204e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGF.CGM.getLangOpts().Exceptions && 421c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson !BaseClassDecl->hasTrivialDestructor()) 4221f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 4231f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall isBaseVirtual); 424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 426fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregorstatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 427fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue LHS, 4280bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Expr *Init, 429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar, 430fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType T, 4310bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes, 432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned Index) { 4330bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Index == ArrayIndexes.size()) { 434f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman LValue LV = LHS; 435924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl { // Scope for Cleanups. 436924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CodeGenFunction::RunCleanupsScope Cleanups(CGF); 437924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 438924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (ArrayIndexVar) { 439924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // If we have an array index variable, load it and use it as an offset. 440924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Then, increment the value. 441924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Dest = LHS.getAddress(); 442924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 443924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 444924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 445924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 446924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.Builder.CreateStore(Next, ArrayIndexVar); 447924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 448924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Update the LValue. 449924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAddress(Dest); 450924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CharUnits Align = CGF.getContext().getTypeAlignInChars(T); 451924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAlignment(std::min(Align, LV.getAlignment())); 452924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 453924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 4549d232c884ea9872d6555df0fd7359699819bc1f1John McCall switch (CGF.getEvaluationKind(T)) { 4559d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Scalar: 456924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); 4579d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 4589d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Complex: 4599d232c884ea9872d6555df0fd7359699819bc1f1John McCall CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); 4609d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 4619d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Aggregate: { 462924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot Slot = 463924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::forLValue(LV, 464924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::IsDestructed, 465924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::DoesNotNeedGCBarriers, 466649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 467924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 468924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitAggExpr(Init, Slot); 4699d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 4709d232c884ea9872d6555df0fd7359699819bc1f1John McCall } 471924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 472fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 473558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 474924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Now, outside of the initializer cleanup scope, destroy the backing array 475924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // for a std::initializer_list member. 476972edf0534d8a50f87fac1d0ff34eb22f593df11Sebastian Redl CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init); 477924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 482fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(Array && "Array initialization without the array type?"); 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IndexVar 4840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]); 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(IndexVar && "Array index variable not loaded"); 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Initialize this index variable to zero. 488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value* Zero 489fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = llvm::Constant::getNullValue( 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.ConvertType(CGF.getContext().getSizeType())); 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, IndexVar); 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Start the loop with a block that tests the condition. 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(CondBlock); 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 500fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Generate: if (loop-index < number-of-elements) fall to the loop body, 501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // otherwise, go to the block after the for-loop. 502fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor uint64_t NumElements = Array->getSize().getZExtValue(); 503fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 504985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::Value *NumElementsPtr = 505985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::ConstantInt::get(Counter->getType(), NumElements); 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "isless"); 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If the condition is true, execute the body. 510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 511fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 512fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ForBody); 513fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 514fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 515fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor { 516f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope Cleanups(CGF); 517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 518fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Inside the loop body recurse to emit the inner loop or, eventually, the 519fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // constructor call. 5200bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, 5210bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Array->getElementType(), ArrayIndexes, Index + 1); 522fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 523fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 524fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ContinueBlock); 525fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 526fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the increment of the loop counter. 527fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 528fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Counter = CGF.Builder.CreateLoad(IndexVar); 529fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 530fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(NextVal, IndexVar); 531fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 532fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Finally, branch back up to the condition for the next iteration. 533fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBranch(CondBlock); 534fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 535fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the fall-through block. 536fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(AfterFor, true); 537fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor} 538182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 541cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 542fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const CXXConstructorDecl *Constructor, 543fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 54400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet assert(MemberInit->isAnyMemberInitializer() && 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 5467a614d8380297fcd2bc23986241905d97222948cRichard Smith assert(MemberInit->getInit() && "Must have initializer!"); 547607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 54900eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldDecl *Field = MemberInit->getAnyMember(); 5500bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 551607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 552607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 553377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 554859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 555377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman 55600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (MemberInit->isIndirectMemberInitializer()) { 557859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // If we are initializing an anonymous union field, drill down to 558859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // the field. 559859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 560859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(), 561859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IEnd = IndirectField->chain_end(); 562859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman for ( ; I != IEnd; ++I) 563859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I)); 56400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 565a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall } else { 566859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 5690bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Special case: if we are in a copy or move constructor, and we are copying 5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // an array of PODs or classes with trivial copy constructors, ignore the 5710bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // AST and perform the copy we know is equivalent. 5720bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // FIXME: This is hacky at best... if we had a bit more explicit information 5730bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // in the AST, we could generalize it more easily. 5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman const ConstantArrayType *Array 5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.getContext().getAsConstantArrayType(FieldType); 5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Array && Constructor->isImplicitlyDefined() && 5770bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Constructor->isCopyOrMoveConstructor()) { 5780bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 579e9385363069388d8e3536052a138f17332e00620Richard Smith CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 5800bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (BaseElementTy.isPODType(CGF.getContext()) || 581e9385363069388d8e3536052a138f17332e00620Richard Smith (CE && CE->getConstructor()->isTrivial())) { 582e9385363069388d8e3536052a138f17332e00620Richard Smith // Find the source pointer. We know it's the last argument because 583e9385363069388d8e3536052a138f17332e00620Richard Smith // we know we're in an implicit copy constructor. 5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned SrcArgIndex = Args.size() - 1; 5850bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman llvm::Value *SrcPtr 5860bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 587377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 588377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5900bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Copy the aggregate. 5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 592649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier LHS.isVolatileQualified()); 5930bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman return; 5940bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5950bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5970bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes; 5980bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (MemberInit->getNumArrayIndices()) 5990bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes = MemberInit->getArrayIndexes(); 600b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes); 6010bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman} 6020bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid CodeGenFunction::EmitInitializerForField(FieldDecl *Field, 604b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LValue LHS, Expr *Init, 605b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayRef<VarDecl *> ArrayIndexes) { 6060bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 6079d232c884ea9872d6555df0fd7359699819bc1f1John McCall switch (getEvaluationKind(FieldType)) { 6089d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Scalar: 609f85e193739c953358c865005855253af4f68a497John McCall if (LHS.isSimple()) { 610b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitExprAsInit(Init, Field, LHS, false); 611f85e193739c953358c865005855253af4f68a497John McCall } else { 612b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman RValue RHS = RValue::get(EmitScalarExpr(Init)); 613b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitStoreThroughLValue(RHS, LHS); 614f85e193739c953358c865005855253af4f68a497John McCall } 6159d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 6169d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Complex: 6179d232c884ea9872d6555df0fd7359699819bc1f1John McCall EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); 6189d232c884ea9872d6555df0fd7359699819bc1f1John McCall break; 6199d232c884ea9872d6555df0fd7359699819bc1f1John McCall case TEK_Aggregate: { 620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar = 0; 6210bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (ArrayIndexes.size()) { 622b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 623fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 624fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // The LHS is a pointer to the first object we'll be constructing, as 625fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // a flat array. 626b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman QualType BaseElementTy = getContext().getBaseElementType(FieldType); 627b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *BasePtr = ConvertType(BaseElementTy); 628fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr = llvm::PointerType::getUnqual(BasePtr); 629b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), 630b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman BasePtr); 631b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy); 632fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Create an array index that will be used to walk over all of the 634fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // objects we're constructing. 635b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index"); 636fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 637b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman Builder.CreateStore(Zero, ArrayIndexVar); 638fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 639fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 640fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the block variables for the array indices, if any. 6410bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I) 642b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAutoVarDecl(*ArrayIndexes[I]); 643fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 644fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 645b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, 6460bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes, 0); 647607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 6489d232c884ea9872d6555df0fd7359699819bc1f1John McCall } 649074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall 650074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // Ensure that we destroy this object if an exception is thrown 651074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // later in the constructor. 652074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 653074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall if (needsEHCleanup(dtorKind)) 654074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 655607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 656607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Checks whether the given constructor is a valid subject for the 658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// complete-to-base constructor delegation optimization, i.e. 659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// emitting the complete constructor as a simple call to the base 660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// constructor. 661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallstatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Currently we disable the optimization for classes with virtual 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // bases because (1) the addresses of parameter variables need to be 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // consistent across all initializers but (2) the delegate function 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // call necessarily creates a second copy of the parameter variable. 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // The limiting example (purely theoretical AFAIK): 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct A { A(int &c) { c++; } }; 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct B : virtual A { 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // B(int count) : A(count) { printf("%d\n", count); } 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // }; 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // ...although even this example could in principle be emitted as a 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation since the address of the parameter doesn't escape. 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getParent()->getNumVBases()) { 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list trivial vbase initializers. This case wouldn't 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // be subject to the restrictions below. 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list cases where: 680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - there are no non-reference parameters to the constructor 681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't access any non-reference parameters 682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't take the address of non-reference 683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // parameters 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - etc. 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // If we ever add any of the above cases, remember that: 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - function-try-blocks will always blacklist this optimization 687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - we need to perform the constructor prologue and cleanup in 688c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // EmitConstructorBody. 689c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 690c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 691c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 692c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 693c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // We also disable the optimization for variadic functions because 694c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // it's impossible to "re-pass" varargs. 695c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 696c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 698059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt // FIXME: Decide if we can do a delegation of a delegating constructor. 699059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (Ctor->isDelegatingConstructor()) 700059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return false; 701059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 702c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return true; 703c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7059fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitConstructorBody - Emits the body of the current constructor. 7069fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 7079fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 7089fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXCtorType CtorType = CurGD.getCtorType(); 7099fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 710c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Before we go any further, try the complete->base constructor 711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation optimization. 7128560791791e7b33249feb0ffafeca427076b37b4Timur Iskhodzhanov if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 713b8b2c9da87e7d70a1679db026f40548b3192b705John McCall CGM.getContext().getTargetInfo().getCXXABI().hasConstructorVariants()) { 714d67ef0eed463b43980f04a444155f423114be34bDevang Patel if (CGDebugInfo *DI = getDebugInfo()) 71573fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, Ctor->getLocEnd()); 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args); 717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return; 718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7209fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Ctor->getBody(); 7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 722c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Enter the function-try-block before the constructor prologue if 723c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // applicable. 724c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 725c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 72659a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7279fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 728f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); 7299fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 73056ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // TODO: in restricted cases, we can emit the vbase initializers of 73156ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // a complete ctor and then delegate to the base ctor. 73256ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall 733c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Emit the constructor prologue, i.e. the base and member 734c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // initializers. 735fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitCtorPrologue(Ctor, CtorType, Args); 7369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit the body of the statement. 738c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 7399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall else if (Body) 7419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(Body); 7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7439fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit any cleanup blocks associated with the member or base 7449fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // initializers, which includes (along the exceptional path) the 7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // destructors for those members and bases that were fully 7469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // constructed. 747f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall PopCleanupBlocks(CleanupDepth); 7489fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 749c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 75059a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7519fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 7529fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 75356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesnamespace { 75456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class FieldMemcpyizer { 75556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 75656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 75756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec) 75856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 75956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 76056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField(0), LastField(0), FirstFieldOffset(0), LastFieldOffset(0), 76156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex(0) { } 76256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 76356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static bool isMemcpyableField(FieldDecl *F) { 76456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Qualifiers Qual = F->getType().getQualifiers(); 76556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 76656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 76756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 76856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 76956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 77056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemcpyableField(FieldDecl *F) { 77156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField == 0) 77256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addInitialField(F); 77356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames else 77456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addNextField(F); 77556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 77656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 77756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits getMemcpySize() const { 77856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastFieldSize = 77956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->isBitField() ? 78056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->getBitWidthValue(CGF.getContext()) : 78156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getTypeSize(LastField->getType()); 78256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t MemcpySizeBits = 78356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset + LastFieldSize - FirstFieldOffset + 78456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getCharWidth() - 1; 78556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = 78656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().toCharUnitsFromBits(MemcpySizeBits); 78756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return MemcpySize; 78856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 78956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 79056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpy() { 79156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Give the subclass a chance to bail out if it feels the memcpy isn't 79256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // worth it (e.g. Hasn't aggregated enough data). 79356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField == 0) { 79456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 79556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 79656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 7975e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames CharUnits Alignment; 79856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 79956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField->isBitField()) { 80056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGRecordLayout &RL = 80156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 80256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 8035e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment); 8045e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } else { 80523742cd8c6416c6c777904fb837b2021361c4f38Lang Hames Alignment = CGF.getContext().getDeclAlign(FirstField); 8065e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } 8075e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 8085e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames assert((CGF.getContext().toCharUnitsFromBits(FirstFieldOffset) % 8095e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment) == 0 && "Bad field alignment."); 81056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 81156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = getMemcpySize(); 81256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 81356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 81456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue DestLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 81556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 81656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 81756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 81856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 81956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 82056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddr() : Dest.getAddress(), 82156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Src.isBitField() ? Src.getBitFieldAddr() : Src.getAddress(), 82256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemcpySize, Alignment); 82356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 82456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 82656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void reset() { 82756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = 0; 82856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames protected: 83156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CodeGenFunction &CGF; 83256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXRecordDecl *ClassDecl; 83356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 83556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpyIR(llvm::Value *DestPtr, llvm::Value *SrcPtr, 83756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits Size, CharUnits Alignment) { 83856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); 83956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *DBP = 84056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), DPT->getAddressSpace()); 84156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DestPtr = CGF.Builder.CreateBitCast(DestPtr, DBP); 84256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); 84456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *SBP = 84556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), SPT->getAddressSpace()); 84656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, SBP); 84756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity(), 84956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Alignment.getQuantity()); 85056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 85156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 85256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addInitialField(FieldDecl *F) { 85356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 85456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 85556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 85656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FirstFieldOffset; 85756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 85856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 85956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 86056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 86156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addNextField(FieldDecl *F) { 86256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(F->getFieldIndex() == LastAddedFieldIndex + 1 && 86356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Cannot aggregate non-contiguous fields."); 86456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 86556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 86656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // The 'first' and 'last' fields are chosen by offset, rather than field 86756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // index. This allows the code to support bitfields, as well as regular 86856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // fields. 86956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 87056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FOffset < FirstFieldOffset) { 87156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 87256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = FOffset; 87356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (FOffset > LastFieldOffset) { 87456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 87556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FOffset; 87656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 87756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 87856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 87956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec; 88056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const ASTRecordLayout &RecLayout; 88156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *FirstField; 88256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *LastField; 88356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FirstFieldOffset, LastFieldOffset; 88456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastAddedFieldIndex; 88556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 88656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 88756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class ConstructorMemcpyizer : public FieldMemcpyizer { 88856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 88956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 89056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// Get source argument for copy constructor. Returns null if not a copy 89156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// constructor. 89256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD, 89356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) { 89456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (CD->isCopyOrMoveConstructor() && CD->isImplicitlyDefined()) 89556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Args[Args.size() - 1]; 89656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 89756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 89856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 89956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns true if a CXXCtorInitializer represents a member initialization 90056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // that can be rolled into a memcpy. 90156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 90256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!MemcpyableCtor) 90356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 90456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = MemberInit->getMember(); 90556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(Field != 0 && "No field for member init."); 90656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = Field->getType(); 90756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 90856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 90956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on non-POD, not-trivially-constructable members. 91056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(CE && CE->getConstructor()->isTrivial()) && 91156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 91256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldType->isReferenceType())) 91356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 91456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on volatile fields. 91656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!isMemcpyableField(Field)) 91756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 91856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Otherwise we're good. 92056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 92156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 92256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 92356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 92456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 92556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 92656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)), 92756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl(CD), 92856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemcpyableCtor(CD->isImplicitlyDefined() && 92956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CD->isCopyOrMoveConstructor() && 93056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getLangOpts().getGC() == LangOptions::NonGC), 93156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Args(Args) { } 93256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 93356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemberInitializer(CXXCtorInitializer *MemberInit) { 93456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (isMemberInitMemcpyable(MemberInit)) { 93556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.push_back(MemberInit); 93656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(MemberInit->getMember()); 93756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 93856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 93956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 94056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl, Args); 94156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 94256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 94356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 94456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedInits() { 94556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedInits.size() <= 1) { 94656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // This memcpy is too small to be worthwhile. Fall back on default 94756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // codegen. 94856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 94956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 95056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits[i], ConstructorDecl, Args); 95156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 95256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 95356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 95456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 95556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 95656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames pushEHDestructors(); 95756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 95856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.clear(); 95956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 96056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 96156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void pushEHDestructors() { 96256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 96356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 96456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 96556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 96656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 96756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = AggregatedInits[i]->getMember()->getType(); 96856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 96956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (CGF.needsEHCleanup(dtorKind)) 97056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 97156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 97456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 97556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 97656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 97856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 97956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXConstructorDecl *ConstructorDecl; 98056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool MemcpyableCtor; 98156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args; 98256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 98356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 98456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class AssignmentMemcpyizer : public FieldMemcpyizer { 98656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 98756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns the memcpyable field copied by the given statement, if one 98956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // exists. Otherwise r 99056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl* getMemcpyableField(Stmt *S) { 99156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!AssignmentsMemcpyable) 99256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 99356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 99456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Recognise trivial assignments. 99556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BO->getOpcode() != BO_Assign) 99656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 99756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 99856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 99956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 100056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 100156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 100256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 100356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Stmt *RHS = BO->getRHS(); 100456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 100556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RHS = EC->getSubExpr(); 100656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!RHS) 100756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 100856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS); 100956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field) 101056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 101156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 101256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 101356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 101456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(MD && (MD->isCopyAssignmentOperator() || 101556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isMoveAssignmentOperator()) && 101656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isTrivial())) 101756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 101856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 101956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!IOA) 102056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 102256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 102356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 102556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 102656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 102856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 102956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 103056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 103156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 103256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *DstPtr = CE->getArg(0); 103356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 103456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DstPtr = DC->getSubExpr(); 103556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 103656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!DUO || DUO->getOpcode() != UO_AddrOf) 103756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 103856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 103956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 104056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 104156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 104256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 104356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 104456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *SrcPtr = CE->getArg(1); 104556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 104656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = SC->getSubExpr(); 104756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 104856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!SUO || SUO->getOpcode() != UO_AddrOf) 104956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 105056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 105156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 105256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 105356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 105456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 105556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 105656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 105756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 105856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 105956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool AssignmentsMemcpyable; 106056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<Stmt*, 16> AggregatedStmts; 106156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 106256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 106356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 106456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 106556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 106656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 106756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 106856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(Args.size() == 2); 106956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 107056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 107156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAssignment(Stmt *S) { 107256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *F = getMemcpyableField(S); 107356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (F) { 107456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(F); 107556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.push_back(S); 107656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 107756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 107856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.EmitStmt(S); 107956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedStmts() { 108356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedStmts.size() <= 1) { 108456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedStmts.size(); ++i) 108556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.EmitStmt(AggregatedStmts[i]); 108656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 108756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 109056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.clear(); 109156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 109256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 109356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 109456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 109556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 109656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 109756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 109856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 109956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 1100607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 1101607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 1102607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 1103fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CXXCtorType CtorType, 1104fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 1105059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (CD->isDelegatingConstructor()) 1106059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return EmitDelegatingCXXConstructorCall(CD, Args); 1107059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1108607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 1109a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 11101d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 11111d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov E = CD->init_end(); 11121d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11131d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *BaseCtorContinueBB = 0; 11141d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (ClassDecl->getNumVBases() && 11151d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov !CGM.getTarget().getCXXABI().hasConstructorVariants()) { 11161d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // The ABIs that don't have constructor variants need to put a branch 11171d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // before the virtual base initialization code. 11181d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov BaseCtorContinueBB = CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this); 11191d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(BaseCtorContinueBB); 11201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11211d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11221d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Virtual base initializers first. 11231d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { 11241d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 11251d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11261d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (BaseCtorContinueBB) { 11281d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Complete object handler should continue to the remaining initializers. 11291d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Builder.CreateBr(BaseCtorContinueBB); 11301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBlock(BaseCtorContinueBB); 11311d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 11321d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 11331d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Then, non-virtual base initializers. 11341d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E && (*B)->isBaseInitializer(); B++) { 11351d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(!(*B)->isBaseVirtual()); 11361d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov EmitBaseInitializer(*this, ClassDecl, *B, CtorType); 1137607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1138607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1139603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson InitializeVTablePointers(ClassDecl); 1140a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 11411d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // And finally, initialize class members. 114256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer CM(*this, CD, Args); 11431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov for (; B != E; B++) { 11441d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorInitializer *Member = (*B); 11451d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(!Member->isBaseInitializer()); 11461d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(Member->isAnyMemberInitializer() && 11471d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "Delegating initializer on non-delegating constructor"); 11481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CM.addMemberInitializer(Member); 11491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 115056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CM.finish(); 1151607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1152607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1153adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1154adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 1155adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1156adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1157adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonHasTrivialDestructorBody(ASTContext &Context, 1158adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *BaseClassDecl, 1159adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl) 1160adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1161adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // If the destructor is trivial we don't have to check anything else. 1162adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1163adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1164adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1165adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 1166adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1167adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1168adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check fields. 1169adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(), 1170adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson E = BaseClassDecl->field_end(); I != E; ++I) { 1171581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *Field = *I; 1172adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1173adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1174adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1175adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1176adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1177adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check non-virtual bases. 1178adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 1179adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end(); 1180adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 1181adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (I->isVirtual()) 1182adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson continue; 1183adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1184adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *NonVirtualBase = 1185adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1186adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, NonVirtualBase, 1187adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1188adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1189adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1190adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1191adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl == MostDerivedClassDecl) { 1192adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check virtual bases. 1193adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 1194adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); 1195adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 1196adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *VirtualBase = 1197adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1198adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, VirtualBase, 1199adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1200adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1201adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1202adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1203adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1204adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1205adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1206adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1207adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1208adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, 1209adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field) 1210adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1211adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 1212adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1213adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 1214adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!RT) 1215adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1216adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1217adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1218adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 1219adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1220adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1221ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// CanSkipVTablePointerInitialization - Check whether we need to initialize 1222ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// any vtable pointers before calling this destructor. 1223ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlssonstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 1224e3d6cf2149beb1c215ea6e87023c27b4f37712adAnders Carlsson const CXXDestructorDecl *Dtor) { 1225ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!Dtor->hasTrivialBody()) 1226ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return false; 1227ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1228ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson // Check the fields. 1229ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1230ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1231ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 1232581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *Field = *I; 1233ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1234adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1235adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1236ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson } 1237ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1238ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return true; 1239ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson} 1240ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 12419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitDestructorBody - Emits the body of the current destructor. 12429fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 12439fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 12449fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXDtorType DtorType = CurGD.getDtorType(); 12459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 124650da2cadcc6da86abff6772de65280ace2cabc94John McCall // The call to operator delete in a deleting destructor happens 124750da2cadcc6da86abff6772de65280ace2cabc94John McCall // outside of the function-try-block, which means it's always 124850da2cadcc6da86abff6772de65280ace2cabc94John McCall // possible to delegate the destructor body to the complete 124950da2cadcc6da86abff6772de65280ace2cabc94John McCall // destructor. Do so. 125050da2cadcc6da86abff6772de65280ace2cabc94John McCall if (DtorType == Dtor_Deleting) { 125150da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Deleting); 125250da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 1253378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 125450da2cadcc6da86abff6772de65280ace2cabc94John McCall PopCleanupBlock(); 125550da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 125650da2cadcc6da86abff6772de65280ace2cabc94John McCall } 125750da2cadcc6da86abff6772de65280ace2cabc94John McCall 12589fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Dtor->getBody(); 12599fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 12609fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If the body is a function-try-block, enter the try before 126150da2cadcc6da86abff6772de65280ace2cabc94John McCall // anything else. 126250da2cadcc6da86abff6772de65280ace2cabc94John McCall bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 12639fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 126459a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 12659fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 126650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the epilogue cleanups. 126750da2cadcc6da86abff6772de65280ace2cabc94John McCall RunCleanupsScope DtorEpilogue(*this); 126850da2cadcc6da86abff6772de65280ace2cabc94John McCall 12699fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If this is the complete variant, just invoke the base variant; 12709fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // the epilogue will destruct the virtual bases. But we can't do 12719fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // this optimization if the body is a function-try-block, because 12729fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // we'd introduce *two* handler blocks. 127350da2cadcc6da86abff6772de65280ace2cabc94John McCall switch (DtorType) { 127450da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 127550da2cadcc6da86abff6772de65280ace2cabc94John McCall 127650da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Complete: 127750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for virtual bases. 127850da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Complete); 127950da2cadcc6da86abff6772de65280ace2cabc94John McCall 1280b8b2c9da87e7d70a1679db026f40548b3192b705John McCall if (!isTryBody && 1281b8b2c9da87e7d70a1679db026f40548b3192b705John McCall CGM.getContext().getTargetInfo().getCXXABI().hasDestructorVariants()) { 128250da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 1283378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 128450da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 128550da2cadcc6da86abff6772de65280ace2cabc94John McCall } 128650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Fallthrough: act like we're in the base variant. 12879fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 128850da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Base: 128950da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for fields and non-virtual bases. 129050da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Base); 129150da2cadcc6da86abff6772de65280ace2cabc94John McCall 129250da2cadcc6da86abff6772de65280ace2cabc94John McCall // Initialize the vtable pointers before entering the body. 1293ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 1294ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson InitializeVTablePointers(Dtor->getParent()); 12959fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 129650da2cadcc6da86abff6772de65280ace2cabc94John McCall if (isTryBody) 129750da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 129850da2cadcc6da86abff6772de65280ace2cabc94John McCall else if (Body) 129950da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(Body); 130050da2cadcc6da86abff6772de65280ace2cabc94John McCall else { 130150da2cadcc6da86abff6772de65280ace2cabc94John McCall assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 130250da2cadcc6da86abff6772de65280ace2cabc94John McCall // nothing to do besides what's in the epilogue 130350da2cadcc6da86abff6772de65280ace2cabc94John McCall } 13045abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // -fapple-kext must inline any call to this dtor into 13055abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // the caller's body. 13067edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (getLangOpts().AppleKext) 130772390b39c545426023ec104afe8706395d732badBill Wendling CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 130850da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 13099fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } 13109fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 131150da2cadcc6da86abff6772de65280ace2cabc94John McCall // Jump out through the epilogue cleanups. 131250da2cadcc6da86abff6772de65280ace2cabc94John McCall DtorEpilogue.ForceCleanup(); 13139fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 13149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Exit the try if applicable. 13159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 131659a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 13179fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 13189fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 131956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesvoid CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 132056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 132156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const Stmt *RootS = AssignOp->getBody(); 132256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(isa<CompoundStmt>(RootS) && 132356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Body of an implicit assignment operator should be compound stmt."); 132456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 132556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 132656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LexicalScope Scope(*this, RootCS->getSourceRange()); 132756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 132856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer AM(*this, AssignOp, Args); 132956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (CompoundStmt::const_body_iterator I = RootCS->body_begin(), 133056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames E = RootCS->body_end(); 133156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames I != E; ++I) { 133256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AM.emitAssignment(*I); 133356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 133456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AM.finish(); 133556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 133656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 133750da2cadcc6da86abff6772de65280ace2cabc94John McCallnamespace { 133850da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the operator delete associated with the current destructor. 13391f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallDtorDelete : EHScopeStack::Cleanup { 134050da2cadcc6da86abff6772de65280ace2cabc94John McCall CallDtorDelete() {} 134150da2cadcc6da86abff6772de65280ace2cabc94John McCall 1342ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 134350da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 134450da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = Dtor->getParent(); 134550da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 134650da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.getContext().getTagDeclType(ClassDecl)); 134750da2cadcc6da86abff6772de65280ace2cabc94John McCall } 134850da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 134950da2cadcc6da86abff6772de65280ace2cabc94John McCall 135059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov struct CallDtorDeleteConditional : EHScopeStack::Cleanup { 135159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldDeleteCondition; 135259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov public: 135359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 135459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov : ShouldDeleteCondition(ShouldDeleteCondition) { 135559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov assert(ShouldDeleteCondition != NULL); 135659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 135759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 135859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov void Emit(CodeGenFunction &CGF, Flags flags) { 135959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 136059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 136159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldCallDelete 136259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 136359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 136459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 136559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(callDeleteBB); 136659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 136759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXRecordDecl *ClassDecl = Dtor->getParent(); 136859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 136959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.getContext().getTagDeclType(ClassDecl)); 137059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateBr(continueBB); 137159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 137259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(continueBB); 137359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 137459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov }; 137559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 13769928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall class DestroyField : public EHScopeStack::Cleanup { 13779928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field; 1378516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne CodeGenFunction::Destroyer *destroyer; 13799928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray; 13809928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 13819928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall public: 13829928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 13839928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray) 1384516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne : field(field), destroyer(destroyer), 13859928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall useEHCleanupForArray(useEHCleanupForArray) {} 13869928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 1387ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 13889928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall // Find the address of the field. 13899928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall llvm::Value *thisValue = CGF.LoadCXXThis(); 1390377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 1391377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 1392377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue LV = CGF.EmitLValueForField(ThisLV, field); 13939928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall assert(LV.isSimple()); 13949928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 13959928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 1396ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall flags.isForNormalCleanup() && useEHCleanupForArray); 139750da2cadcc6da86abff6772de65280ace2cabc94John McCall } 139850da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 139950da2cadcc6da86abff6772de65280ace2cabc94John McCall} 140050da2cadcc6da86abff6772de65280ace2cabc94John McCall 1401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 1402607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 1403607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 140450da2cadcc6da86abff6772de65280ace2cabc94John McCallvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 140550da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXDtorType DtorType) { 1406607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 1407607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 1408607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 140950da2cadcc6da86abff6772de65280ace2cabc94John McCall // The deleting-destructor phase just needs to call the appropriate 141050da2cadcc6da86abff6772de65280ace2cabc94John McCall // operator delete that Sema picked up. 14113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Deleting) { 14123b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DD->getOperatorDelete() && 14133b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "operator delete missing - EmitDtorEpilogue"); 141459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (CXXStructorImplicitParamValue) { 141559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // If there is an implicit param to the deleting dtor, it's a boolean 141659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // telling whether we should call delete at the end of the dtor. 141759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDeleteConditional>( 141859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov NormalAndEHCleanup, CXXStructorImplicitParamValue); 141959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } else { 142059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 142159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 14223b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14233b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14243b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 142550da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = DD->getParent(); 142650da2cadcc6da86abff6772de65280ace2cabc94John McCall 1427416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith // Unions have no bases and do not call field destructors. 1428416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith if (ClassDecl->isUnion()) 1429416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith return; 1430416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith 143150da2cadcc6da86abff6772de65280ace2cabc94John McCall // The complete-destructor phase just destructs all the virtual bases. 14323b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Complete) { 143350da2cadcc6da86abff6772de65280ace2cabc94John McCall 143450da2cadcc6da86abff6772de65280ace2cabc94John McCall // We push them in the forward order so that they'll be popped in 143550da2cadcc6da86abff6772de65280ace2cabc94John McCall // the reverse order. 143650da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 143750da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); 14383b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall I != E; ++I) { 14393b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall const CXXBaseSpecifier &Base = *I; 14403b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall CXXRecordDecl *BaseClassDecl 14413b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 14423b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14433b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Ignore trivial destructors. 14443b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (BaseClassDecl->hasTrivialDestructor()) 14453b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall continue; 144650da2cadcc6da86abff6772de65280ace2cabc94John McCall 14471f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14481f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14491f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ true); 14503b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 145150da2cadcc6da86abff6772de65280ace2cabc94John McCall 14523b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14533b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14543b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14553b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DtorType == Dtor_Base); 145650da2cadcc6da86abff6772de65280ace2cabc94John McCall 145750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy non-virtual bases. 145850da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 145950da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 146050da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXBaseSpecifier &Base = *I; 146150da2cadcc6da86abff6772de65280ace2cabc94John McCall 146250da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore virtual bases. 146350da2cadcc6da86abff6772de65280ace2cabc94John McCall if (Base.isVirtual()) 146450da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 146550da2cadcc6da86abff6772de65280ace2cabc94John McCall 146650da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 146750da2cadcc6da86abff6772de65280ace2cabc94John McCall 146850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore trivial destructors. 146950da2cadcc6da86abff6772de65280ace2cabc94John McCall if (BaseClassDecl->hasTrivialDestructor()) 147050da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 14713b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14721f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14731f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14741f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ false); 147550da2cadcc6da86abff6772de65280ace2cabc94John McCall } 147650da2cadcc6da86abff6772de65280ace2cabc94John McCall 147750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy direct fields. 14785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const FieldDecl *, 16> FieldDecls; 1479607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1480607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 1481581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *field = *I; 14829928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType type = field->getType(); 14839928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 14849928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall if (!dtorKind) continue; 14859928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 14869a561d539158a30b68fc258b81a994f3fac10212Richard Smith // Anonymous union members do not have their destructors called. 14879a561d539158a30b68fc258b81a994f3fac10212Richard Smith const RecordType *RT = type->getAsUnionType(); 14889a561d539158a30b68fc258b81a994f3fac10212Richard Smith if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; 14899a561d539158a30b68fc258b81a994f3fac10212Richard Smith 14909928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CleanupKind cleanupKind = getCleanupKind(dtorKind); 14919928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall EHStack.pushCleanup<DestroyField>(cleanupKind, field, 14929928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall getDestroyer(dtorKind), 14939928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall cleanupKind & EHCleanup); 1494607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1495607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1496607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1497c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1498c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 149959174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor/// 1500c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1501c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayType the type of the array to initialize 1502c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin an arrayType* 1503c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1504c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 15053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1506c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1507c3c0766277cd64bf117450a1519c9cf762d994d4John McCall const ConstantArrayType *arrayType, 1508c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1509c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1510c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1511c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1512c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType elementType; 1513c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements = 1514c3c0766277cd64bf117450a1519c9cf762d994d4John McCall emitArrayLength(arrayType, elementType, arrayBegin); 1515c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1516c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1517c3c0766277cd64bf117450a1519c9cf762d994d4John McCall argBegin, argEnd, zeroInitialize); 15183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 15193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1520c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1521c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 1522c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// 1523c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1524c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param numElements the number of elements in the array; 1525dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall/// may be zero 1526c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin a T*, where T is the type constructed by ctor 1527c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1528c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 15293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1530c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1531c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements, 1532c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1533c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1534c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1535c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1536dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1537dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // It's legal for numElements to be zero. This can happen both 1538dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // dynamically, because x can be zero in 'new A[x]', and statically, 1539dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // because of GCC extensions that permit zero-length arrays. There 1540dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // are probably legitimate places where we could assume that this 1541dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // doesn't happen, but it's not clear that it's worth it. 1542dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BranchInst *zeroCheckBranch = 0; 1543dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1544dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Optimize for a constant count. 1545dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::ConstantInt *constantCount 1546dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall = dyn_cast<llvm::ConstantInt>(numElements); 1547dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount) { 1548dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Just skip out if the constant count is zero. 1549dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount->isZero()) return; 1550dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1551dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Otherwise, emit the check. 1552dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } else { 1553dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1554dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1555dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1556dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall EmitBlock(loopBB); 1557dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } 1558dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1559c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Find the end of the array. 1560c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1561c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.end"); 1562c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1563c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Enter the loop, setting up a phi for the current location to initialize. 1564c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1565c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1566c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(loopBB); 1567c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1568c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.cur"); 1569c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(arrayBegin, entryBB); 15703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 15713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 1572c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1573c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType type = getContext().getTypeDeclType(ctor->getParent()); 15743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 157559174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor // Zero initialize the storage, if requested. 1576c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (zeroInitialize) 1577c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitNullInitialization(cur, type); 157859174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor 15793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 15803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 15813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 15823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 15833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 15843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 15853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 15863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 158744ec82b4a1597802f5bf17721481b8c265bc8dc5Anders Carlsson { 1588f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 15893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1590c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Evaluate the constructor and its arguments in a regular 1591c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // partial-destroy cleanup. 15924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().Exceptions && 1593c3c0766277cd64bf117450a1519c9cf762d994d4John McCall !ctor->getParent()->hasTrivialDestructor()) { 1594c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Destroyer *destroyer = destroyCXXObject; 1595c3c0766277cd64bf117450a1519c9cf762d994d4John McCall pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1596c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 15973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1598c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1599378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, cur, argBegin, argEnd); 1600c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 16013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1602c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Go to the next element. 1603c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *next = 1604c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1605c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.next"); 1606c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(next, Builder.GetInsertBlock()); 16073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1608c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Check whether that's the end of the loop. 1609c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1610c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1611c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateCondBr(done, contBB, loopBB); 16123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1613dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Patch the earlier check to skip over the loop. 1614dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1615dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1616c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(contBB); 16173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 16183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1619bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1620bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall llvm::Value *addr, 1621bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall QualType type) { 1622bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const RecordType *rtype = type->castAs<RecordType>(); 1623bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1624bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXDestructorDecl *dtor = record->getDestructor(); 1625bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall assert(!dtor->isTrivial()); 1626bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1627378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, addr); 1628bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall} 1629bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall 16303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 16313b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1632155ed4a23366f4514befb1c9f5f89d16f8b8b6dbAnders Carlsson CXXCtorType Type, bool ForVirtualBase, 1633378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 16343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 16353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 16363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 16373ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 16383ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel CGDebugInfo *DI = getDebugInfo(); 16393a70cd6e1cc414856e41ce5509aa61c89bf472dcAlexey Samsonov if (DI && 16404cdad3151bfb2075c6bdbfe89fbb08f31a90a45bDouglas Gregor CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo) { 1641af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // If debug info for this class has not been emitted then this is the 1642af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // right time to do so. 16433ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel const CXXRecordDecl *Parent = D->getParent(); 16443ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel DI->getOrCreateRecordType(CGM.getContext().getTypeDeclType(Parent), 16453ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel Parent->getLocation()); 16463ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel } 16473ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 16481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // If this is a trivial constructor, just emit what's needed. 16498b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 16508b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 16518b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 16528b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 16538b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 16543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16568b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16578b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 165885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 165985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 16608b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16618b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 16628b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 16638b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 16648b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 16653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 16681d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Non-trivial constructors are handled in an ABI-specific manner. 166963fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren llvm::Value *Callee = CGM.getCXXABI().EmitConstructorCall(*this, D, Type, 167063fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren ForVirtualBase, Delegating, This, ArgBeg, ArgEnd); 167163fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren if (CGM.getCXXABI().HasThisReturn(CurGD) && 167263fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CGM.getCXXABI().HasThisReturn(GlobalDecl(D, Type))) 167363fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CalleeWithThisReturn = Callee; 16743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 16753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallvoid 167734999876e215b22febc240b1a6dc054215d12f9cFariborz JahanianCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 167834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *This, llvm::Value *Src, 167934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgBeg, 168034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgEnd) { 168134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian if (D->isTrivial()) { 168234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 168385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 168485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 168534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 168634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian return; 168734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 168834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, 168934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian clang::Ctor_Complete); 169034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(D->isInstance() && 169134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Trying to emit a member call expr on a static method!"); 169234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 169334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 169434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 169534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallArgList Args; 169634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 169734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the this ptr. 169804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(This), D->getThisType(getContext())); 169934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 170034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 170134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the src ptr. 170234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType QT = *(FPT->arg_type_begin()); 17032acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *t = CGM.getTypes().ConvertType(QT); 170434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian Src = Builder.CreateBitCast(Src, t); 170504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(Src), QT); 170634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 170734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Skip over first argument (Src). 170834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian ++ArgBeg; 170934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator Arg = ArgBeg; 171034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, 171134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian E = FPT->arg_type_end(); I != E; ++I, ++Arg) { 171234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(Arg != ArgEnd && "Running over edge of argument list!"); 1713413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, *I); 171434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 171534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Either we've emitted all the call args, or we have a call to a 171634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // variadic function. 171734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert((Arg == ArgEnd || FPT->isVariadic()) && 171834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Extra arguments in non-variadic function!"); 171934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // If we still have any arguments, emit them using the type of the argument. 172034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (; Arg != ArgEnd; ++Arg) { 172134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType ArgType = Arg->getType(); 1722413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, ArgType); 172334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 172434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 17250f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All), 17260f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Callee, ReturnValueSlot(), Args, D); 172734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian} 172834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 172934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanianvoid 1730c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1731c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CXXCtorType CtorType, 1732c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall const FunctionArgList &Args) { 1733c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CallArgList DelegateArgs; 1734c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1735c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1736c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "no parameters to constructor"); 1737c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1738c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // this 173904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1740c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1741c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1742c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // vtt 17431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (llvm::Value *VTT = GetVTTParameter(GlobalDecl(Ctor, CtorType), 1744378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1745378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true)) { 1746c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 174704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(VTT), VoidPP); 1748c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1749af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD)) { 1750c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "cannot skip vtt parameter, already done with args"); 1751d26bc76c98006609002d9930f8840490e88ac5b5John McCall assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1752c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1753c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1754c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1755c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1756c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Explicit arguments. 1757c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall for (; I != E; ++I) { 1758413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall const VarDecl *param = *I; 1759413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitDelegateCallArg(DelegateArgs, param); 1760c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1761c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 176263fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(Ctor, CtorType); 1763de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), 176463fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren Callee, ReturnValueSlot(), DelegateArgs, Ctor); 176563fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren if (CGM.getCXXABI().HasThisReturn(CurGD) && 176663fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CGM.getCXXABI().HasThisReturn(GlobalDecl(Ctor, CtorType))) 176763fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CalleeWithThisReturn = Callee; 1768c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 1769c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1770b76af9c969558b4484be87933e89e76e7ee87e21Sean Huntnamespace { 1771b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1772b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXDestructorDecl *Dtor; 1773b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt llvm::Value *Addr; 1774b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type; 1775b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1776b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1777b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type) 1778b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt : Dtor(D), Addr(Addr), Type(Type) {} 1779b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1780ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1781b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1782378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true, Addr); 1783b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1784b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt }; 1785b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1786b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1787059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Huntvoid 1788059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean HuntCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1789059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt const FunctionArgList &Args) { 1790059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt assert(Ctor->isDelegatingConstructor()); 1791059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1792059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt llvm::Value *ThisPtr = LoadCXXThis(); 1793059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1794f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman QualType Ty = getContext().getTagDeclType(Ctor->getParent()); 1795d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = getContext().getTypeAlignInChars(Ty); 1796f85e193739c953358c865005855253af4f68a497John McCall AggValueSlot AggSlot = 1797f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), 17987c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 1799410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 1800649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 1801059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1802059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1803059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1804b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXRecordDecl *ClassDecl = Ctor->getParent(); 18054e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1806b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type = 1807b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1808b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1809b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1810b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ClassDecl->getDestructor(), 1811b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ThisPtr, Type); 1812b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1813b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1814059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 18153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 18163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 18178e6404ca28d6bbb76e97ea2a53a74816c2a74665Anders Carlsson bool ForVirtualBase, 1818378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 18193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 18201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *VTT = GetVTTParameter(GlobalDecl(DD, Type), 1821378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor ForVirtualBase, Delegating); 1822ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian llvm::Value *Callee = 0; 18237edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (getLangOpts().AppleKext) 1824771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 1825771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian DD->getParent()); 1826ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian 1827ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (!Callee) 1828ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 18293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18304def70d3040e73707c738f7c366737a986135edfRichard Smith // FIXME: Provide a source location here. 18314def70d3040e73707c738f7c366737a986135edfRichard Smith EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This, 183259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov VTT, getContext().getPointerType(getContext().VoidPtrTy), 183359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 0, 0); 183463fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren if (CGM.getCXXABI().HasThisReturn(CurGD) && 183563fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CGM.getCXXABI().HasThisReturn(GlobalDecl(DD, Type))) 183663fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren CalleeWithThisReturn = Callee; 18373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 18383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1839291ae949612e371c41bf771a483b407d49372a4fJohn McCallnamespace { 18401f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallLocalDtor : EHScopeStack::Cleanup { 1841291ae949612e371c41bf771a483b407d49372a4fJohn McCall const CXXDestructorDecl *Dtor; 1842291ae949612e371c41bf771a483b407d49372a4fJohn McCall llvm::Value *Addr; 1843291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1844291ae949612e371c41bf771a483b407d49372a4fJohn McCall CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1845291ae949612e371c41bf771a483b407d49372a4fJohn McCall : Dtor(D), Addr(Addr) {} 1846291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1847ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1848291ae949612e371c41bf771a483b407d49372a4fJohn McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1849378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1850378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 1851291ae949612e371c41bf771a483b407d49372a4fJohn McCall } 1852291ae949612e371c41bf771a483b407d49372a4fJohn McCall }; 1853291ae949612e371c41bf771a483b407d49372a4fJohn McCall} 1854291ae949612e371c41bf771a483b407d49372a4fJohn McCall 185581407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCallvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 185681407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall llvm::Value *Addr) { 18571f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 185881407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall} 185981407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall 1860f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1861f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1862f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!ClassDecl) return; 1863f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ClassDecl->hasTrivialDestructor()) return; 1864f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1865f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1866642a75f883e644bcfbb82e7af0313776ad1ce33cJohn McCall assert(D && D->isUsed() && "destructor not marked as used!"); 186781407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall PushDestructorCleanup(D, Addr); 1868f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1869f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 18703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1871bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1872bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 18733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 1874043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); 187514c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck CharUnits VBaseOffsetOffset = 18761d2b31710539d705a3850c9fc3aa1804c2a5efeePeter Collingbourne CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); 18773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 187914c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 188014c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck "vbase.offset.ptr"); 18812acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 18823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 18833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 18853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 18863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 18883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 18903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 18913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1892d103f9f9b401b419e756f8c1849683cd77586067Anders Carlssonvoid 1893d103f9f9b401b419e756f8c1849683cd77586067Anders CarlssonCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1894b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1895d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1896d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson llvm::Constant *VTable, 1897d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson const CXXRecordDecl *VTableClass) { 1898c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 1899c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1900d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute the address point. 1901c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTableAddressPoint; 1902851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson 1903c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Check if we need to use a vtable from the VTT. 1904851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && 1905b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson (RD->getNumVBases() || NearestVBase)) { 1906c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Get the secondary vpointer index. 1907c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson uint64_t VirtualPointerIndex = 1908c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 1909c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1910c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson /// Load the VTT. 1911c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTT = LoadCXXVTT(); 1912c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson if (VirtualPointerIndex) 1913c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 1914c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1915c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // And load the address point from the VTT. 1916c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = Builder.CreateLoad(VTT); 1917c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } else { 191884fcc48817bb04c7de1acafcaa1f54ee3235a97bPeter Collingbourne uint64_t AddressPoint = 1919e09cdf46aa2b86c24e6bf7a7ead2eaded964f2ffPeter Collingbourne CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base); 1920c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = 1921d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); 1922c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } 1923d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1924d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute where to store the address point. 19258246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VirtualOffset = 0; 19269a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtualOffset = CharUnits::Zero(); 19273e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson 19283e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { 19293e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // We need to use the virtual base offset offset because the virtual base 19303e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // might have a different offset in the most derived class. 19318246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, 19328246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NearestVBase); 1933d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck NonVirtualOffset = OffsetFromNearestVBase; 19343e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } else { 19358246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // We can just use the base offset in the complete class. 19364230d529a8797bbeef2328b60abeae333f7e143fKen Dyck NonVirtualOffset = Base.getBaseOffset(); 19373e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } 19388246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 19398246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // Apply the offsets. 19408246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VTableField = LoadCXXThis(); 19418246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 19429a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtualOffset.isZero() || VirtualOffset) 19438246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 19448246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NonVirtualOffset, 19458246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset); 194636fd6beef1ffaf93217d8ce96d900d4ed817e463Anders Carlsson 1947d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Finally, store the address point. 19482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *AddressPointPtrTy = 1949d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableAddressPoint->getType()->getPointerTo(); 1950d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 19518cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 19528cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); 1953d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 1954d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1955603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid 1956603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders CarlssonCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1957b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1958d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1959603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson bool BaseIsNonVirtualPrimaryBase, 1960603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable, 1961603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *VTableClass, 1962603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy& VBases) { 1963603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // If this base is a non-virtual primary base the address point has already 1964603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // been set. 1965603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseIsNonVirtualPrimaryBase) { 1966603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointer for this base. 19674235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 19684235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson VTable, VTableClass); 1969603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 19704658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1971603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 19724658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1973603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Traverse bases. 1974603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1975603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson E = RD->bases_end(); I != E; ++I) { 19760703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson CXXRecordDecl *BaseDecl 19770703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1978603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1979603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 1980603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseDecl->isDynamicClass()) 1981603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1982603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1983d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffset; 1984d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffsetFromNearestVBase; 198514da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson bool BaseDeclIsNonVirtualPrimaryBase; 1986603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1987603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (I->isVirtual()) { 1988603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Check if we've visited this virtual base before. 1989603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!VBases.insert(BaseDecl)) 1990603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1991603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1992603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = 1993603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson getContext().getASTRecordLayout(VTableClass); 1994603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1995d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1996d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffsetFromNearestVBase = CharUnits::Zero(); 199714da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = false; 1998603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } else { 1999603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 2000603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 20014230d529a8797bbeef2328b60abeae333f7e143fKen Dyck BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 20024235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase = 2003d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 200414da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 2005603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 20060703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson 20074230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 2008b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson I->isVirtual() ? BaseDecl : NearestVBase, 20094235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase, 201014da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase, 2011603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, VTableClass, VBases); 20123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 20133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 20143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 2015603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 2016603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 20170703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson if (!RD->isDynamicClass()) 20183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 20193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 2020603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Get the VTable. 2021603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD); 20223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 2023603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointers for this class and all of its bases. 2024603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy VBases; 20254230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 20264230d529a8797bbeef2328b60abeae333f7e143fKen Dyck /*NearestVBase=*/0, 2027d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck /*OffsetFromNearestVBase=*/CharUnits::Zero(), 2028603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson /*BaseIsNonVirtualPrimaryBase=*/false, 2029603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, RD, VBases); 20303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 2031043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman 2032043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohmanllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 20332acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty) { 2034043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 20358cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 20368cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr()); 20378cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany return VTable; 2038043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman} 2039a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2040a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { 2041a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const Expr *E = Base; 2042a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2043a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 2044a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = E->IgnoreParens(); 2045a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 2046a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_DerivedToBase || 2047a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_UncheckedDerivedToBase || 2048a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_NoOp) { 2049a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 2050a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2051a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2052a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2053a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2054a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson break; 2055a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2056a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2057a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson QualType DerivedType = E->getType(); 2058a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const PointerType *PTy = DerivedType->getAs<PointerType>()) 2059a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson DerivedType = PTy->getPointeeType(); 2060a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2061a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return cast<CXXRecordDecl>(DerivedType->castAs<RecordType>()->getDecl()); 2062a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2063a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2064a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 2065a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// quite what we want. 2066a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 2067a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 2068a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 2069a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = PE->getSubExpr(); 2070a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2071a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2072a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2073a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 2074a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_NoOp) { 2075a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 2076a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2077a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2078a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2079a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 2080a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UO->getOpcode() == UO_Extension) { 2081a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = UO->getSubExpr(); 2082a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2083a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2084a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2085a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return E; 2086a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2087a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2088a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2089a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// canDevirtualizeMemberFunctionCall - Checks whether the given virtual member 2090a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// function call on the given expr can be devirtualized. 2091a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool canDevirtualizeMemberFunctionCall(const Expr *Base, 2092a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 2093a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the most derived class is marked final, we know that no subclass can 2094a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // override this member function and so we can devirtualize it. For example: 2095a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2096a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct A { virtual void f(); } 2097a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct B final : A { }; 2098a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2099a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // void f(B *b) { 2100a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // b->f(); 2101a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // } 2102a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2103a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base); 2104a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 2105a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2106a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2107a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the member function is marked 'final', we know that it can't be 2108a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // overridden and can therefore devirtualize it. 2109a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->hasAttr<FinalAttr>()) 2110a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2111a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2112a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Similarly, if the class itself is marked 'final' it can't be overridden 2113a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // and we can therefore devirtualize the member function call. 2114a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->getParent()->hasAttr<FinalAttr>()) 2115a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2116a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2117a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson Base = skipNoOpCastsAndParens(Base); 2118a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 2119a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 2120a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // This is a record decl. We know the type and can devirtualize it. 2121a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return VD->getType()->isRecordType(); 2122a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2123a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2124a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2125a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2126a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2127a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can always devirtualize calls on temporary object expressions. 2128a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXConstructExpr>(Base)) 2129a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2130a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2131a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // And calls on bound temporaries. 2132a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXBindTemporaryExpr>(Base)) 2133a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2134a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2135a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Check if this is a call expr that returns a record type. 2136a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 2137a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CE->getCallReturnType()->isRecordType(); 2138a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2139a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can't devirtualize the call. 2140a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2141a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2142a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2143a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool UseVirtualCall(ASTContext &Context, 2144a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXOperatorCallExpr *CE, 2145a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 2146a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (!MD->isVirtual()) 2147a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2148a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2149a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // When building with -fapple-kext, all calls must go through the vtable since 2150a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // the kernel linker can do runtime patching of vtables. 21514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context.getLangOpts().AppleKext) 2152a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2153a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2154a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD); 2155a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2156a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2157a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonllvm::Value * 2158a2447e0d1e28669cd637204a871f15b1215277fdAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 2159a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD, 2160a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson llvm::Value *This) { 2161de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnType = 2162de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().GetFunctionType( 2163de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(MD)); 2164a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2165a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UseVirtualCall(getContext(), E, MD)) 2166de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return BuildVirtualCall(MD, This, fnType); 2167a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2168de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return CGM.GetAddrOfFunction(MD, fnType); 2169a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2170bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman 21710f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallvoid CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda, 21720f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CallArgList &callArgs) { 217364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Lookup the call operator 21740f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall DeclarationName operatorName 217521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman = getContext().DeclarationNames.getCXXOperatorName(OO_Call); 21760f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CXXMethodDecl *callOperator = 21773bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie cast<CXXMethodDecl>(lambda->lookup(operatorName).front()); 217821f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 217921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Get the address of the call operator. 21800f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const CGFunctionInfo &calleeFnInfo = 21810f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 21820f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall llvm::Value *callee = 21830f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.GetAddrOfFunction(GlobalDecl(callOperator), 21840f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().GetFunctionType(calleeFnInfo)); 21850f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Prepare the return slot. 21870f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const FunctionProtoType *FPT = 21880f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callOperator->getType()->castAs<FunctionProtoType>(); 21890f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall QualType resultType = FPT->getResultType(); 21900f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ReturnValueSlot returnSlot; 21910f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && 21920f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 21939d232c884ea9872d6555df0fd7359699819bc1f1John McCall !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) 21940f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); 21950f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // We don't need to separately arrange the call arguments because 21970f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // the call can't be variadic anyway --- it's impossible to forward 21980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // variadic arguments. 219921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 220021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Now emit our call. 22010f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, 22020f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callArgs, callOperator); 220321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 22040f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // If necessary, copy the returned value into the slot. 22050f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && returnSlot.isNull()) 22060f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitReturnOfRValue(RV, resultType); 220750f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman else 220850f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman EmitBranchThroughCleanup(ReturnBlock); 220921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman} 221021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 221164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaBlockInvokeBody() { 221264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const BlockDecl *BD = BlockInfo->getBlockDecl(); 221364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const VarDecl *variable = BD->capture_begin()->getVariable(); 221464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 221564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 221664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 221764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 221864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 221964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 222064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = GetAddrOfBlockDecl(variable, false); 222164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 222264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 222364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 222464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (BlockDecl::param_const_iterator I = BD->param_begin(), 222564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = BD->param_end(); I != E; ++I) { 222664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 222764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 222864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 222964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 223064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 223164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 223264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 223364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { 223464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman if (cast<CXXMethodDecl>(CurFuncDecl)->isVariadic()) { 223564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // FIXME: Making this work correctly is nasty because it requires either 223664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // cloning the body of the call operator or making the call operator forward. 223764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CGM.ErrorUnsupported(CurFuncDecl, "lambda conversion to variadic function"); 223864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 223964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 224064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 224164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitFunctionBody(Args); 224264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 224364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 224464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 224564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = MD->getParent(); 224664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 224764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 224864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 224964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 225064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 225164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 225264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 225364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 225464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 225564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (FunctionDecl::param_const_iterator I = MD->param_begin(), 225664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = MD->param_end(); I != E; ++I) { 225764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 225864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 225964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 226064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 226164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 226264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 226364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 226427dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregorvoid CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { 226527dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor if (MD->isVariadic()) { 226621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // FIXME: Making this work correctly is nasty because it requires either 226721f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // cloning the body of the call operator or making the call operator forward. 226821f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 226964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 227021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman } 227121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 227227dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor EmitLambdaDelegatingInvokeBody(MD); 2273bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman} 2274