CGClass.cpp revision 5e8577ece79b5ed07b0ab4dcb284a26076efdf65
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" 182f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 197e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "clang/AST/EvaluatedExprVisitor.h" 205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "clang/AST/StmtCXX.h" 2256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#include "clang/Basic/TargetBuiltins.h" 233ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include "clang/Frontend/CodeGenOptions.h" 242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 275d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 2855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyckstatic CharUnits 2934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, 3034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *DerivedClass, 31f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start, 32f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator End) { 3355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = CharUnits::Zero(); 3434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *RD = DerivedClass; 3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 37f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXBaseSpecifier *Base = *I; 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson assert(!Base->isVirtual() && "Should not see virtual bases here!"); 4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the layout. 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *BaseDecl = 4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Add the offset. 4855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RD = BaseDecl; 5134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return Offset; 5434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 555d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 5684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 57a04efdf635d35d88e65041fad007225d8c8d64a5Anders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 58f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 59f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd) { 60f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 61a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = 63f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 64f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall PathBegin, PathEnd); 6555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (Offset.isZero()) 66a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson return 0; 67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 682acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 69a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 70a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 7155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 7284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 748561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// Gets the address of a direct base class within a complete object. 75bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 76bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 77bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 78bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 79bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 808561a8666c70f924c8f0209c41b9b77bbbf90607Anders CarlssonCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 818561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 828561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Base, 838561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson bool BaseIsVirtual) { 84bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 905fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck CharUnits Offset; 91bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 928561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (BaseIsVirtual) 935fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getVBaseClassOffset(Base); 94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 955fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getBaseClassOffset(Base); 96bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 98bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 1005fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck if (Offset.isPositive()) { 101bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1025fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); 103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall } 104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 105bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall return V; 107d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1099dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlssonstatic llvm::Value * 1107916c997127fe616ba255ba4cade10e5de0c8812John McCallApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ptr, 1117916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits nonVirtualOffset, 1127916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *virtualOffset) { 1137916c997127fe616ba255ba4cade10e5de0c8812John McCall // Assert that we have something to do. 1147916c997127fe616ba255ba4cade10e5de0c8812John McCall assert(!nonVirtualOffset.isZero() || virtualOffset != 0); 1157916c997127fe616ba255ba4cade10e5de0c8812John McCall 1167916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the offset from the static and dynamic components. 1177916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *baseOffset; 1187916c997127fe616ba255ba4cade10e5de0c8812John McCall if (!nonVirtualOffset.isZero()) { 1197916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy, 1207916c997127fe616ba255ba4cade10e5de0c8812John McCall nonVirtualOffset.getQuantity()); 1217916c997127fe616ba255ba4cade10e5de0c8812John McCall if (virtualOffset) { 1227916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 1237916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1247916c997127fe616ba255ba4cade10e5de0c8812John McCall } else { 1257916c997127fe616ba255ba4cade10e5de0c8812John McCall baseOffset = virtualOffset; 1267916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1279dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1289dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson // Apply the base offset. 1297916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy); 1307916c997127fe616ba255ba4cade10e5de0c8812John McCall ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr"); 1317916c997127fe616ba255ba4cade10e5de0c8812John McCall return ptr; 1329dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson} 1339dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1345d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 13534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 1368561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 137f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 138f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 13934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson bool NullCheckValue) { 140f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 14134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 142f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start = PathBegin; 14334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *VBase = 0; 14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1457916c997127fe616ba255ba4cade10e5de0c8812John McCall // Sema has done some convenient canonicalization here: if the 1467916c997127fe616ba255ba4cade10e5de0c8812John McCall // access path involved any virtual steps, the conversion path will 1477916c997127fe616ba255ba4cade10e5de0c8812John McCall // *start* with a step down to the correct virtual base subobject, 1487916c997127fe616ba255ba4cade10e5de0c8812John McCall // and hence will not require any further steps. 14934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if ((*Start)->isVirtual()) { 15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VBase = 15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson ++Start; 15334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 1547916c997127fe616ba255ba4cade10e5de0c8812John McCall 1557916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the static offset of the ultimate destination within its 1567916c997127fe616ba255ba4cade10e5de0c8812John McCall // allocating subobject (the virtual base, if there is one, or else 1577916c997127fe616ba255ba4cade10e5de0c8812John McCall // the "complete" object that we see). 15855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits NonVirtualOffset = 1598561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 160f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall Start, PathEnd); 16134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1627916c997127fe616ba255ba4cade10e5de0c8812John McCall // If there's a virtual step, we can sometimes "devirtualize" it. 1637916c997127fe616ba255ba4cade10e5de0c8812John McCall // For now, that's limited to when the derived type is final. 1647916c997127fe616ba255ba4cade10e5de0c8812John McCall // TODO: "devirtualize" this for accesses to known-complete objects. 1657916c997127fe616ba255ba4cade10e5de0c8812John McCall if (VBase && Derived->hasAttr<FinalAttr>()) { 1667916c997127fe616ba255ba4cade10e5de0c8812John McCall const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 1677916c997127fe616ba255ba4cade10e5de0c8812John McCall CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 1687916c997127fe616ba255ba4cade10e5de0c8812John McCall NonVirtualOffset += vBaseOffset; 1697916c997127fe616ba255ba4cade10e5de0c8812John McCall VBase = 0; // we no longer have a virtual step 1707916c997127fe616ba255ba4cade10e5de0c8812John McCall } 1717916c997127fe616ba255ba4cade10e5de0c8812John McCall 17234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the base pointer type. 1732acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtrTy = 174f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ConvertType((PathEnd[-1])->getType())->getPointerTo(); 1757916c997127fe616ba255ba4cade10e5de0c8812John McCall 1767916c997127fe616ba255ba4cade10e5de0c8812John McCall // If the static offset is zero and we don't have a virtual step, 1777916c997127fe616ba255ba4cade10e5de0c8812John McCall // just do a bitcast; null checks are unnecessary. 17855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (NonVirtualOffset.isZero() && !VBase) { 17934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 1817916c997127fe616ba255ba4cade10e5de0c8812John McCall 1827916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *origBB = 0; 1837916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *endBB = 0; 18434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1857916c997127fe616ba255ba4cade10e5de0c8812John McCall // Skip over the offset (and the vtable load) if we're supposed to 1867916c997127fe616ba255ba4cade10e5de0c8812John McCall // null-check the pointer. 18734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 1887916c997127fe616ba255ba4cade10e5de0c8812John McCall origBB = Builder.GetInsertBlock(); 1897916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 1907916c997127fe616ba255ba4cade10e5de0c8812John McCall endBB = createBasicBlock("cast.end"); 19134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1927916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::Value *isNull = Builder.CreateIsNull(Value); 1937916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateCondBr(isNull, endBB, notNullBB); 1947916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(notNullBB); 19534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 19634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1977916c997127fe616ba255ba4cade10e5de0c8812John McCall // Compute the virtual offset. 19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::Value *VirtualOffset = 0; 199336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (VBase) { 2007916c997127fe616ba255ba4cade10e5de0c8812John McCall VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); 201336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } 20234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2037916c997127fe616ba255ba4cade10e5de0c8812John McCall // Apply both offsets. 20455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 2059a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset, 20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VirtualOffset); 20734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2087916c997127fe616ba255ba4cade10e5de0c8812John McCall // Cast to the destination type. 20934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 2107916c997127fe616ba255ba4cade10e5de0c8812John McCall 2117916c997127fe616ba255ba4cade10e5de0c8812John McCall // Build a phi if we needed a null check. 21234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 2137916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 2147916c997127fe616ba255ba4cade10e5de0c8812John McCall Builder.CreateBr(endBB); 2157916c997127fe616ba255ba4cade10e5de0c8812John McCall EmitBlock(endBB); 21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2177916c997127fe616ba255ba4cade10e5de0c8812John McCall llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); 2187916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(Value, notNullBB); 2197916c997127fe616ba255ba4cade10e5de0c8812John McCall PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); 22034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = PHI; 22134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 22234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Value; 22434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 22534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonllvm::Value * 227a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 2288561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 229f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 232f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 233a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 2358561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 2362acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 237c764830bdb6de82baed068889096bd3e52d4cbdaRichard Smith 238a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 239f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 240a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 241a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 242a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 243a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 244a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 245a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 255b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 260a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 261c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateBitCast(Value, Int8PtrTy); 262c5685438df6105052b02c9e02f01c34489606308Eli Friedman Value = Builder.CreateGEP(Value, Builder.CreateNeg(NonVirtualOffset), 263c5685438df6105052b02c9e02f01c34489606308Eli Friedman "sub.ptr"); 264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 268a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 274bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 27732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 278a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 27932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2805d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 281a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2825d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 28321c9ad9d29d08a287292c670e7c52bc522c7f8bbAnders Carlsson 284c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a 285c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases. 286314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, 287378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool ForVirtualBase, 288378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating) { 289af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (!CodeGenVTables::needsVTTParameter(GD)) { 290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 291c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 292c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 293c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 294c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); 295c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2963b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 297c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 298c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall uint64_t SubVTTIndex; 3003b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 301378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor if (Delegating) { 302378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If this is a delegating constructor call, just load the VTT. 303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor return CGF.LoadCXXVTT(); 304378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor } else if (RD == Base) { 305378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // If the record matches the base, this is the complete ctor/dtor 306378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor // variant calling the base variant in a class with virtual bases. 307af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson assert(!CodeGenVTables::needsVTTParameter(CGF.CurGD) && 3083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "doing no-op VTT offset in base dtor/ctor?"); 309314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson assert(!ForVirtualBase && "Can't have same class as virtual base!"); 3103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall SubVTTIndex = 0; 3113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } else { 312c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson const ASTRecordLayout &Layout = 313c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.getContext().getASTRecordLayout(RD); 3144230d529a8797bbeef2328b60abeae333f7e143fKen Dyck CharUnits BaseOffset = ForVirtualBase ? 3154230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getVBaseClassOffset(Base) : 3164230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getBaseClassOffset(Base); 317c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 318c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson SubVTTIndex = 319c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 3203b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 3213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 323af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) { 324c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 325c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.LoadCXXVTT(); 326c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 327c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 328c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 3291cbce125b91cad81c8be3f8bbae8df917211176cAnders Carlsson VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD); 330c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 331c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 332c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 333c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 334c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 335c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 336182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 33750da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the destructor for a direct base class. 3381f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallBaseDtor : EHScopeStack::Cleanup { 33950da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *BaseClass; 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall bool BaseIsVirtual; 34150da2cadcc6da86abff6772de65280ace2cabc94John McCall CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 34250da2cadcc6da86abff6772de65280ace2cabc94John McCall : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 343182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 344ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 34550da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *DerivedClass = 34650da2cadcc6da86abff6772de65280ace2cabc94John McCall cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 34750da2cadcc6da86abff6772de65280ace2cabc94John McCall 34850da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *D = BaseClass->getDestructor(); 34950da2cadcc6da86abff6772de65280ace2cabc94John McCall llvm::Value *Addr = 35050da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 35150da2cadcc6da86abff6772de65280ace2cabc94John McCall DerivedClass, BaseClass, 35250da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseIsVirtual); 353378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 354378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 355182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 356182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// A visitor which checks whether an initializer uses 'this' in a 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// way which requires the vtable to be properly set. 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool UsesThis; 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3677e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Black-list all explicit and implicit references to 'this'. 3687e1dff7a68a4d00e71debafa7f5c259473091746John McCall // 3697e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Do we need to worry about external references to 'this' derived 3707e1dff7a68a4d00e71debafa7f5c259473091746John McCall // from arbitrary code? If so, then anything which runs arbitrary 3717e1dff7a68a4d00e71debafa7f5c259473091746John McCall // external code might potentially access the vtable. 3727e1dff7a68a4d00e71debafa7f5c259473091746John McCall void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 3737e1dff7a68a4d00e71debafa7f5c259473091746John McCall }; 3747e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3757e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3767e1dff7a68a4d00e71debafa7f5c259473091746John McCallstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 3777e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker Checker(C); 3787e1dff7a68a4d00e71debafa7f5c259473091746John McCall Checker.Visit(const_cast<Expr*>(Init)); 3797e1dff7a68a4d00e71debafa7f5c259473091746John McCall return Checker.UsesThis; 380182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 381182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 384cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *BaseInit, 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 39580638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson bool isBaseVirtual = BaseInit->isBaseVirtual(); 396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 4017e1dff7a68a4d00e71debafa7f5c259473091746John McCall // If the initializer for the base (other than the constructor 4027e1dff7a68a4d00e71debafa7f5c259473091746John McCall // itself) accesses 'this' in any way, we need to initialize the 4037e1dff7a68a4d00e71debafa7f5c259473091746John McCall // vtables. 4047e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 4057e1dff7a68a4d00e71debafa7f5c259473091746John McCall CGF.InitializeVTablePointers(ClassDecl); 4067e1dff7a68a4d00e71debafa7f5c259473091746John McCall 407bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 408bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 4098561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson llvm::Value *V = 4108561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 41150da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseClassDecl, 41250da2cadcc6da86abff6772de65280ace2cabc94John McCall isBaseVirtual); 413d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = CGF.getContext().getTypeAlignInChars(BaseType); 4147c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot AggSlot = 415f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(V, Alignment, Qualifiers(), 4167c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 417410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 418649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 419558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 420558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 421594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 4224e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGF.CGM.getLangOpts().Exceptions && 423c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson !BaseClassDecl->hasTrivialDestructor()) 4241f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 4251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall isBaseVirtual); 426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 428fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregorstatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue LHS, 4300bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Expr *Init, 431fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar, 432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType T, 4330bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes, 434fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned Index) { 4350bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Index == ArrayIndexes.size()) { 436f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman LValue LV = LHS; 437924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl { // Scope for Cleanups. 438924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CodeGenFunction::RunCleanupsScope Cleanups(CGF); 439924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 440924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (ArrayIndexVar) { 441924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // If we have an array index variable, load it and use it as an offset. 442924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Then, increment the value. 443924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Dest = LHS.getAddress(); 444924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 445924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 446924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 447924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 448924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.Builder.CreateStore(Next, ArrayIndexVar); 449924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 450924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Update the LValue. 451924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAddress(Dest); 452924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CharUnits Align = CGF.getContext().getTypeAlignInChars(T); 453924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAlignment(std::min(Align, LV.getAlignment())); 454924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 455924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 456924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (!CGF.hasAggregateLLVMType(T)) { 457924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); 458924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else if (T->isAnyComplexType()) { 459924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(), 460924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.isVolatileQualified()); 461924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else { 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); 469924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 470fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 471558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 472924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Now, outside of the initializer cleanup scope, destroy the backing array 473924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // for a std::initializer_list member. 474972edf0534d8a50f87fac1d0ff34eb22f593df11Sebastian Redl CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init); 475924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 476fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 477fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(Array && "Array initialization without the array type?"); 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IndexVar 4820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]); 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(IndexVar && "Array index variable not loaded"); 484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Initialize this index variable to zero. 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value* Zero 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = llvm::Constant::getNullValue( 488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.ConvertType(CGF.getContext().getSizeType())); 489fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, IndexVar); 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Start the loop with a block that tests the condition. 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(CondBlock); 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Generate: if (loop-index < number-of-elements) fall to the loop body, 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // otherwise, go to the block after the for-loop. 500fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor uint64_t NumElements = Array->getSize().getZExtValue(); 501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 502985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::Value *NumElementsPtr = 503985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::ConstantInt::get(Counter->getType(), NumElements); 504fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 505fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "isless"); 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If the condition is true, execute the body. 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ForBody); 511fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 512fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 513fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor { 514f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope Cleanups(CGF); 515fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 516fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Inside the loop body recurse to emit the inner loop or, eventually, the 517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // constructor call. 5180bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, 5190bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Array->getElementType(), ArrayIndexes, Index + 1); 520fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 521fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 522fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ContinueBlock); 523fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 524fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the increment of the loop counter. 525fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 526fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Counter = CGF.Builder.CreateLoad(IndexVar); 527fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 528fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(NextVal, IndexVar); 529fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 530fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Finally, branch back up to the condition for the next iteration. 531fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBranch(CondBlock); 532fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 533fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the fall-through block. 534fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(AfterFor, true); 535fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor} 536182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 539cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 540fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const CXXConstructorDecl *Constructor, 541fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 54200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet assert(MemberInit->isAnyMemberInitializer() && 543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 5447a614d8380297fcd2bc23986241905d97222948cRichard Smith assert(MemberInit->getInit() && "Must have initializer!"); 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 54700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldDecl *Field = MemberInit->getAnyMember(); 5480bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 551377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 552859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 553377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman 55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (MemberInit->isIndirectMemberInitializer()) { 555859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // If we are initializing an anonymous union field, drill down to 556859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman // the field. 557859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 558859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(), 559859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman IEnd = IndirectField->chain_end(); 560859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman for ( ; I != IEnd; ++I) 561859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I)); 56200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 563a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall } else { 564859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 5670bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Special case: if we are in a copy or move constructor, and we are copying 5680bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // an array of PODs or classes with trivial copy constructors, ignore the 5690bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // AST and perform the copy we know is equivalent. 5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // FIXME: This is hacky at best... if we had a bit more explicit information 5710bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // in the AST, we could generalize it more easily. 5720bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman const ConstantArrayType *Array 5730bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.getContext().getAsConstantArrayType(FieldType); 5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Array && Constructor->isImplicitlyDefined() && 5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Constructor->isCopyOrMoveConstructor()) { 5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 577e9385363069388d8e3536052a138f17332e00620Richard Smith CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 5780bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (BaseElementTy.isPODType(CGF.getContext()) || 579e9385363069388d8e3536052a138f17332e00620Richard Smith (CE && CE->getConstructor()->isTrivial())) { 580e9385363069388d8e3536052a138f17332e00620Richard Smith // Find the source pointer. We know it's the last argument because 581e9385363069388d8e3536052a138f17332e00620Richard Smith // we know we're in an implicit copy constructor. 5820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned SrcArgIndex = Args.size() - 1; 5830bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman llvm::Value *SrcPtr 5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 585377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 586377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 5870bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5880bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Copy the aggregate. 5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 590649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier LHS.isVolatileQualified()); 5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman return; 5920bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5930bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5940bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5950bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes; 5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (MemberInit->getNumArrayIndices()) 5970bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes = MemberInit->getArrayIndexes(); 598b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes); 5990bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman} 6000bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 601b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid CodeGenFunction::EmitInitializerForField(FieldDecl *Field, 602b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LValue LHS, Expr *Init, 603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayRef<VarDecl *> ArrayIndexes) { 6040bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 605b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman if (!hasAggregateLLVMType(FieldType)) { 606f85e193739c953358c865005855253af4f68a497John McCall if (LHS.isSimple()) { 607b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitExprAsInit(Init, Field, LHS, false); 608f85e193739c953358c865005855253af4f68a497John McCall } else { 609b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman RValue RHS = RValue::get(EmitScalarExpr(Init)); 610b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitStoreThroughLValue(RHS, LHS); 611f85e193739c953358c865005855253af4f68a497John McCall } 6120bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } else if (FieldType->isAnyComplexType()) { 613b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitComplexExprIntoAddr(Init, LHS.getAddress(), LHS.isVolatileQualified()); 614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 615fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar = 0; 6160bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (ArrayIndexes.size()) { 617b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 618fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 619fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // The LHS is a pointer to the first object we'll be constructing, as 620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // a flat array. 621b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman QualType BaseElementTy = getContext().getBaseElementType(FieldType); 622b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *BasePtr = ConvertType(BaseElementTy); 623fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr = llvm::PointerType::getUnqual(BasePtr); 624b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), 625b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman BasePtr); 626b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy); 627fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 628fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Create an array index that will be used to walk over all of the 629fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // objects we're constructing. 630b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index"); 631fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 632b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman Builder.CreateStore(Zero, ArrayIndexVar); 633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 634fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 635fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the block variables for the array indices, if any. 6360bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I) 637b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAutoVarDecl(*ArrayIndexes[I]); 638fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 639fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 640b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, 6410bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes, 0); 642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 643074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall 644074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // Ensure that we destroy this object if an exception is thrown 645074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall // later in the constructor. 646074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 647074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall if (needsEHCleanup(dtorKind)) 648074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 651c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Checks whether the given constructor is a valid subject for the 652c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// complete-to-base constructor delegation optimization, i.e. 653c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// emitting the complete constructor as a simple call to the base 654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// constructor. 655c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallstatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 656c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Currently we disable the optimization for classes with virtual 658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // bases because (1) the addresses of parameter variables need to be 659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // consistent across all initializers but (2) the delegate function 660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // call necessarily creates a second copy of the parameter variable. 661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // The limiting example (purely theoretical AFAIK): 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct A { A(int &c) { c++; } }; 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct B : virtual A { 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // B(int count) : A(count) { printf("%d\n", count); } 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // }; 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // ...although even this example could in principle be emitted as a 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation since the address of the parameter doesn't escape. 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getParent()->getNumVBases()) { 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list trivial vbase initializers. This case wouldn't 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // be subject to the restrictions below. 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list cases where: 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - there are no non-reference parameters to the constructor 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't access any non-reference parameters 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't take the address of non-reference 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // parameters 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - etc. 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // If we ever add any of the above cases, remember that: 680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - function-try-blocks will always blacklist this optimization 681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - we need to perform the constructor prologue and cleanup in 682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // EmitConstructorBody. 683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // We also disable the optimization for variadic functions because 688c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // it's impossible to "re-pass" varargs. 689c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 690c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 691c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 692059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt // FIXME: Decide if we can do a delegation of a delegating constructor. 693059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (Ctor->isDelegatingConstructor()) 694059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return false; 695059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 696c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return true; 697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 698c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 6999fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitConstructorBody - Emits the body of the current constructor. 7009fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 7019fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 7029fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXCtorType CtorType = CurGD.getCtorType(); 7039fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Before we go any further, try the complete->base constructor 705c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation optimization. 7068560791791e7b33249feb0ffafeca427076b37b4Timur Iskhodzhanov if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 707b8b2c9da87e7d70a1679db026f40548b3192b705John McCall CGM.getContext().getTargetInfo().getCXXABI().hasConstructorVariants()) { 708d67ef0eed463b43980f04a444155f423114be34bDevang Patel if (CGDebugInfo *DI = getDebugInfo()) 70973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, Ctor->getLocEnd()); 710c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args); 711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return; 712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 713c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Ctor->getBody(); 7159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Enter the function-try-block before the constructor prologue if 717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // applicable. 718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 72059a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); 7239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 72456ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // TODO: in restricted cases, we can emit the vbase initializers of 72556ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall // a complete ctor and then delegate to the base ctor. 72656ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall 727c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Emit the constructor prologue, i.e. the base and member 728c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // initializers. 729fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitCtorPrologue(Ctor, CtorType, Args); 7309fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7319fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit the body of the statement. 732c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 7339fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 7349fc6a7774643a810c8501dae2323e863fefb623eJohn McCall else if (Body) 7359fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(Body); 7369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit any cleanup blocks associated with the member or base 7389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // initializers, which includes (along the exceptional path) the 7399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // destructors for those members and bases that were fully 7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // constructed. 741f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall PopCleanupBlocks(CleanupDepth); 7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 743c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 74459a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 7469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 74756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesnamespace { 74856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class FieldMemcpyizer { 74956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 75056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 75156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec) 75256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 75356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 75456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField(0), LastField(0), FirstFieldOffset(0), LastFieldOffset(0), 75556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex(0) { } 75656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 75756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static bool isMemcpyableField(FieldDecl *F) { 75856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Qualifiers Qual = F->getType().getQualifiers(); 75956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 76056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 76156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 76256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 76356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 76456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemcpyableField(FieldDecl *F) { 76556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField == 0) 76656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addInitialField(F); 76756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames else 76856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addNextField(F); 76956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 77056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 77156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits getMemcpySize() const { 77256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastFieldSize = 77356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->isBitField() ? 77456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField->getBitWidthValue(CGF.getContext()) : 77556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getTypeSize(LastField->getType()); 77656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t MemcpySizeBits = 77756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset + LastFieldSize - FirstFieldOffset + 77856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().getCharWidth() - 1; 77956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = 78056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getContext().toCharUnitsFromBits(MemcpySizeBits); 78156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return MemcpySize; 78256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 78356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 78456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpy() { 78556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Give the subclass a chance to bail out if it feels the memcpy isn't 78656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // worth it (e.g. Hasn't aggregated enough data). 78756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField == 0) { 78856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 78956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 79056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 7915e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames CharUnits Alignment; 79256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 79356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FirstField->isBitField()) { 79456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGRecordLayout &RL = 79556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 79656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 7975e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment); 7985e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } else { 7995e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames unsigned AlignBits = 8005e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames CGF.getContext().getTypeAlign(FirstField->getType()); 8015e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment = CGF.getContext().toCharUnitsFromBits(AlignBits); 8025e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } 8035e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 8045e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames assert((CGF.getContext().toCharUnitsFromBits(FirstFieldOffset) % 8055e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Alignment) == 0 && "Bad field alignment."); 80656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 80756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits MemcpySize = getMemcpySize(); 80856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 80956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 81056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue DestLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 81156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 81256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 81356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 81456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 81556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 81656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddr() : Dest.getAddress(), 81756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Src.isBitField() ? Src.getBitFieldAddr() : Src.getAddress(), 81856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemcpySize, Alignment); 81956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 82056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 82256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void reset() { 82356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = 0; 82456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 82656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames protected: 82756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CodeGenFunction &CGF; 82856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXRecordDecl *ClassDecl; 82956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 83156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitMemcpyIR(llvm::Value *DestPtr, llvm::Value *SrcPtr, 83356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CharUnits Size, CharUnits Alignment) { 83456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType()); 83556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *DBP = 83656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), DPT->getAddressSpace()); 83756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DestPtr = CGF.Builder.CreateBitCast(DestPtr, DBP); 83856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 83956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType()); 84056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type *SBP = 84156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), SPT->getAddressSpace()); 84256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, SBP); 84356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity(), 84556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Alignment.getQuantity()); 84656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 84756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 84856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addInitialField(FieldDecl *F) { 84956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 85056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 85156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 85256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FirstFieldOffset; 85356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 85456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 85556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 85656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 85756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addNextField(FieldDecl *F) { 85856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(F->getFieldIndex() == LastAddedFieldIndex + 1 && 85956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Cannot aggregate non-contiguous fields."); 86056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastAddedFieldIndex = F->getFieldIndex(); 86156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 86256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // The 'first' and 'last' fields are chosen by offset, rather than field 86356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // index. This allows the code to support bitfields, as well as regular 86456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // fields. 86556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 86656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (FOffset < FirstFieldOffset) { 86756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstField = F; 86856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FirstFieldOffset = FOffset; 86956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (FOffset > LastFieldOffset) { 87056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastField = F; 87156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LastFieldOffset = FOffset; 87256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 87356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 87456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 87556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const VarDecl *SrcRec; 87656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const ASTRecordLayout &RecLayout; 87756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *FirstField; 87856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *LastField; 87956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint64_t FirstFieldOffset, LastFieldOffset; 88056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames unsigned LastAddedFieldIndex; 88156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 88256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 88356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class ConstructorMemcpyizer : public FieldMemcpyizer { 88456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 88556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 88656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// Get source argument for copy constructor. Returns null if not a copy 88756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames /// constructor. 88856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD, 88956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) { 89056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (CD->isCopyOrMoveConstructor() && CD->isImplicitlyDefined()) 89156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Args[Args.size() - 1]; 89256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 89356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 89456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 89556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns true if a CXXCtorInitializer represents a member initialization 89656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // that can be rolled into a memcpy. 89756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 89856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!MemcpyableCtor) 89956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 90056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = MemberInit->getMember(); 90156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(Field != 0 && "No field for member init."); 90256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = Field->getType(); 90356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 90456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 90556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on non-POD, not-trivially-constructable members. 90656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(CE && CE->getConstructor()->isTrivial()) && 90756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 90856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldType->isReferenceType())) 90956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 91056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Bail out on volatile fields. 91256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!isMemcpyableField(Field)) 91356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return false; 91456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Otherwise we're good. 91656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return true; 91756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 91856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 91956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 92056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 92156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 92256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)), 92356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl(CD), 92456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemcpyableCtor(CD->isImplicitlyDefined() && 92556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CD->isCopyOrMoveConstructor() && 92656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.getLangOpts().getGC() == LangOptions::NonGC), 92756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Args(Args) { } 92856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 92956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void addMemberInitializer(CXXCtorInitializer *MemberInit) { 93056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (isMemberInitMemcpyable(MemberInit)) { 93156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.push_back(MemberInit); 93256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(MemberInit->getMember()); 93356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 93456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 93556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 93656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorDecl, Args); 93756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 93856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 93956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 94056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedInits() { 94156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedInits.size() <= 1) { 94256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // This memcpy is too small to be worthwhile. Fall back on default 94356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // codegen. 94456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 94556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 94656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits[i], ConstructorDecl, Args); 94756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 94856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 94956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return; 95056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 95156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 95256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames pushEHDestructors(); 95356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 95456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedInits.clear(); 95556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 95656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 95756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void pushEHDestructors() { 95856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm::Value *ThisPtr = CGF.LoadCXXThis(); 95956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 96056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 96156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 96256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 96356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType FieldType = AggregatedInits[i]->getMember()->getType(); 96456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 96556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (CGF.needsEHCleanup(dtorKind)) 96656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); 96756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 96856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 96956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 97056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 97156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedInits(); 97256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 97456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 97556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXConstructorDecl *ConstructorDecl; 97656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool MemcpyableCtor; 97756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args; 97856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 97956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 98056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames class AssignmentMemcpyizer : public FieldMemcpyizer { 98256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames private: 98356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 98456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Returns the memcpyable field copied by the given statement, if one 98556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // exists. Otherwise r 98656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl* getMemcpyableField(Stmt *S) { 98756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!AssignmentsMemcpyable) 98856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 98956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 99056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // Recognise trivial assignments. 99156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (BO->getOpcode() != BO_Assign) 99256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 99356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 99456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 99556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 99656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 99756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 99856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 99956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Stmt *RHS = BO->getRHS(); 100056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 100156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames RHS = EC->getSubExpr(); 100256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!RHS) 100356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 100456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS); 100556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field) 100656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 100756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 100856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 100956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 101056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!(MD && (MD->isCopyAssignmentOperator() || 101156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isMoveAssignmentOperator()) && 101256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MD->isTrivial())) 101356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 101456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 101556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!IOA) 101656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 101756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 101856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 101956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 102156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 102256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 102456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 102556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 102656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 102756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 102856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *DstPtr = CE->getArg(0); 102956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 103056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames DstPtr = DC->getSubExpr(); 103156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 103256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!DUO || DUO->getOpcode() != UO_AddrOf) 103356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 103456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 103556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME) 103656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 103756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 103856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!Field || !isMemcpyableField(Field)) 103956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 104056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Expr *SrcPtr = CE->getArg(1); 104156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 104256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SrcPtr = SC->getSubExpr(); 104356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 104456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!SUO || SUO->getOpcode() != UO_AddrOf) 104556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 104656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 104756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 104856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 104956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return Field; 105056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 105156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 105256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames return 0; 105356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 105456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 105556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool AssignmentsMemcpyable; 105656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames SmallVector<Stmt*, 16> AggregatedStmts; 105756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 105856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames public: 105956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 106056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 106156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FunctionArgList &Args) 106256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 106356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 106456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(Args.size() == 2); 106556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 106656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 106756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAssignment(Stmt *S) { 106856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames FieldDecl *F = getMemcpyableField(S); 106956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (F) { 107056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames addMemcpyableField(F); 107156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.push_back(S); 107256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 107356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 107456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.EmitStmt(S); 107556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 107656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 107756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 107856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void emitAggregatedStmts() { 107956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (AggregatedStmts.size() <= 1) { 108056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (unsigned i = 0; i < AggregatedStmts.size(); ++i) 108156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CGF.EmitStmt(AggregatedStmts[i]); 108256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames reset(); 108356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitMemcpy(); 108656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AggregatedStmts.clear(); 108756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 108856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 108956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames void finish() { 109056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames emitAggregatedStmts(); 109156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 109256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames }; 109356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 109456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 109556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 1096607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 1097607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 1098607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 1099fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CXXCtorType CtorType, 1100fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 1101059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (CD->isDelegatingConstructor()) 1102059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return EmitDelegatingCXXConstructorCall(CD, Args); 1103059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1104607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 1105a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 11065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer *, 8> MemberInitializers; 1107607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1108607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 1109607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 1110607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 1111cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *Member = (*B); 1112607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1113d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt if (Member->isBaseInitializer()) { 1114607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 1115d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } else { 1116d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt assert(Member->isAnyMemberInitializer() && 1117d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt "Delegating initializer on non-delegating constructor"); 1118a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson MemberInitializers.push_back(Member); 1119d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } 1120607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1121607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1122603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson InitializeVTablePointers(ClassDecl); 1123a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 112456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ConstructorMemcpyizer CM(*this, CD, Args); 1125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) 112656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CM.addMemberInitializer(MemberInitializers[I]); 112756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames CM.finish(); 1128607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1129607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1130adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1131adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 1132adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1133adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1134adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonHasTrivialDestructorBody(ASTContext &Context, 1135adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *BaseClassDecl, 1136adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl) 1137adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1138adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // If the destructor is trivial we don't have to check anything else. 1139adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1140adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1141adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1142adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 1143adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1144adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1145adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check fields. 1146adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(), 1147adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson E = BaseClassDecl->field_end(); I != E; ++I) { 1148581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *Field = *I; 1149adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1150adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1151adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1152adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1153adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1154adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check non-virtual bases. 1155adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 1156adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end(); 1157adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 1158adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (I->isVirtual()) 1159adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson continue; 1160adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1161adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *NonVirtualBase = 1162adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1163adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, NonVirtualBase, 1164adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1165adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1166adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1167adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1168adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl == MostDerivedClassDecl) { 1169adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check virtual bases. 1170adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 1171adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); 1172adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 1173adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *VirtualBase = 1174adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1175adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, VirtualBase, 1176adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 1177adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1178adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1179adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 1180adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1181adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1182adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1183adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1184adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 1185adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, 1186adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field) 1187adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 1188adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 1189adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1190adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 1191adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!RT) 1192adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 1193adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1194adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1195adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 1196adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 1197adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 1198ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// CanSkipVTablePointerInitialization - Check whether we need to initialize 1199ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// any vtable pointers before calling this destructor. 1200ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlssonstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 1201e3d6cf2149beb1c215ea6e87023c27b4f37712adAnders Carlsson const CXXDestructorDecl *Dtor) { 1202ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!Dtor->hasTrivialBody()) 1203ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return false; 1204ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1205ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson // Check the fields. 1206ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const CXXRecordDecl *ClassDecl = Dtor->getParent(); 1207ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1208ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 1209581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *Field = *I; 1210ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1211adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 1212adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 1213ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson } 1214ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 1215ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return true; 1216ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson} 1217ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 12189fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitDestructorBody - Emits the body of the current destructor. 12199fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 12209fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 12219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXDtorType DtorType = CurGD.getDtorType(); 12229fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 122350da2cadcc6da86abff6772de65280ace2cabc94John McCall // The call to operator delete in a deleting destructor happens 122450da2cadcc6da86abff6772de65280ace2cabc94John McCall // outside of the function-try-block, which means it's always 122550da2cadcc6da86abff6772de65280ace2cabc94John McCall // possible to delegate the destructor body to the complete 122650da2cadcc6da86abff6772de65280ace2cabc94John McCall // destructor. Do so. 122750da2cadcc6da86abff6772de65280ace2cabc94John McCall if (DtorType == Dtor_Deleting) { 122850da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Deleting); 122950da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 1230378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 123150da2cadcc6da86abff6772de65280ace2cabc94John McCall PopCleanupBlock(); 123250da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 123350da2cadcc6da86abff6772de65280ace2cabc94John McCall } 123450da2cadcc6da86abff6772de65280ace2cabc94John McCall 12359fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Dtor->getBody(); 12369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 12379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If the body is a function-try-block, enter the try before 123850da2cadcc6da86abff6772de65280ace2cabc94John McCall // anything else. 123950da2cadcc6da86abff6772de65280ace2cabc94John McCall bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 12409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 124159a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 12429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 124350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the epilogue cleanups. 124450da2cadcc6da86abff6772de65280ace2cabc94John McCall RunCleanupsScope DtorEpilogue(*this); 124550da2cadcc6da86abff6772de65280ace2cabc94John McCall 12469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If this is the complete variant, just invoke the base variant; 12479fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // the epilogue will destruct the virtual bases. But we can't do 12489fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // this optimization if the body is a function-try-block, because 12499fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // we'd introduce *two* handler blocks. 125050da2cadcc6da86abff6772de65280ace2cabc94John McCall switch (DtorType) { 125150da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 125250da2cadcc6da86abff6772de65280ace2cabc94John McCall 125350da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Complete: 125450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for virtual bases. 125550da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Complete); 125650da2cadcc6da86abff6772de65280ace2cabc94John McCall 1257b8b2c9da87e7d70a1679db026f40548b3192b705John McCall if (!isTryBody && 1258b8b2c9da87e7d70a1679db026f40548b3192b705John McCall CGM.getContext().getTargetInfo().getCXXABI().hasDestructorVariants()) { 125950da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 1260378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, LoadCXXThis()); 126150da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 126250da2cadcc6da86abff6772de65280ace2cabc94John McCall } 126350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Fallthrough: act like we're in the base variant. 12649fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 126550da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Base: 126650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for fields and non-virtual bases. 126750da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Base); 126850da2cadcc6da86abff6772de65280ace2cabc94John McCall 126950da2cadcc6da86abff6772de65280ace2cabc94John McCall // Initialize the vtable pointers before entering the body. 1270ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 1271ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson InitializeVTablePointers(Dtor->getParent()); 12729fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 127350da2cadcc6da86abff6772de65280ace2cabc94John McCall if (isTryBody) 127450da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 127550da2cadcc6da86abff6772de65280ace2cabc94John McCall else if (Body) 127650da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(Body); 127750da2cadcc6da86abff6772de65280ace2cabc94John McCall else { 127850da2cadcc6da86abff6772de65280ace2cabc94John McCall assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 127950da2cadcc6da86abff6772de65280ace2cabc94John McCall // nothing to do besides what's in the epilogue 128050da2cadcc6da86abff6772de65280ace2cabc94John McCall } 12815abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // -fapple-kext must inline any call to this dtor into 12825abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // the caller's body. 12837edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (getLangOpts().AppleKext) 128472390b39c545426023ec104afe8706395d732badBill Wendling CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 128550da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 12869fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } 12879fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 128850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Jump out through the epilogue cleanups. 128950da2cadcc6da86abff6772de65280ace2cabc94John McCall DtorEpilogue.ForceCleanup(); 12909fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 12919fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Exit the try if applicable. 12929fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 129359a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 12949fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 12959fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 129656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hamesvoid CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 129756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 129856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const Stmt *RootS = AssignOp->getBody(); 129956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(isa<CompoundStmt>(RootS) && 130056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Body of an implicit assignment operator should be compound stmt."); 130156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 130256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 130356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames LexicalScope Scope(*this, RootCS->getSourceRange()); 130456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 130556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AssignmentMemcpyizer AM(*this, AssignOp, Args); 130656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (CompoundStmt::const_body_iterator I = RootCS->body_begin(), 130756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames E = RootCS->body_end(); 130856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames I != E; ++I) { 130956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AM.emitAssignment(*I); 131056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 131156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames AM.finish(); 131256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 131356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 131450da2cadcc6da86abff6772de65280ace2cabc94John McCallnamespace { 131550da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the operator delete associated with the current destructor. 13161f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallDtorDelete : EHScopeStack::Cleanup { 131750da2cadcc6da86abff6772de65280ace2cabc94John McCall CallDtorDelete() {} 131850da2cadcc6da86abff6772de65280ace2cabc94John McCall 1319ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 132050da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 132150da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = Dtor->getParent(); 132250da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 132350da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.getContext().getTagDeclType(ClassDecl)); 132450da2cadcc6da86abff6772de65280ace2cabc94John McCall } 132550da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 132650da2cadcc6da86abff6772de65280ace2cabc94John McCall 132759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov struct CallDtorDeleteConditional : EHScopeStack::Cleanup { 132859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldDeleteCondition; 132959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov public: 133059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 133159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov : ShouldDeleteCondition(ShouldDeleteCondition) { 133259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov assert(ShouldDeleteCondition != NULL); 133359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 133459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 133559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov void Emit(CodeGenFunction &CGF, Flags flags) { 133659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 133759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 133859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov llvm::Value *ShouldCallDelete 133959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 134059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 134159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 134259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(callDeleteBB); 134359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 134459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXRecordDecl *ClassDecl = Dtor->getParent(); 134559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 134659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.getContext().getTagDeclType(ClassDecl)); 134759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.Builder.CreateBr(continueBB); 134859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 134959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.EmitBlock(continueBB); 135059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 135159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov }; 135259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 13539928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall class DestroyField : public EHScopeStack::Cleanup { 13549928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field; 1355516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne CodeGenFunction::Destroyer *destroyer; 13569928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray; 13579928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 13589928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall public: 13599928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 13609928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray) 1361516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne : field(field), destroyer(destroyer), 13629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall useEHCleanupForArray(useEHCleanupForArray) {} 13639928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 1364ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 13659928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall // Find the address of the field. 13669928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall llvm::Value *thisValue = CGF.LoadCXXThis(); 1367377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 1368377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 1369377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman LValue LV = CGF.EmitLValueForField(ThisLV, field); 13709928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall assert(LV.isSimple()); 13719928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 13729928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 1373ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall flags.isForNormalCleanup() && useEHCleanupForArray); 137450da2cadcc6da86abff6772de65280ace2cabc94John McCall } 137550da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 137650da2cadcc6da86abff6772de65280ace2cabc94John McCall} 137750da2cadcc6da86abff6772de65280ace2cabc94John McCall 1378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 1379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 1380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 138150da2cadcc6da86abff6772de65280ace2cabc94John McCallvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 138250da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXDtorType DtorType) { 1383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 1384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 1385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 138650da2cadcc6da86abff6772de65280ace2cabc94John McCall // The deleting-destructor phase just needs to call the appropriate 138750da2cadcc6da86abff6772de65280ace2cabc94John McCall // operator delete that Sema picked up. 13883b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Deleting) { 13893b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DD->getOperatorDelete() && 13903b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "operator delete missing - EmitDtorEpilogue"); 139159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (CXXStructorImplicitParamValue) { 139259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // If there is an implicit param to the deleting dtor, it's a boolean 139359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // telling whether we should call delete at the end of the dtor. 139459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDeleteConditional>( 139559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov NormalAndEHCleanup, CXXStructorImplicitParamValue); 139659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } else { 139759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 139859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 13993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14003b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14013b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 140250da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = DD->getParent(); 140350da2cadcc6da86abff6772de65280ace2cabc94John McCall 1404416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith // Unions have no bases and do not call field destructors. 1405416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith if (ClassDecl->isUnion()) 1406416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith return; 1407416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith 140850da2cadcc6da86abff6772de65280ace2cabc94John McCall // The complete-destructor phase just destructs all the virtual bases. 14093b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Complete) { 141050da2cadcc6da86abff6772de65280ace2cabc94John McCall 141150da2cadcc6da86abff6772de65280ace2cabc94John McCall // We push them in the forward order so that they'll be popped in 141250da2cadcc6da86abff6772de65280ace2cabc94John McCall // the reverse order. 141350da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 141450da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); 14153b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall I != E; ++I) { 14163b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall const CXXBaseSpecifier &Base = *I; 14173b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall CXXRecordDecl *BaseClassDecl 14183b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 14193b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14203b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Ignore trivial destructors. 14213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (BaseClassDecl->hasTrivialDestructor()) 14223b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall continue; 142350da2cadcc6da86abff6772de65280ace2cabc94John McCall 14241f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14261f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ true); 14273b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 142850da2cadcc6da86abff6772de65280ace2cabc94John McCall 14293b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 14303b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 14313b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14323b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DtorType == Dtor_Base); 143350da2cadcc6da86abff6772de65280ace2cabc94John McCall 143450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy non-virtual bases. 143550da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 143650da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 143750da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXBaseSpecifier &Base = *I; 143850da2cadcc6da86abff6772de65280ace2cabc94John McCall 143950da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore virtual bases. 144050da2cadcc6da86abff6772de65280ace2cabc94John McCall if (Base.isVirtual()) 144150da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 144250da2cadcc6da86abff6772de65280ace2cabc94John McCall 144350da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 144450da2cadcc6da86abff6772de65280ace2cabc94John McCall 144550da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore trivial destructors. 144650da2cadcc6da86abff6772de65280ace2cabc94John McCall if (BaseClassDecl->hasTrivialDestructor()) 144750da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 14483b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 14491f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 14501f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 14511f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ false); 145250da2cadcc6da86abff6772de65280ace2cabc94John McCall } 145350da2cadcc6da86abff6772de65280ace2cabc94John McCall 145450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy direct fields. 14555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const FieldDecl *, 16> FieldDecls; 1456607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1457607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 1458581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl *field = *I; 14599928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType type = field->getType(); 14609928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 14619928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall if (!dtorKind) continue; 14629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 14639a561d539158a30b68fc258b81a994f3fac10212Richard Smith // Anonymous union members do not have their destructors called. 14649a561d539158a30b68fc258b81a994f3fac10212Richard Smith const RecordType *RT = type->getAsUnionType(); 14659a561d539158a30b68fc258b81a994f3fac10212Richard Smith if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; 14669a561d539158a30b68fc258b81a994f3fac10212Richard Smith 14679928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CleanupKind cleanupKind = getCleanupKind(dtorKind); 14689928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall EHStack.pushCleanup<DestroyField>(cleanupKind, field, 14699928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall getDestroyer(dtorKind), 14709928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall cleanupKind & EHCleanup); 1471607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1472607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1473607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1474c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1475c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 147659174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor/// 1477c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1478c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayType the type of the array to initialize 1479c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin an arrayType* 1480c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1481c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 14823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1483c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1484c3c0766277cd64bf117450a1519c9cf762d994d4John McCall const ConstantArrayType *arrayType, 1485c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1486c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1487c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1488c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1489c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType elementType; 1490c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements = 1491c3c0766277cd64bf117450a1519c9cf762d994d4John McCall emitArrayLength(arrayType, elementType, arrayBegin); 1492c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1493c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1494c3c0766277cd64bf117450a1519c9cf762d994d4John McCall argBegin, argEnd, zeroInitialize); 14953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 14963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1497c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1498c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 1499c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// 1500c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1501c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param numElements the number of elements in the array; 1502dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall/// may be zero 1503c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin a T*, where T is the type constructed by ctor 1504c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1505c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 15063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1507c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1508c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements, 1509c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1510c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1511c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1512c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1513dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1514dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // It's legal for numElements to be zero. This can happen both 1515dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // dynamically, because x can be zero in 'new A[x]', and statically, 1516dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // because of GCC extensions that permit zero-length arrays. There 1517dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // are probably legitimate places where we could assume that this 1518dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // doesn't happen, but it's not clear that it's worth it. 1519dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BranchInst *zeroCheckBranch = 0; 1520dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1521dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Optimize for a constant count. 1522dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::ConstantInt *constantCount 1523dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall = dyn_cast<llvm::ConstantInt>(numElements); 1524dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount) { 1525dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Just skip out if the constant count is zero. 1526dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount->isZero()) return; 1527dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1528dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Otherwise, emit the check. 1529dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } else { 1530dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1531dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1532dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1533dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall EmitBlock(loopBB); 1534dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } 1535dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1536c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Find the end of the array. 1537c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1538c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.end"); 1539c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1540c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Enter the loop, setting up a phi for the current location to initialize. 1541c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1542c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1543c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(loopBB); 1544c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1545c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.cur"); 1546c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(arrayBegin, entryBB); 15473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 15483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 1549c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1550c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType type = getContext().getTypeDeclType(ctor->getParent()); 15513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 155259174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor // Zero initialize the storage, if requested. 1553c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (zeroInitialize) 1554c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitNullInitialization(cur, type); 155559174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor 15563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 15573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 15583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 15593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 15603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 15613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 15623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 15633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 156444ec82b4a1597802f5bf17721481b8c265bc8dc5Anders Carlsson { 1565f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 15663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1567c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Evaluate the constructor and its arguments in a regular 1568c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // partial-destroy cleanup. 15694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().Exceptions && 1570c3c0766277cd64bf117450a1519c9cf762d994d4John McCall !ctor->getParent()->hasTrivialDestructor()) { 1571c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Destroyer *destroyer = destroyCXXObject; 1572c3c0766277cd64bf117450a1519c9cf762d994d4John McCall pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1573c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 15743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1575c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1576378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, cur, argBegin, argEnd); 1577c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 15783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1579c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Go to the next element. 1580c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *next = 1581c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1582c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.next"); 1583c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(next, Builder.GetInsertBlock()); 15843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1585c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Check whether that's the end of the loop. 1586c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1587c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1588c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateCondBr(done, contBB, loopBB); 15893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1590dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Patch the earlier check to skip over the loop. 1591dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1592dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1593c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(contBB); 15943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 15953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1596bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1597bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall llvm::Value *addr, 1598bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall QualType type) { 1599bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const RecordType *rtype = type->castAs<RecordType>(); 1600bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1601bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXDestructorDecl *dtor = record->getDestructor(); 1602bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall assert(!dtor->isTrivial()); 1603bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1604378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, addr); 1605bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall} 1606bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall 16073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 16083b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1609155ed4a23366f4514befb1c9f5f89d16f8b8b6dbAnders Carlsson CXXCtorType Type, bool ForVirtualBase, 1610378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 16113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 16123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 16133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 16143ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 16153ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel CGDebugInfo *DI = getDebugInfo(); 16163a70cd6e1cc414856e41ce5509aa61c89bf472dcAlexey Samsonov if (DI && 16174cdad3151bfb2075c6bdbfe89fbb08f31a90a45bDouglas Gregor CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo) { 1618af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // If debug info for this class has not been emitted then this is the 1619af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // right time to do so. 16203ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel const CXXRecordDecl *Parent = D->getParent(); 16213ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel DI->getOrCreateRecordType(CGM.getContext().getTypeDeclType(Parent), 16223ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel Parent->getLocation()); 16233ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel } 16243ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 16258b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 16268b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 16278b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 16288b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 16298b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 16303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16328b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16338b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 163485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 163585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 16368b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 16378b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 16388b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 16398b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 16408b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 16413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 16423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 16433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1644378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type), ForVirtualBase, 1645378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Delegating); 16463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 16473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 16484def70d3040e73707c738f7c366737a986135edfRichard Smith // FIXME: Provide a source location here. 16494def70d3040e73707c738f7c366737a986135edfRichard Smith EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 165059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov VTT, getContext().getPointerType(getContext().VoidPtrTy), 165159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ArgBeg, ArgEnd); 16523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 16533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallvoid 165534999876e215b22febc240b1a6dc054215d12f9cFariborz JahanianCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 165634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *This, llvm::Value *Src, 165734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgBeg, 165834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgEnd) { 165934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian if (D->isTrivial()) { 166034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 166185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 166285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 166334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 166434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian return; 166534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 166634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, 166734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian clang::Ctor_Complete); 166834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(D->isInstance() && 166934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Trying to emit a member call expr on a static method!"); 167034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 167134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 167234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 167334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallArgList Args; 167434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 167534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the this ptr. 167604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(This), D->getThisType(getContext())); 167734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 167834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 167934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the src ptr. 168034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType QT = *(FPT->arg_type_begin()); 16812acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *t = CGM.getTypes().ConvertType(QT); 168234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian Src = Builder.CreateBitCast(Src, t); 168304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(Src), QT); 168434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 168534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Skip over first argument (Src). 168634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian ++ArgBeg; 168734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator Arg = ArgBeg; 168834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, 168934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian E = FPT->arg_type_end(); I != E; ++I, ++Arg) { 169034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(Arg != ArgEnd && "Running over edge of argument list!"); 1691413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, *I); 169234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 169334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Either we've emitted all the call args, or we have a call to a 169434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // variadic function. 169534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert((Arg == ArgEnd || FPT->isVariadic()) && 169634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Extra arguments in non-variadic function!"); 169734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // If we still have any arguments, emit them using the type of the argument. 169834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (; Arg != ArgEnd; ++Arg) { 169934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType ArgType = Arg->getType(); 1700413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, ArgType); 170134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 170234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 17030f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All), 17040f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall Callee, ReturnValueSlot(), Args, D); 170534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian} 170634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 170734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanianvoid 1708c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1709c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CXXCtorType CtorType, 1710c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall const FunctionArgList &Args) { 1711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CallArgList DelegateArgs; 1712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1713c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1714c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "no parameters to constructor"); 1715c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // this 171704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1720c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // vtt 1721314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType), 1722378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1723378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true)) { 1724c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 172504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(VTT), VoidPP); 1726c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1727af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD)) { 1728c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "cannot skip vtt parameter, already done with args"); 1729d26bc76c98006609002d9930f8840490e88ac5b5John McCall assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1730c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1731c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1732c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1733c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1734c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Explicit arguments. 1735c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall for (; I != E; ++I) { 1736413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall const VarDecl *param = *I; 1737413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitDelegateCallArg(DelegateArgs, param); 1738c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1739c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1740de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), 1741c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CGM.GetAddrOfCXXConstructor(Ctor, CtorType), 1742c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ReturnValueSlot(), DelegateArgs, Ctor); 1743c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 1744c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1745b76af9c969558b4484be87933e89e76e7ee87e21Sean Huntnamespace { 1746b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1747b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXDestructorDecl *Dtor; 1748b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt llvm::Value *Addr; 1749b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type; 1750b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1751b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1752b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type) 1753b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt : Dtor(D), Addr(Addr), Type(Type) {} 1754b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1755ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1756b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1757378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/true, Addr); 1758b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1759b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt }; 1760b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1761b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1762059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Huntvoid 1763059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean HuntCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1764059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt const FunctionArgList &Args) { 1765059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt assert(Ctor->isDelegatingConstructor()); 1766059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1767059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt llvm::Value *ThisPtr = LoadCXXThis(); 1768059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1769f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman QualType Ty = getContext().getTagDeclType(Ctor->getParent()); 1770d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = getContext().getTypeAlignInChars(Ty); 1771f85e193739c953358c865005855253af4f68a497John McCall AggValueSlot AggSlot = 1772f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), 17737c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 1774410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 1775649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased); 1776059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1777059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1778059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1779b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXRecordDecl *ClassDecl = Ctor->getParent(); 17804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1781b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type = 1782b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1783b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1784b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1785b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ClassDecl->getDestructor(), 1786b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ThisPtr, Type); 1787b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1788b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1789059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 17903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 17913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 17928e6404ca28d6bbb76e97ea2a53a74816c2a74665Anders Carlsson bool ForVirtualBase, 1793378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor bool Delegating, 17943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1795314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type), 1796378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor ForVirtualBase, Delegating); 1797ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian llvm::Value *Callee = 0; 17987edf9e38b91917b661277601c0e448eef0eb2b56Richard Smith if (getLangOpts().AppleKext) 1799771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 1800771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian DD->getParent()); 1801ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian 1802ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (!Callee) 1803ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 18043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18054def70d3040e73707c738f7c366737a986135edfRichard Smith // FIXME: Provide a source location here. 18064def70d3040e73707c738f7c366737a986135edfRichard Smith EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This, 180759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov VTT, getContext().getPointerType(getContext().VoidPtrTy), 180859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 0, 0); 18093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 18103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1811291ae949612e371c41bf771a483b407d49372a4fJohn McCallnamespace { 18121f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallLocalDtor : EHScopeStack::Cleanup { 1813291ae949612e371c41bf771a483b407d49372a4fJohn McCall const CXXDestructorDecl *Dtor; 1814291ae949612e371c41bf771a483b407d49372a4fJohn McCall llvm::Value *Addr; 1815291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1816291ae949612e371c41bf771a483b407d49372a4fJohn McCall CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1817291ae949612e371c41bf771a483b407d49372a4fJohn McCall : Dtor(D), Addr(Addr) {} 1818291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1819ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1820291ae949612e371c41bf771a483b407d49372a4fJohn McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1821378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*ForVirtualBase=*/false, 1822378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor /*Delegating=*/false, Addr); 1823291ae949612e371c41bf771a483b407d49372a4fJohn McCall } 1824291ae949612e371c41bf771a483b407d49372a4fJohn McCall }; 1825291ae949612e371c41bf771a483b407d49372a4fJohn McCall} 1826291ae949612e371c41bf771a483b407d49372a4fJohn McCall 182781407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCallvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 182881407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall llvm::Value *Addr) { 18291f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 183081407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall} 183181407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall 1832f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1833f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1834f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!ClassDecl) return; 1835f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ClassDecl->hasTrivialDestructor()) return; 1836f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1837f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1838642a75f883e644bcfbb82e7af0313776ad1ce33cJohn McCall assert(D && D->isUsed() && "destructor not marked as used!"); 183981407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall PushDestructorCleanup(D, Addr); 1840f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1841f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 18423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1843bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1844bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 18453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 1846043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); 184714c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck CharUnits VBaseOffsetOffset = 18481d2b31710539d705a3850c9fc3aa1804c2a5efeePeter Collingbourne CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); 18493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 185114c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 185214c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck "vbase.offset.ptr"); 18532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 18543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 18553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 18573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 18583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 18603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 18613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 18623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 18633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1864d103f9f9b401b419e756f8c1849683cd77586067Anders Carlssonvoid 1865d103f9f9b401b419e756f8c1849683cd77586067Anders CarlssonCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1866b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1867d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1868d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson llvm::Constant *VTable, 1869d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson const CXXRecordDecl *VTableClass) { 1870c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 1871c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1872d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute the address point. 1873c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTableAddressPoint; 1874851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson 1875c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Check if we need to use a vtable from the VTT. 1876851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && 1877b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson (RD->getNumVBases() || NearestVBase)) { 1878c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Get the secondary vpointer index. 1879c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson uint64_t VirtualPointerIndex = 1880c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 1881c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1882c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson /// Load the VTT. 1883c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTT = LoadCXXVTT(); 1884c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson if (VirtualPointerIndex) 1885c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 1886c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1887c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // And load the address point from the VTT. 1888c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = Builder.CreateLoad(VTT); 1889c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } else { 189084fcc48817bb04c7de1acafcaa1f54ee3235a97bPeter Collingbourne uint64_t AddressPoint = 1891e09cdf46aa2b86c24e6bf7a7ead2eaded964f2ffPeter Collingbourne CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base); 1892c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = 1893d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); 1894c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } 1895d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1896d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute where to store the address point. 18978246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VirtualOffset = 0; 18989a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtualOffset = CharUnits::Zero(); 18993e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson 19003e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { 19013e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // We need to use the virtual base offset offset because the virtual base 19023e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // might have a different offset in the most derived class. 19038246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, 19048246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NearestVBase); 1905d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck NonVirtualOffset = OffsetFromNearestVBase; 19063e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } else { 19078246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // We can just use the base offset in the complete class. 19084230d529a8797bbeef2328b60abeae333f7e143fKen Dyck NonVirtualOffset = Base.getBaseOffset(); 19093e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } 19108246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 19118246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // Apply the offsets. 19128246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VTableField = LoadCXXThis(); 19138246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 19149a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtualOffset.isZero() || VirtualOffset) 19158246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 19168246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NonVirtualOffset, 19178246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset); 191836fd6beef1ffaf93217d8ce96d900d4ed817e463Anders Carlsson 1919d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Finally, store the address point. 19202acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *AddressPointPtrTy = 1921d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableAddressPoint->getType()->getPointerTo(); 1922d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 19238cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 19248cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); 1925d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 1926d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1927603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid 1928603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders CarlssonCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1929b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1930d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1931603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson bool BaseIsNonVirtualPrimaryBase, 1932603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable, 1933603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *VTableClass, 1934603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy& VBases) { 1935603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // If this base is a non-virtual primary base the address point has already 1936603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // been set. 1937603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseIsNonVirtualPrimaryBase) { 1938603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointer for this base. 19394235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 19404235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson VTable, VTableClass); 1941603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 19424658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1943603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 19444658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1945603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Traverse bases. 1946603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1947603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson E = RD->bases_end(); I != E; ++I) { 19480703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson CXXRecordDecl *BaseDecl 19490703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1950603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1951603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 1952603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseDecl->isDynamicClass()) 1953603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1954603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1955d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffset; 1956d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffsetFromNearestVBase; 195714da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson bool BaseDeclIsNonVirtualPrimaryBase; 1958603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1959603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (I->isVirtual()) { 1960603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Check if we've visited this virtual base before. 1961603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!VBases.insert(BaseDecl)) 1962603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1963603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1964603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = 1965603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson getContext().getASTRecordLayout(VTableClass); 1966603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1967d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1968d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffsetFromNearestVBase = CharUnits::Zero(); 196914da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = false; 1970603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } else { 1971603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1972603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 19734230d529a8797bbeef2328b60abeae333f7e143fKen Dyck BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 19744235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase = 1975d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 197614da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 1977603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 19780703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson 19794230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 1980b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson I->isVirtual() ? BaseDecl : NearestVBase, 19814235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase, 198214da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase, 1983603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, VTableClass, VBases); 19843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 19853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 19863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1987603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 1988603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 19890703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson if (!RD->isDynamicClass()) 19903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 19913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1992603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Get the VTable. 1993603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD); 19943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1995603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointers for this class and all of its bases. 1996603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy VBases; 19974230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 19984230d529a8797bbeef2328b60abeae333f7e143fKen Dyck /*NearestVBase=*/0, 1999d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck /*OffsetFromNearestVBase=*/CharUnits::Zero(), 2000603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson /*BaseIsNonVirtualPrimaryBase=*/false, 2001603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, RD, VBases); 20023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 2003043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman 2004043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohmanllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 20052acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty) { 2006043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 20078cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 20088cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr()); 20098cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany return VTable; 2010043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman} 2011a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2012a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { 2013a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const Expr *E = Base; 2014a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2015a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 2016a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = E->IgnoreParens(); 2017a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 2018a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_DerivedToBase || 2019a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_UncheckedDerivedToBase || 2020a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_NoOp) { 2021a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 2022a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2023a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2024a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2025a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2026a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson break; 2027a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2028a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2029a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson QualType DerivedType = E->getType(); 2030a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const PointerType *PTy = DerivedType->getAs<PointerType>()) 2031a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson DerivedType = PTy->getPointeeType(); 2032a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2033a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return cast<CXXRecordDecl>(DerivedType->castAs<RecordType>()->getDecl()); 2034a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2035a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2036a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 2037a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// quite what we want. 2038a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 2039a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 2040a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 2041a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = PE->getSubExpr(); 2042a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2043a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2044a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2045a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 2046a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_NoOp) { 2047a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 2048a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2049a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2050a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2051a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 2052a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UO->getOpcode() == UO_Extension) { 2053a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = UO->getSubExpr(); 2054a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 2055a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2056a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2057a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return E; 2058a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2059a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2060a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2061a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// canDevirtualizeMemberFunctionCall - Checks whether the given virtual member 2062a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// function call on the given expr can be devirtualized. 2063a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool canDevirtualizeMemberFunctionCall(const Expr *Base, 2064a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 2065a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the most derived class is marked final, we know that no subclass can 2066a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // override this member function and so we can devirtualize it. For example: 2067a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2068a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct A { virtual void f(); } 2069a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct B final : A { }; 2070a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2071a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // void f(B *b) { 2072a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // b->f(); 2073a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // } 2074a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 2075a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base); 2076a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 2077a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2078a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2079a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the member function is marked 'final', we know that it can't be 2080a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // overridden and can therefore devirtualize it. 2081a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->hasAttr<FinalAttr>()) 2082a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2083a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2084a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Similarly, if the class itself is marked 'final' it can't be overridden 2085a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // and we can therefore devirtualize the member function call. 2086a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->getParent()->hasAttr<FinalAttr>()) 2087a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2088a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2089a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson Base = skipNoOpCastsAndParens(Base); 2090a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 2091a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 2092a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // This is a record decl. We know the type and can devirtualize it. 2093a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return VD->getType()->isRecordType(); 2094a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2095a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2096a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2097a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 2098a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2099a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can always devirtualize calls on temporary object expressions. 2100a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXConstructExpr>(Base)) 2101a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2102a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2103a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // And calls on bound temporaries. 2104a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXBindTemporaryExpr>(Base)) 2105a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2106a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2107a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Check if this is a call expr that returns a record type. 2108a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 2109a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CE->getCallReturnType()->isRecordType(); 2110a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2111a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can't devirtualize the call. 2112a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2113a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2114a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2115a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool UseVirtualCall(ASTContext &Context, 2116a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXOperatorCallExpr *CE, 2117a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 2118a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (!MD->isVirtual()) 2119a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 2120a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2121a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // When building with -fapple-kext, all calls must go through the vtable since 2122a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // the kernel linker can do runtime patching of vtables. 21234e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context.getLangOpts().AppleKext) 2124a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 2125a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2126a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD); 2127a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2128a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2129a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonllvm::Value * 2130a2447e0d1e28669cd637204a871f15b1215277fdAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 2131a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD, 2132a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson llvm::Value *This) { 2133de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnType = 2134de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().GetFunctionType( 2135de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(MD)); 2136a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2137a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UseVirtualCall(getContext(), E, MD)) 2138de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return BuildVirtualCall(MD, This, fnType); 2139a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 2140de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return CGM.GetAddrOfFunction(MD, fnType); 2141a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 2142bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman 21430f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallvoid CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda, 21440f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CallArgList &callArgs) { 214564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Lookup the call operator 21460f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall DeclarationName operatorName 214721f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman = getContext().DeclarationNames.getCXXOperatorName(OO_Call); 21480f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CXXMethodDecl *callOperator = 21493bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie cast<CXXMethodDecl>(lambda->lookup(operatorName).front()); 215021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 215121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Get the address of the call operator. 21520f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const CGFunctionInfo &calleeFnInfo = 21530f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 21540f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall llvm::Value *callee = 21550f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.GetAddrOfFunction(GlobalDecl(callOperator), 21560f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().GetFunctionType(calleeFnInfo)); 21570f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Prepare the return slot. 21590f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const FunctionProtoType *FPT = 21600f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callOperator->getType()->castAs<FunctionProtoType>(); 21610f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall QualType resultType = FPT->getResultType(); 21620f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ReturnValueSlot returnSlot; 21630f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && 21640f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 21650f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall hasAggregateLLVMType(calleeFnInfo.getReturnType())) 21660f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); 21670f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 21680f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // We don't need to separately arrange the call arguments because 21690f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // the call can't be variadic anyway --- it's impossible to forward 21700f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // variadic arguments. 217121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 217221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Now emit our call. 21730f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, 21740f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall callArgs, callOperator); 217521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 21760f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // If necessary, copy the returned value into the slot. 21770f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall if (!resultType->isVoidType() && returnSlot.isNull()) 21780f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall EmitReturnOfRValue(RV, resultType); 217950f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman else 218050f089a6e1837cb81f8d1830bda6db619e422a2eEli Friedman EmitBranchThroughCleanup(ReturnBlock); 218121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman} 218221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 218364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaBlockInvokeBody() { 218464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const BlockDecl *BD = BlockInfo->getBlockDecl(); 218564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const VarDecl *variable = BD->capture_begin()->getVariable(); 218664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 218764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 218864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 218964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 219064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 219164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 219264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = GetAddrOfBlockDecl(variable, false); 219364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 219464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 219564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 219664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (BlockDecl::param_const_iterator I = BD->param_begin(), 219764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = BD->param_end(); I != E; ++I) { 219864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 219964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 220064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 220164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 220264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 220364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 220464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 220564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { 220664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman if (cast<CXXMethodDecl>(CurFuncDecl)->isVariadic()) { 220764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // FIXME: Making this work correctly is nasty because it requires either 220864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // cloning the body of the call operator or making the call operator forward. 220964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CGM.ErrorUnsupported(CurFuncDecl, "lambda conversion to variadic function"); 221064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 221164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 221264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 221364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitFunctionBody(Args); 221464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 221564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 221664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 221764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = MD->getParent(); 221864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 221964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 222064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 222164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 222264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 222364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 222464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 222564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 222664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 222764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (FunctionDecl::param_const_iterator I = MD->param_begin(), 222864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = MD->param_end(); I != E; ++I) { 222964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 223064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 223164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 223264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 223364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 223464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 223564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 223627dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregorvoid CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { 223727dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor if (MD->isVariadic()) { 223821f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // FIXME: Making this work correctly is nasty because it requires either 223921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // cloning the body of the call operator or making the call operator forward. 224021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 224164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 224221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman } 224321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 224427dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor EmitLambdaDelegatingInvokeBody(MD); 2245bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman} 2246