CGClass.cpp revision 64bee65a3436e3f0c352fcfe2130676f3502cffe
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" 165d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 172f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 187e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "clang/AST/EvaluatedExprVisitor.h" 195d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 209fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "clang/AST/StmtCXX.h" 213ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include "clang/Frontend/CodeGenOptions.h" 222f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 235d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 245d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 2655c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyckstatic CharUnits 2734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, 2834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *DerivedClass, 29f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start, 30f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator End) { 3155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = CharUnits::Zero(); 3234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *RD = DerivedClass; 3434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 35f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXBaseSpecifier *Base = *I; 3734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson assert(!Base->isVirtual() && "Should not see virtual bases here!"); 3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the layout. 4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *BaseDecl = 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Add the offset. 4655c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RD = BaseDecl; 4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return Offset; 5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 535d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 5484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 55a04efdf635d35d88e65041fad007225d8c8d64a5Anders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 56f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 57f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd) { 58f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 59a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6055c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = 61f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 62f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall PathBegin, PathEnd); 6355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (Offset.isZero()) 64a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson return 0; 65a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 68a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 7084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 728561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// Gets the address of a direct base class within a complete object. 73bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 74bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 75bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 76bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 77bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 788561a8666c70f924c8f0209c41b9b77bbbf90607Anders CarlssonCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 798561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 808561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Base, 818561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson bool BaseIsVirtual) { 82bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 83bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 84bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 885fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck CharUnits Offset; 89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 908561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (BaseIsVirtual) 915fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getVBaseClassOffset(Base); 92bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 935fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getBaseClassOffset(Base); 94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 95bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 96bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 985fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck if (Offset.isPositive()) { 99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 1005fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck V = Builder.CreateConstInBoundsGEP1_64(V, Offset.getQuantity()); 101bff225ecf77fb891596ecb1b27196310d268365eJohn McCall } 102bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall return V; 105d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1079dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlssonstatic llvm::Value * 1089dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders CarlssonApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr, 1099a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtual, llvm::Value *Virtual) { 1102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 1119dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1129dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1139dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson llvm::Value *NonVirtualOffset = 0; 1149a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtual.isZero()) 1159a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, 1169a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtual.getQuantity()); 1179dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1189dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson llvm::Value *BaseOffset; 1199dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson if (Virtual) { 1209dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson if (NonVirtualOffset) 1219dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson BaseOffset = CGF.Builder.CreateAdd(Virtual, NonVirtualOffset); 1229dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson else 1239dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson BaseOffset = Virtual; 1249dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson } else 1259dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson BaseOffset = NonVirtualOffset; 1269dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1279dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson // Apply the base offset. 1288b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner ThisPtr = CGF.Builder.CreateBitCast(ThisPtr, CGF.Int8PtrTy); 1299dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson ThisPtr = CGF.Builder.CreateGEP(ThisPtr, BaseOffset, "add.ptr"); 1309dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1319dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson return ThisPtr; 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 14534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the virtual base. 14634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if ((*Start)->isVirtual()) { 14734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VBase = 14834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 14934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson ++Start; 15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 15255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits NonVirtualOffset = 1538561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 154f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall Start, PathEnd); 15534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 15634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the base pointer type. 1572acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtrTy = 158f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ConvertType((PathEnd[-1])->getType())->getPointerTo(); 15934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 16055c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (NonVirtualOffset.isZero() && !VBase) { 16134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Just cast back. 16234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 16334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 16434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 16534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastNull = 0; 16634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 16734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastEnd = 0; 16834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 16934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 17034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNull = createBasicBlock("cast.null"); 17134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 17234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastEnd = createBasicBlock("cast.end"); 17334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 174b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 17534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 17634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastNotNull); 17734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 17834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 17934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::Value *VirtualOffset = 0; 18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 181336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (VBase) { 182336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (Derived->hasAttr<FinalAttr>()) { 183336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson VirtualOffset = 0; 184336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson 185336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 186336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson 18755c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits VBaseOffset = Layout.getVBaseClassOffset(VBase); 18855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck NonVirtualOffset += VBaseOffset; 189336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } else 190336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); 191336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } 19234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 19334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Apply the offsets. 19455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 1959a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset, 19634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VirtualOffset); 19734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Cast back. 19934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 20034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 20134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 20234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateBr(CastEnd); 20334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastNull); 20434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateBr(CastEnd); 20534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastEnd); 20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 207bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 20834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson PHI->addIncoming(Value, CastNotNull); 20934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 21034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNull); 21134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = PHI; 21234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 21334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 21434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Value; 21534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 21734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonllvm::Value * 218a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 2198561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 220f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 221f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 223f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 224a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 225a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 2268561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 2272acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 228a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 229a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 231a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 232a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 233a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 234a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 235a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 236a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 246b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 251a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 252a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType()); 253a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateSub(Value, NonVirtualOffset); 254a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 255a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 256a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 257a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 261a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 262a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 263a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 264a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 265bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 266a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 26832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 27032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2715d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2735d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 27421c9ad9d29d08a287292c670e7c52bc522c7f8bbAnders Carlsson 275c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a 276c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases. 277314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, 278314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson bool ForVirtualBase) { 279af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (!CodeGenVTables::needsVTTParameter(GD)) { 280c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 281c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 282c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 283c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 284c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); 285c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2863b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 287c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 288c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2893b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall uint64_t SubVTTIndex; 2903b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 2913b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // If the record matches the base, this is the complete ctor/dtor 2923b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // variant calling the base variant in a class with virtual bases. 2933b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (RD == Base) { 294af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson assert(!CodeGenVTables::needsVTTParameter(CGF.CurGD) && 2953b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "doing no-op VTT offset in base dtor/ctor?"); 296314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson assert(!ForVirtualBase && "Can't have same class as virtual base!"); 2973b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall SubVTTIndex = 0; 2983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } else { 299c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson const ASTRecordLayout &Layout = 300c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.getContext().getASTRecordLayout(RD); 3014230d529a8797bbeef2328b60abeae333f7e143fKen Dyck CharUnits BaseOffset = ForVirtualBase ? 3024230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getVBaseClassOffset(Base) : 3034230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getBaseClassOffset(Base); 304c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 305c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson SubVTTIndex = 306c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 3073b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 3083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 309c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 310af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) { 311c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 312c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.LoadCXXVTT(); 313c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 314c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 315c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 3161cbce125b91cad81c8be3f8bbae8df917211176cAnders Carlsson VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD); 317c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 318c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 319c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 320c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 321c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 323182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 32450da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the destructor for a direct base class. 3251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallBaseDtor : EHScopeStack::Cleanup { 32650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *BaseClass; 32750da2cadcc6da86abff6772de65280ace2cabc94John McCall bool BaseIsVirtual; 32850da2cadcc6da86abff6772de65280ace2cabc94John McCall CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 32950da2cadcc6da86abff6772de65280ace2cabc94John McCall : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 330182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 331ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 33250da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *DerivedClass = 33350da2cadcc6da86abff6772de65280ace2cabc94John McCall cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 33450da2cadcc6da86abff6772de65280ace2cabc94John McCall 33550da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *D = BaseClass->getDestructor(); 33650da2cadcc6da86abff6772de65280ace2cabc94John McCall llvm::Value *Addr = 33750da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 33850da2cadcc6da86abff6772de65280ace2cabc94John McCall DerivedClass, BaseClass, 33950da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseIsVirtual); 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, Addr); 341182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 342182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 3437e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3447e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// A visitor which checks whether an initializer uses 'this' in a 3457e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// way which requires the vtable to be properly set. 3467e1dff7a68a4d00e71debafa7f5c259473091746John McCall struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 3477e1dff7a68a4d00e71debafa7f5c259473091746John McCall typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 3487e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3497e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool UsesThis; 3507e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3517e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 3527e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3537e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Black-list all explicit and implicit references to 'this'. 3547e1dff7a68a4d00e71debafa7f5c259473091746John McCall // 3557e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Do we need to worry about external references to 'this' derived 3567e1dff7a68a4d00e71debafa7f5c259473091746John McCall // from arbitrary code? If so, then anything which runs arbitrary 3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall // external code might potentially access the vtable. 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall }; 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCallstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker Checker(C); 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall Checker.Visit(const_cast<Expr*>(Init)); 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall return Checker.UsesThis; 366182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 367182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 368607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 369607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 370cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *BaseInit, 371607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 38180638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson bool isBaseVirtual = BaseInit->isBaseVirtual(); 382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 3877e1dff7a68a4d00e71debafa7f5c259473091746John McCall // If the initializer for the base (other than the constructor 3887e1dff7a68a4d00e71debafa7f5c259473091746John McCall // itself) accesses 'this' in any way, we need to initialize the 3897e1dff7a68a4d00e71debafa7f5c259473091746John McCall // vtables. 3907e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 3917e1dff7a68a4d00e71debafa7f5c259473091746John McCall CGF.InitializeVTablePointers(ClassDecl); 3927e1dff7a68a4d00e71debafa7f5c259473091746John McCall 393bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 394bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 3958561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson llvm::Value *V = 3968561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 39750da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseClassDecl, 39850da2cadcc6da86abff6772de65280ace2cabc94John McCall isBaseVirtual); 399d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = CGF.getContext().getTypeAlignInChars(BaseType); 4007c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot AggSlot = 401f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(V, Alignment, Qualifiers(), 4027c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 403410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 404410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased); 405558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 406558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 407594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 4087a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson if (CGF.CGM.getLangOptions().Exceptions && 409c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson !BaseClassDecl->hasTrivialDestructor()) 4101f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 4111f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall isBaseVirtual); 412607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 413607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 414fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregorstatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 415fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue LHS, 4160bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Expr *Init, 417fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar, 418fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType T, 4190bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes, 420fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned Index) { 4210bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Index == ArrayIndexes.size()) { 422f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman LValue LV = LHS; 423924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl { // Scope for Cleanups. 424924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CodeGenFunction::RunCleanupsScope Cleanups(CGF); 425924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 426924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (ArrayIndexVar) { 427924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // If we have an array index variable, load it and use it as an offset. 428924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Then, increment the value. 429924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Dest = LHS.getAddress(); 430924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 431924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 432924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 433924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 434924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.Builder.CreateStore(Next, ArrayIndexVar); 435924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 436924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Update the LValue. 437924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAddress(Dest); 438924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CharUnits Align = CGF.getContext().getTypeAlignInChars(T); 439924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.setAlignment(std::min(Align, LV.getAlignment())); 440924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 441924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 442924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (!CGF.hasAggregateLLVMType(T)) { 443924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); 444924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else if (T->isAnyComplexType()) { 445924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(), 446924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl LV.isVolatileQualified()); 447924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else { 448924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot Slot = 449924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::forLValue(LV, 450924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::IsDestructed, 451924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::DoesNotNeedGCBarriers, 452924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl AggValueSlot::IsNotAliased); 453924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 454924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl CGF.EmitAggExpr(Init, Slot); 455924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 456fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 457558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 458924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // Now, outside of the initializer cleanup scope, destroy the backing array 459924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl // for a std::initializer_list member. 460972edf0534d8a50f87fac1d0ff34eb22f593df11Sebastian Redl CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init); 461924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 462fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 463fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 464fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 465fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 466fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(Array && "Array initialization without the array type?"); 467fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IndexVar 4680bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]); 469fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(IndexVar && "Array index variable not loaded"); 470fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 471fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Initialize this index variable to zero. 472fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value* Zero 473fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = llvm::Constant::getNullValue( 474fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.ConvertType(CGF.getContext().getSizeType())); 475fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, IndexVar); 476fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 477fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Start the loop with a block that tests the condition. 478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(CondBlock); 482fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Generate: if (loop-index < number-of-elements) fall to the loop body, 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // otherwise, go to the block after the for-loop. 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor uint64_t NumElements = Array->getSize().getZExtValue(); 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 488985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::Value *NumElementsPtr = 489985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::ConstantInt::get(Counter->getType(), NumElements); 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "isless"); 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If the condition is true, execute the body. 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ForBody); 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor { 500f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope Cleanups(CGF); 501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 502fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Inside the loop body recurse to emit the inner loop or, eventually, the 503fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // constructor call. 5040bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, 5050bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Array->getElementType(), ArrayIndexes, Index + 1); 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ContinueBlock); 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the increment of the loop counter. 511fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 512fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Counter = CGF.Builder.CreateLoad(IndexVar); 513fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 514fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(NextVal, IndexVar); 515fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 516fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Finally, branch back up to the condition for the next iteration. 517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBranch(CondBlock); 518fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 519fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the fall-through block. 520fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(AfterFor, true); 521fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor} 522182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 523182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 5241f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallMemberDtor : EHScopeStack::Cleanup { 5250bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman llvm::Value *V; 526182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall CXXDestructorDecl *Dtor; 527182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 5280bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman CallMemberDtor(llvm::Value *V, CXXDestructorDecl *Dtor) 5290bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman : V(V), Dtor(Dtor) {} 530182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 531ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 532182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 5330bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman V); 534182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 535182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 536182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 53785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl 53885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstatic bool hasTrivialCopyOrMoveConstructor(const CXXRecordDecl *Record, 53985ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl bool Moving) { 54085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl return Moving ? Record->hasTrivialMoveConstructor() : 54185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl Record->hasTrivialCopyConstructor(); 54285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl} 5430bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 544607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 546cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 547fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const CXXConstructorDecl *Constructor, 548fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 54900eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet assert(MemberInit->isAnyMemberInitializer() && 550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 5517a614d8380297fcd2bc23986241905d97222948cRichard Smith assert(MemberInit->getInit() && "Must have initializer!"); 552607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldDecl *Field = MemberInit->getAnyMember(); 5550bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 556607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 558a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall LValue LHS; 55906a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson 560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we are initializing an anonymous union field, drill down to the field. 56100eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (MemberInit->isIndirectMemberInitializer()) { 56200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, 56300eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet MemberInit->getIndirectMember(), 0); 56400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 565a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall } else { 566a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); 567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 5690bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Special case: if we are in a copy or move constructor, and we are copying 5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // an array of PODs or classes with trivial copy constructors, ignore the 5710bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // AST and perform the copy we know is equivalent. 5720bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // FIXME: This is hacky at best... if we had a bit more explicit information 5730bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // in the AST, we could generalize it more easily. 5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman const ConstantArrayType *Array 5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.getContext().getAsConstantArrayType(FieldType); 5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (Array && Constructor->isImplicitlyDefined() && 5770bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Constructor->isCopyOrMoveConstructor()) { 5780bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 5790bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl(); 5800bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (BaseElementTy.isPODType(CGF.getContext()) || 5810bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman (Record && hasTrivialCopyOrMoveConstructor(Record, 5820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman Constructor->isMoveConstructor()))) { 5830bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Find the source pointer. We knows it's the last argument because 5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // we know we're in a copy constructor. 5850bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned SrcArgIndex = Args.size() - 1; 5860bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman llvm::Value *SrcPtr 5870bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 5880bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0); 5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5900bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Copy the aggregate. 5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 5920bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman LHS.isVolatileQualified()); 5930bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman return; 5940bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5950bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } 5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 5970bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayRef<VarDecl *> ArrayIndexes; 5980bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (MemberInit->getNumArrayIndices()) 5990bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes = MemberInit->getArrayIndexes(); 600b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes); 6010bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman} 6020bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid CodeGenFunction::EmitInitializerForField(FieldDecl *Field, 604b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LValue LHS, Expr *Init, 605b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayRef<VarDecl *> ArrayIndexes) { 6060bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman QualType FieldType = Field->getType(); 607b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman if (!hasAggregateLLVMType(FieldType)) { 608f85e193739c953358c865005855253af4f68a497John McCall if (LHS.isSimple()) { 609b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitExprAsInit(Init, Field, LHS, false); 610f85e193739c953358c865005855253af4f68a497John McCall } else { 611b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman RValue RHS = RValue::get(EmitScalarExpr(Init)); 612b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitStoreThroughLValue(RHS, LHS); 613f85e193739c953358c865005855253af4f68a497John McCall } 6140bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman } else if (FieldType->isAnyComplexType()) { 615b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitComplexExprIntoAddr(Init, LHS.getAddress(), LHS.isVolatileQualified()); 616607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 617fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar = 0; 6180bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman if (ArrayIndexes.size()) { 619b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 621fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // The LHS is a pointer to the first object we'll be constructing, as 622fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // a flat array. 623b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman QualType BaseElementTy = getContext().getBaseElementType(FieldType); 624b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Type *BasePtr = ConvertType(BaseElementTy); 625fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr = llvm::PointerType::getUnqual(BasePtr); 626b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman llvm::Value *BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), 627b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman BasePtr); 628b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy); 629fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 630fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Create an array index that will be used to walk over all of the 631fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // objects we're constructing. 632b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman ArrayIndexVar = CreateTempAlloca(SizeTy, "object.index"); 633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 634b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman Builder.CreateStore(Zero, ArrayIndexVar); 635fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 636fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 637fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the block variables for the array indices, if any. 6380bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I) 639b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAutoVarDecl(*ArrayIndexes[I]); 640fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 641fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 642b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, 6430bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman ArrayIndexes, 0); 6449405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 645b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman if (!CGM.getLangOptions().Exceptions) 6469405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 6479405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 648fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // FIXME: If we have an array of classes w/ non-trivial destructors, 649fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // we need to destroy in reverse order of construction along the exception 650fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // path. 6519405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 6529405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson if (!RT) 6539405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 6549405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 6559405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 656182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall if (!RD->hasTrivialDestructor()) 657b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman EHStack.pushCleanup<CallMemberDtor>(EHCleanup, LHS.getAddress(), 658b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman RD->getDestructor()); 659607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 660607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 661607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Checks whether the given constructor is a valid subject for the 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// complete-to-base constructor delegation optimization, i.e. 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// emitting the complete constructor as a simple call to the base 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// constructor. 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallstatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Currently we disable the optimization for classes with virtual 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // bases because (1) the addresses of parameter variables need to be 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // consistent across all initializers but (2) the delegate function 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // call necessarily creates a second copy of the parameter variable. 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // The limiting example (purely theoretical AFAIK): 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct A { A(int &c) { c++; } }; 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct B : virtual A { 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // B(int count) : A(count) { printf("%d\n", count); } 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // }; 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // ...although even this example could in principle be emitted as a 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation since the address of the parameter doesn't escape. 680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getParent()->getNumVBases()) { 681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list trivial vbase initializers. This case wouldn't 682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // be subject to the restrictions below. 683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list cases where: 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - there are no non-reference parameters to the constructor 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't access any non-reference parameters 687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't take the address of non-reference 688c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // parameters 689c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - etc. 690c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // If we ever add any of the above cases, remember that: 691c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - function-try-blocks will always blacklist this optimization 692c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - we need to perform the constructor prologue and cleanup in 693c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // EmitConstructorBody. 694c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 695c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 696c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 698c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // We also disable the optimization for variadic functions because 699c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // it's impossible to "re-pass" varargs. 700c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 701c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 702c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 703059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt // FIXME: Decide if we can do a delegation of a delegating constructor. 704059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (Ctor->isDelegatingConstructor()) 705059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return false; 706059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 707c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return true; 708c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 709c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7109fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitConstructorBody - Emits the body of the current constructor. 7119fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 7129fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 7139fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXCtorType CtorType = CurGD.getCtorType(); 7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 715c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Before we go any further, try the complete->base constructor 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation optimization. 717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor)) { 718d67ef0eed463b43980f04a444155f423114be34bDevang Patel if (CGDebugInfo *DI = getDebugInfo()) 71973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, Ctor->getLocEnd()); 720c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args); 721c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return; 722c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 723c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7249fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Ctor->getBody(); 7259fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 726c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Enter the function-try-block before the constructor prologue if 727c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // applicable. 728c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 729c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 73059a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7319fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 732f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); 7339fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 734c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Emit the constructor prologue, i.e. the base and member 735c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // initializers. 736fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitCtorPrologue(Ctor, CtorType, Args); 7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit the body of the statement. 739c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 7419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall else if (Body) 7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(Body); 7439fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7449fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit any cleanup blocks associated with the member or base 7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // initializers, which includes (along the exceptional path) the 7469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // destructors for those members and bases that were fully 7479fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // constructed. 748f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall PopCleanupBlocks(CleanupDepth); 7499fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 750c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 75159a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7529fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 7539fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 754607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 757fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CXXCtorType CtorType, 758fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 759059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (CD->isDelegatingConstructor()) 760059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return EmitDelegatingCXXConstructorCall(CD, Args); 761059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 763a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 7645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer *, 8> MemberInitializers; 765607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 766607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 767607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 768607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 769cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *Member = (*B); 770607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 771d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt if (Member->isBaseInitializer()) { 772607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 773d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } else { 774d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt assert(Member->isAnyMemberInitializer() && 775d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt "Delegating initializer on non-delegating constructor"); 776a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson MemberInitializers.push_back(Member); 777d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } 778607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 779607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 780603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson InitializeVTablePointers(ClassDecl); 781a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 782f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) 783fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args); 784607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 785607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 786adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 787adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 788adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 789adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 790adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonHasTrivialDestructorBody(ASTContext &Context, 791adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *BaseClassDecl, 792adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl) 793adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 794adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // If the destructor is trivial we don't have to check anything else. 795adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 796adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 797adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 798adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 799adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 800adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 801adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check fields. 802adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(), 803adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson E = BaseClassDecl->field_end(); I != E; ++I) { 804adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field = *I; 805adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 806adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 807adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 808adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 809adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 810adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check non-virtual bases. 811adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 812adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end(); 813adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 814adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (I->isVirtual()) 815adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson continue; 816adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 817adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *NonVirtualBase = 818adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 819adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, NonVirtualBase, 820adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 821adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 822adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 823adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 824adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl == MostDerivedClassDecl) { 825adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check virtual bases. 826adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 827adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); 828adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 829adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *VirtualBase = 830adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 831adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, VirtualBase, 832adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 833adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 834adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 835adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 836adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 837adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 838adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 839adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 840adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 841adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, 842adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field) 843adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 844adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 845adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 846adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 847adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!RT) 848adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 849adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 850adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 851adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 852adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 853adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 854ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// CanSkipVTablePointerInitialization - Check whether we need to initialize 855ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// any vtable pointers before calling this destructor. 856ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlssonstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 857e3d6cf2149beb1c215ea6e87023c27b4f37712adAnders Carlsson const CXXDestructorDecl *Dtor) { 858ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!Dtor->hasTrivialBody()) 859ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return false; 860ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 861ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson // Check the fields. 862ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const CXXRecordDecl *ClassDecl = Dtor->getParent(); 863ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 864ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 865ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const FieldDecl *Field = *I; 866ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 867adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 868adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 869ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson } 870ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 871ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return true; 872ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson} 873ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 8749fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitDestructorBody - Emits the body of the current destructor. 8759fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 8769fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 8779fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXDtorType DtorType = CurGD.getDtorType(); 8789fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 87950da2cadcc6da86abff6772de65280ace2cabc94John McCall // The call to operator delete in a deleting destructor happens 88050da2cadcc6da86abff6772de65280ace2cabc94John McCall // outside of the function-try-block, which means it's always 88150da2cadcc6da86abff6772de65280ace2cabc94John McCall // possible to delegate the destructor body to the complete 88250da2cadcc6da86abff6772de65280ace2cabc94John McCall // destructor. Do so. 88350da2cadcc6da86abff6772de65280ace2cabc94John McCall if (DtorType == Dtor_Deleting) { 88450da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Deleting); 88550da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 88650da2cadcc6da86abff6772de65280ace2cabc94John McCall LoadCXXThis()); 88750da2cadcc6da86abff6772de65280ace2cabc94John McCall PopCleanupBlock(); 88850da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 88950da2cadcc6da86abff6772de65280ace2cabc94John McCall } 89050da2cadcc6da86abff6772de65280ace2cabc94John McCall 8919fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Dtor->getBody(); 8929fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 8939fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If the body is a function-try-block, enter the try before 89450da2cadcc6da86abff6772de65280ace2cabc94John McCall // anything else. 89550da2cadcc6da86abff6772de65280ace2cabc94John McCall bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 8969fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 89759a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8989fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 89950da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the epilogue cleanups. 90050da2cadcc6da86abff6772de65280ace2cabc94John McCall RunCleanupsScope DtorEpilogue(*this); 90150da2cadcc6da86abff6772de65280ace2cabc94John McCall 9029fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If this is the complete variant, just invoke the base variant; 9039fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // the epilogue will destruct the virtual bases. But we can't do 9049fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // this optimization if the body is a function-try-block, because 9059fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // we'd introduce *two* handler blocks. 90650da2cadcc6da86abff6772de65280ace2cabc94John McCall switch (DtorType) { 90750da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 90850da2cadcc6da86abff6772de65280ace2cabc94John McCall 90950da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Complete: 91050da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for virtual bases. 91150da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Complete); 91250da2cadcc6da86abff6772de65280ace2cabc94John McCall 91350da2cadcc6da86abff6772de65280ace2cabc94John McCall if (!isTryBody) { 91450da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 91550da2cadcc6da86abff6772de65280ace2cabc94John McCall LoadCXXThis()); 91650da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 91750da2cadcc6da86abff6772de65280ace2cabc94John McCall } 91850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Fallthrough: act like we're in the base variant. 9199fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 92050da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Base: 92150da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for fields and non-virtual bases. 92250da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Base); 92350da2cadcc6da86abff6772de65280ace2cabc94John McCall 92450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Initialize the vtable pointers before entering the body. 925ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 926ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson InitializeVTablePointers(Dtor->getParent()); 9279fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 92850da2cadcc6da86abff6772de65280ace2cabc94John McCall if (isTryBody) 92950da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 93050da2cadcc6da86abff6772de65280ace2cabc94John McCall else if (Body) 93150da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(Body); 93250da2cadcc6da86abff6772de65280ace2cabc94John McCall else { 93350da2cadcc6da86abff6772de65280ace2cabc94John McCall assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 93450da2cadcc6da86abff6772de65280ace2cabc94John McCall // nothing to do besides what's in the epilogue 93550da2cadcc6da86abff6772de65280ace2cabc94John McCall } 9365abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // -fapple-kext must inline any call to this dtor into 9375abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // the caller's body. 9385abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian if (getContext().getLangOptions().AppleKext) 9395abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 94050da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 9419fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } 9429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 94350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Jump out through the epilogue cleanups. 94450da2cadcc6da86abff6772de65280ace2cabc94John McCall DtorEpilogue.ForceCleanup(); 9459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 9469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Exit the try if applicable. 9479fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 94859a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 9499fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 9509fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 95150da2cadcc6da86abff6772de65280ace2cabc94John McCallnamespace { 95250da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the operator delete associated with the current destructor. 9531f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallDtorDelete : EHScopeStack::Cleanup { 95450da2cadcc6da86abff6772de65280ace2cabc94John McCall CallDtorDelete() {} 95550da2cadcc6da86abff6772de65280ace2cabc94John McCall 956ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 95750da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 95850da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = Dtor->getParent(); 95950da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 96050da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.getContext().getTagDeclType(ClassDecl)); 96150da2cadcc6da86abff6772de65280ace2cabc94John McCall } 96250da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 96350da2cadcc6da86abff6772de65280ace2cabc94John McCall 9649928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall class DestroyField : public EHScopeStack::Cleanup { 9659928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field; 966516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne CodeGenFunction::Destroyer *destroyer; 9679928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray; 9689928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 9699928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall public: 9709928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 9719928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray) 972516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne : field(field), destroyer(destroyer), 9739928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall useEHCleanupForArray(useEHCleanupForArray) {} 9749928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 975ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 9769928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall // Find the address of the field. 9779928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall llvm::Value *thisValue = CGF.LoadCXXThis(); 9789928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0); 9799928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall assert(LV.isSimple()); 9809928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 9819928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 982ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall flags.isForNormalCleanup() && useEHCleanupForArray); 98350da2cadcc6da86abff6772de65280ace2cabc94John McCall } 98450da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 98550da2cadcc6da86abff6772de65280ace2cabc94John McCall} 98650da2cadcc6da86abff6772de65280ace2cabc94John McCall 987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 99050da2cadcc6da86abff6772de65280ace2cabc94John McCallvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 99150da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXDtorType DtorType) { 992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 99550da2cadcc6da86abff6772de65280ace2cabc94John McCall // The deleting-destructor phase just needs to call the appropriate 99650da2cadcc6da86abff6772de65280ace2cabc94John McCall // operator delete that Sema picked up. 9973b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Deleting) { 9983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DD->getOperatorDelete() && 9993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "operator delete missing - EmitDtorEpilogue"); 10001f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 10013b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 10023b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 10033b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 100450da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = DD->getParent(); 100550da2cadcc6da86abff6772de65280ace2cabc94John McCall 1006416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith // Unions have no bases and do not call field destructors. 1007416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith if (ClassDecl->isUnion()) 1008416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith return; 1009416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith 101050da2cadcc6da86abff6772de65280ace2cabc94John McCall // The complete-destructor phase just destructs all the virtual bases. 10113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Complete) { 101250da2cadcc6da86abff6772de65280ace2cabc94John McCall 101350da2cadcc6da86abff6772de65280ace2cabc94John McCall // We push them in the forward order so that they'll be popped in 101450da2cadcc6da86abff6772de65280ace2cabc94John McCall // the reverse order. 101550da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 101650da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); 10173b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall I != E; ++I) { 10183b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall const CXXBaseSpecifier &Base = *I; 10193b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall CXXRecordDecl *BaseClassDecl 10203b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 10213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 10223b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Ignore trivial destructors. 10233b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (BaseClassDecl->hasTrivialDestructor()) 10243b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall continue; 102550da2cadcc6da86abff6772de65280ace2cabc94John McCall 10261f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 10271f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 10281f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ true); 10293b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 103050da2cadcc6da86abff6772de65280ace2cabc94John McCall 10313b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 10323b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 10333b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 10343b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DtorType == Dtor_Base); 103550da2cadcc6da86abff6772de65280ace2cabc94John McCall 103650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy non-virtual bases. 103750da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 103850da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 103950da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXBaseSpecifier &Base = *I; 104050da2cadcc6da86abff6772de65280ace2cabc94John McCall 104150da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore virtual bases. 104250da2cadcc6da86abff6772de65280ace2cabc94John McCall if (Base.isVirtual()) 104350da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 104450da2cadcc6da86abff6772de65280ace2cabc94John McCall 104550da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 104650da2cadcc6da86abff6772de65280ace2cabc94John McCall 104750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore trivial destructors. 104850da2cadcc6da86abff6772de65280ace2cabc94John McCall if (BaseClassDecl->hasTrivialDestructor()) 104950da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 10503b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 10511f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 10521f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 10531f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ false); 105450da2cadcc6da86abff6772de65280ace2cabc94John McCall } 105550da2cadcc6da86abff6772de65280ace2cabc94John McCall 105650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy direct fields. 10575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const FieldDecl *, 16> FieldDecls; 1058607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1059607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 10609928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field = *I; 10619928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType type = field->getType(); 10629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 10639928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall if (!dtorKind) continue; 10649928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 10659928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CleanupKind cleanupKind = getCleanupKind(dtorKind); 10669928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall EHStack.pushCleanup<DestroyField>(cleanupKind, field, 10679928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall getDestroyer(dtorKind), 10689928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall cleanupKind & EHCleanup); 1069607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1070607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1071607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1072c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1073c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 107459174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor/// 1075c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1076c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param argBegin,argEnd the arguments to evaluate and pass to the 1077c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor 1078c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayType the type of the array to initialize 1079c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin an arrayType* 1080c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1081c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1083c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1084c3c0766277cd64bf117450a1519c9cf762d994d4John McCall const ConstantArrayType *arrayType, 1085c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1086c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1087c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1088c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1089c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType elementType; 1090c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements = 1091c3c0766277cd64bf117450a1519c9cf762d994d4John McCall emitArrayLength(arrayType, elementType, arrayBegin); 1092c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1093c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1094c3c0766277cd64bf117450a1519c9cf762d994d4John McCall argBegin, argEnd, zeroInitialize); 10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1097c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1098c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 1099c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// 1100c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1101c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param numElements the number of elements in the array; 1102dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall/// may be zero 1103c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param argBegin,argEnd the arguments to evaluate and pass to the 1104c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor 1105c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin a T*, where T is the type constructed by ctor 1106c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1107c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1109c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1110c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements, 1111c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1112c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1113c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1114c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1115dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1116dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // It's legal for numElements to be zero. This can happen both 1117dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // dynamically, because x can be zero in 'new A[x]', and statically, 1118dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // because of GCC extensions that permit zero-length arrays. There 1119dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // are probably legitimate places where we could assume that this 1120dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // doesn't happen, but it's not clear that it's worth it. 1121dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BranchInst *zeroCheckBranch = 0; 1122dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1123dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Optimize for a constant count. 1124dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::ConstantInt *constantCount 1125dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall = dyn_cast<llvm::ConstantInt>(numElements); 1126dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount) { 1127dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Just skip out if the constant count is zero. 1128dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount->isZero()) return; 1129dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1130dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Otherwise, emit the check. 1131dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } else { 1132dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1133dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1134dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1135dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall EmitBlock(loopBB); 1136dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } 1137dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1138c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Find the end of the array. 1139c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1140c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.end"); 1141c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1142c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Enter the loop, setting up a phi for the current location to initialize. 1143c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1144c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1145c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(loopBB); 1146c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1147c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.cur"); 1148c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(arrayBegin, entryBB); 11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 1151c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1152c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType type = getContext().getTypeDeclType(ctor->getParent()); 11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 115459174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor // Zero initialize the storage, if requested. 1155c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (zeroInitialize) 1156c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitNullInitialization(cur, type); 115759174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor 11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 116644ec82b4a1597802f5bf17721481b8c265bc8dc5Anders Carlsson { 1167f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1169c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Evaluate the constructor and its arguments in a regular 1170c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // partial-destroy cleanup. 1171c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (getLangOptions().Exceptions && 1172c3c0766277cd64bf117450a1519c9cf762d994d4John McCall !ctor->getParent()->hasTrivialDestructor()) { 1173c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Destroyer *destroyer = destroyCXXObject; 1174c3c0766277cd64bf117450a1519c9cf762d994d4John McCall pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1175c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1177c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1178c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur, argBegin, argEnd); 1179c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1181c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Go to the next element. 1182c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *next = 1183c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1184c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.next"); 1185c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(next, Builder.GetInsertBlock()); 11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1187c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Check whether that's the end of the loop. 1188c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1189c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1190c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateCondBr(done, contBB, loopBB); 11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1192dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Patch the earlier check to skip over the loop. 1193dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1194dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1195c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(contBB); 11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1198bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1199bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall llvm::Value *addr, 1200bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall QualType type) { 1201bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const RecordType *rtype = type->castAs<RecordType>(); 1202bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1203bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXDestructorDecl *dtor = record->getDestructor(); 1204bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall assert(!dtor->isTrivial()); 1205bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1206bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall addr); 1207bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall} 1208bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall 12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1211155ed4a23366f4514befb1c9f5f89d16f8b8b6dbAnders Carlsson CXXCtorType Type, bool ForVirtualBase, 12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 12153ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 12163ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel CGDebugInfo *DI = getDebugInfo(); 12173ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel if (DI && CGM.getCodeGenOpts().LimitDebugInfo) { 1218af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // If debug info for this class has not been emitted then this is the 1219af790885c7890f3d205bd4715161289bc8aa3f29Eric Christopher // right time to do so. 12203ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel const CXXRecordDecl *Parent = D->getParent(); 12213ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel DI->getOrCreateRecordType(CGM.getContext().getTypeDeclType(Parent), 12223ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel Parent->getLocation()); 12233ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel } 12243ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 12258b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 12268b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 12278b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 12288b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 12298b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12328b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12338b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 123485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 123585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 12368b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12378b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 12388b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 12398b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 12408b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1244314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type), ForVirtualBase); 12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1247c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); 12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1250c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallvoid 125134999876e215b22febc240b1a6dc054215d12f9cFariborz JahanianCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 125234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *This, llvm::Value *Src, 125334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgBeg, 125434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgEnd) { 125534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian if (D->isTrivial()) { 125634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 125785ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 125885ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 125934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 126034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian return; 126134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 126234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, 126334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian clang::Ctor_Complete); 126434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(D->isInstance() && 126534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Trying to emit a member call expr on a static method!"); 126634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 126734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 126834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 126934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallArgList Args; 127034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 127134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the this ptr. 127204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(This), D->getThisType(getContext())); 127334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 127434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 127534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the src ptr. 127634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType QT = *(FPT->arg_type_begin()); 12772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *t = CGM.getTypes().ConvertType(QT); 127834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian Src = Builder.CreateBitCast(Src, t); 127904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(Src), QT); 128034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 128134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Skip over first argument (Src). 128234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian ++ArgBeg; 128334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator Arg = ArgBeg; 128434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, 128534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian E = FPT->arg_type_end(); I != E; ++I, ++Arg) { 128634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(Arg != ArgEnd && "Running over edge of argument list!"); 1287413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, *I); 128834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 128934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Either we've emitted all the call args, or we have a call to a 129034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // variadic function. 129134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert((Arg == ArgEnd || FPT->isVariadic()) && 129234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Extra arguments in non-variadic function!"); 129334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // If we still have any arguments, emit them using the type of the argument. 129434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (; Arg != ArgEnd; ++Arg) { 129534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType ArgType = Arg->getType(); 1296413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, ArgType); 129734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 129834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 1299de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall EmitCall(CGM.getTypes().arrangeFunctionCall(Args, FPT), Callee, 1300c55db3b76df62f2c89e9bcc7437d1065512fb139Eli Friedman ReturnValueSlot(), Args, D); 130134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian} 130234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 130334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanianvoid 1304c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1305c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CXXCtorType CtorType, 1306c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall const FunctionArgList &Args) { 1307c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CallArgList DelegateArgs; 1308c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1309c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1310c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "no parameters to constructor"); 1311c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1312c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // this 131304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1314c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1315c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1316c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // vtt 1317314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType), 1318314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson /*ForVirtualBase=*/false)) { 1319c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 132004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(VTT), VoidPP); 1321c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1322af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD)) { 1323c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "cannot skip vtt parameter, already done with args"); 1324d26bc76c98006609002d9930f8840490e88ac5b5John McCall assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1325c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1326c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1327c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1328c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1329c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Explicit arguments. 1330c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall for (; I != E; ++I) { 1331413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall const VarDecl *param = *I; 1332413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitDelegateCallArg(DelegateArgs, param); 1333c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1334c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1335de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), 1336c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CGM.GetAddrOfCXXConstructor(Ctor, CtorType), 1337c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ReturnValueSlot(), DelegateArgs, Ctor); 1338c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 1339c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1340b76af9c969558b4484be87933e89e76e7ee87e21Sean Huntnamespace { 1341b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1342b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXDestructorDecl *Dtor; 1343b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt llvm::Value *Addr; 1344b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type; 1345b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1346b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1347b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type) 1348b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt : Dtor(D), Addr(Addr), Type(Type) {} 1349b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1350ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1351b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1352b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt Addr); 1353b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1354b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt }; 1355b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1356b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1357059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Huntvoid 1358059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean HuntCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1359059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt const FunctionArgList &Args) { 1360059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt assert(Ctor->isDelegatingConstructor()); 1361059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1362059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt llvm::Value *ThisPtr = LoadCXXThis(); 1363059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1364f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman QualType Ty = getContext().getTagDeclType(Ctor->getParent()); 1365d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = getContext().getTypeAlignInChars(Ty); 1366f85e193739c953358c865005855253af4f68a497John McCall AggValueSlot AggSlot = 1367f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(), 13687c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 1369410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 1370410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased); 1371059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1372059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1373059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1374b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXRecordDecl *ClassDecl = Ctor->getParent(); 1375b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt if (CGM.getLangOptions().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1376b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type = 1377b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1378b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1379b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1380b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ClassDecl->getDestructor(), 1381b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ThisPtr, Type); 1382b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1383b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1384059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 13853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 13863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 13878e6404ca28d6bbb76e97ea2a53a74816c2a74665Anders Carlsson bool ForVirtualBase, 13883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1389314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type), 1390314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson ForVirtualBase); 1391ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian llvm::Value *Callee = 0; 1392ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (getContext().getLangOptions().AppleKext) 1393771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 1394771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian DD->getParent()); 1395ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian 1396ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (!Callee) 1397ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 13983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1399c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); 14003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 14013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1402291ae949612e371c41bf771a483b407d49372a4fJohn McCallnamespace { 14031f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallLocalDtor : EHScopeStack::Cleanup { 1404291ae949612e371c41bf771a483b407d49372a4fJohn McCall const CXXDestructorDecl *Dtor; 1405291ae949612e371c41bf771a483b407d49372a4fJohn McCall llvm::Value *Addr; 1406291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1407291ae949612e371c41bf771a483b407d49372a4fJohn McCall CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1408291ae949612e371c41bf771a483b407d49372a4fJohn McCall : Dtor(D), Addr(Addr) {} 1409291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1410ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1411291ae949612e371c41bf771a483b407d49372a4fJohn McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1412291ae949612e371c41bf771a483b407d49372a4fJohn McCall /*ForVirtualBase=*/false, Addr); 1413291ae949612e371c41bf771a483b407d49372a4fJohn McCall } 1414291ae949612e371c41bf771a483b407d49372a4fJohn McCall }; 1415291ae949612e371c41bf771a483b407d49372a4fJohn McCall} 1416291ae949612e371c41bf771a483b407d49372a4fJohn McCall 141781407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCallvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 141881407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall llvm::Value *Addr) { 14191f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 142081407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall} 142181407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall 1422f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1423f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1424f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!ClassDecl) return; 1425f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ClassDecl->hasTrivialDestructor()) return; 1426f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1427f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1428642a75f883e644bcfbb82e7af0313776ad1ce33cJohn McCall assert(D && D->isUsed() && "destructor not marked as used!"); 142981407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall PushDestructorCleanup(D, Addr); 1430f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1431f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 14323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1433bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1434bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 14353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 1436043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); 143714c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck CharUnits VBaseOffsetOffset = 14381d2b31710539d705a3850c9fc3aa1804c2a5efeePeter Collingbourne CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); 14393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 144114c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 144214c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck "vbase.offset.ptr"); 14432acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 14443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 14453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 14473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 14483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 14503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 14523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 14533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1454d103f9f9b401b419e756f8c1849683cd77586067Anders Carlssonvoid 1455d103f9f9b401b419e756f8c1849683cd77586067Anders CarlssonCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1456b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1457d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1458d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson llvm::Constant *VTable, 1459d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson const CXXRecordDecl *VTableClass) { 1460c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 1461c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1462d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute the address point. 1463c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTableAddressPoint; 1464851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson 1465c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Check if we need to use a vtable from the VTT. 1466851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && 1467b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson (RD->getNumVBases() || NearestVBase)) { 1468c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Get the secondary vpointer index. 1469c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson uint64_t VirtualPointerIndex = 1470c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 1471c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1472c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson /// Load the VTT. 1473c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTT = LoadCXXVTT(); 1474c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson if (VirtualPointerIndex) 1475c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 1476c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1477c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // And load the address point from the VTT. 1478c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = Builder.CreateLoad(VTT); 1479c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } else { 148084fcc48817bb04c7de1acafcaa1f54ee3235a97bPeter Collingbourne uint64_t AddressPoint = 1481e09cdf46aa2b86c24e6bf7a7ead2eaded964f2ffPeter Collingbourne CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base); 1482c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = 1483d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); 1484c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } 1485d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1486d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute where to store the address point. 14878246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VirtualOffset = 0; 14889a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtualOffset = CharUnits::Zero(); 14893e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson 14903e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { 14913e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // We need to use the virtual base offset offset because the virtual base 14923e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // might have a different offset in the most derived class. 14938246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, 14948246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NearestVBase); 1495d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck NonVirtualOffset = OffsetFromNearestVBase; 14963e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } else { 14978246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // We can just use the base offset in the complete class. 14984230d529a8797bbeef2328b60abeae333f7e143fKen Dyck NonVirtualOffset = Base.getBaseOffset(); 14993e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } 15008246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 15018246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // Apply the offsets. 15028246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VTableField = LoadCXXThis(); 15038246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 15049a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtualOffset.isZero() || VirtualOffset) 15058246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 15068246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NonVirtualOffset, 15078246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset); 150836fd6beef1ffaf93217d8ce96d900d4ed817e463Anders Carlsson 1509d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Finally, store the address point. 15102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *AddressPointPtrTy = 1511d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableAddressPoint->getType()->getPointerTo(); 1512d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 1513d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateStore(VTableAddressPoint, VTableField); 1514d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 1515d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1516603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid 1517603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders CarlssonCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1518b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1519d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1520603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson bool BaseIsNonVirtualPrimaryBase, 1521603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable, 1522603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *VTableClass, 1523603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy& VBases) { 1524603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // If this base is a non-virtual primary base the address point has already 1525603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // been set. 1526603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseIsNonVirtualPrimaryBase) { 1527603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointer for this base. 15284235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 15294235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson VTable, VTableClass); 1530603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 15314658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1532603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 15334658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1534603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Traverse bases. 1535603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1536603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson E = RD->bases_end(); I != E; ++I) { 15370703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson CXXRecordDecl *BaseDecl 15380703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1539603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1540603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 1541603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseDecl->isDynamicClass()) 1542603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1543603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1544d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffset; 1545d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffsetFromNearestVBase; 154614da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson bool BaseDeclIsNonVirtualPrimaryBase; 1547603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1548603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (I->isVirtual()) { 1549603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Check if we've visited this virtual base before. 1550603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!VBases.insert(BaseDecl)) 1551603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1552603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1553603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = 1554603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson getContext().getASTRecordLayout(VTableClass); 1555603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1556d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1557d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffsetFromNearestVBase = CharUnits::Zero(); 155814da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = false; 1559603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } else { 1560603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1561603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 15624230d529a8797bbeef2328b60abeae333f7e143fKen Dyck BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 15634235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase = 1564d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 156514da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 1566603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 15670703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson 15684230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 1569b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson I->isVirtual() ? BaseDecl : NearestVBase, 15704235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase, 157114da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase, 1572603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, VTableClass, VBases); 15733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 15743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 15753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1576603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 1577603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 15780703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson if (!RD->isDynamicClass()) 15793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 15803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1581603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Get the VTable. 1582603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD); 15833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1584603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointers for this class and all of its bases. 1585603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy VBases; 15864230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 15874230d529a8797bbeef2328b60abeae333f7e143fKen Dyck /*NearestVBase=*/0, 1588d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck /*OffsetFromNearestVBase=*/CharUnits::Zero(), 1589603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson /*BaseIsNonVirtualPrimaryBase=*/false, 1590603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, RD, VBases); 15913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1592043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman 1593043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohmanllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 15942acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty) { 1595043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 1596043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman return Builder.CreateLoad(VTablePtrSrc, "vtable"); 1597043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman} 1598a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1599a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { 1600a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const Expr *E = Base; 1601a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1602a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 1603a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = E->IgnoreParens(); 1604a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 1605a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_DerivedToBase || 1606a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_UncheckedDerivedToBase || 1607a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_NoOp) { 1608a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 1609a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1610a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1611a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1612a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1613a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson break; 1614a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1615a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1616a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson QualType DerivedType = E->getType(); 1617a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const PointerType *PTy = DerivedType->getAs<PointerType>()) 1618a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson DerivedType = PTy->getPointeeType(); 1619a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1620a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return cast<CXXRecordDecl>(DerivedType->castAs<RecordType>()->getDecl()); 1621a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1622a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1623a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 1624a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// quite what we want. 1625a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 1626a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 1627a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 1628a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = PE->getSubExpr(); 1629a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1630a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1631a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1632a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 1633a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_NoOp) { 1634a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 1635a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1636a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1637a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1638a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 1639a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UO->getOpcode() == UO_Extension) { 1640a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = UO->getSubExpr(); 1641a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1642a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1643a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1644a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return E; 1645a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1646a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1647a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1648a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// canDevirtualizeMemberFunctionCall - Checks whether the given virtual member 1649a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// function call on the given expr can be devirtualized. 1650a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool canDevirtualizeMemberFunctionCall(const Expr *Base, 1651a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 1652a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the most derived class is marked final, we know that no subclass can 1653a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // override this member function and so we can devirtualize it. For example: 1654a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1655a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct A { virtual void f(); } 1656a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct B final : A { }; 1657a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1658a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // void f(B *b) { 1659a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // b->f(); 1660a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // } 1661a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1662a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base); 1663a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 1664a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1665a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1666a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the member function is marked 'final', we know that it can't be 1667a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // overridden and can therefore devirtualize it. 1668a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->hasAttr<FinalAttr>()) 1669a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1670a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1671a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Similarly, if the class itself is marked 'final' it can't be overridden 1672a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // and we can therefore devirtualize the member function call. 1673a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->getParent()->hasAttr<FinalAttr>()) 1674a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1675a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1676a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson Base = skipNoOpCastsAndParens(Base); 1677a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 1678a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 1679a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // This is a record decl. We know the type and can devirtualize it. 1680a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return VD->getType()->isRecordType(); 1681a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1682a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1683a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1684a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1685a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1686a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can always devirtualize calls on temporary object expressions. 1687a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXConstructExpr>(Base)) 1688a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1689a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1690a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // And calls on bound temporaries. 1691a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXBindTemporaryExpr>(Base)) 1692a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1693a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1694a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Check if this is a call expr that returns a record type. 1695a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 1696a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CE->getCallReturnType()->isRecordType(); 1697a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1698a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can't devirtualize the call. 1699a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1700a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1701a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1702a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool UseVirtualCall(ASTContext &Context, 1703a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXOperatorCallExpr *CE, 1704a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 1705a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (!MD->isVirtual()) 1706a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1707a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1708a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // When building with -fapple-kext, all calls must go through the vtable since 1709a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // the kernel linker can do runtime patching of vtables. 1710a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (Context.getLangOptions().AppleKext) 1711a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1712a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1713a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD); 1714a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1715a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1716a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonllvm::Value * 1717a2447e0d1e28669cd637204a871f15b1215277fdAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 1718a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD, 1719a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson llvm::Value *This) { 1720de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *fnType = 1721de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().GetFunctionType( 1722de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeCXXMethodDeclaration(MD)); 1723a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1724a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UseVirtualCall(getContext(), E, MD)) 1725de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return BuildVirtualCall(MD, This, fnType); 1726a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1727de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return CGM.GetAddrOfFunction(MD, fnType); 1728a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1729bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman 173064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *Lambda, 173164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList &CallArgs) { 173264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Lookup the call operator 173321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman DeclarationName Name 173421f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman = getContext().DeclarationNames.getCXXOperatorName(OO_Call); 173521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman DeclContext::lookup_const_result Calls = Lambda->lookup(Name); 173627dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(*Calls.first++); 173764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const FunctionProtoType *FPT = 173864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallOperator->getType()->getAs<FunctionProtoType>(); 173921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman QualType ResultType = FPT->getResultType(); 174021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 174121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Get the address of the call operator. 174227dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor GlobalDecl GD(CallOperator); 1743de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const CGFunctionInfo &CalleeFnInfo = 1744de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionCall(ResultType, CallArgs, FPT->getExtInfo(), 1745de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall RequiredArgs::forPrototypePlus(FPT, 1)); 1746de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::Type *Ty = CGM.getTypes().GetFunctionType(CalleeFnInfo); 174721f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); 174821f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 174921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Determine whether we have a return value slot to use. 175021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman ReturnValueSlot Slot; 175121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman if (!ResultType->isVoidType() && 175227dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && 175321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman hasAggregateLLVMType(CurFnInfo->getReturnType())) 175421f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified()); 175521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 175621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Now emit our call. 175727dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor RValue RV = EmitCall(CalleeFnInfo, Callee, Slot, CallArgs, CallOperator); 175821f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 175921f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // Forward the returned value 176021f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman if (!ResultType->isVoidType() && Slot.isNull()) 176121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman EmitReturnOfRValue(RV, ResultType); 176221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman} 176321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 176464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaBlockInvokeBody() { 176564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const BlockDecl *BD = BlockInfo->getBlockDecl(); 176664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const VarDecl *variable = BD->capture_begin()->getVariable(); 176764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 176864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 176964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 177064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 177164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 177264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 177364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = GetAddrOfBlockDecl(variable, false); 177464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 177564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 177664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 177764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (BlockDecl::param_const_iterator I = BD->param_begin(), 177864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = BD->param_end(); I != E; ++I) { 177964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 178064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 178164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 178264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 178364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 178464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 178564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 178664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { 178764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman if (cast<CXXMethodDecl>(CurFuncDecl)->isVariadic()) { 178864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // FIXME: Making this work correctly is nasty because it requires either 178964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // cloning the body of the call operator or making the call operator forward. 179064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CGM.ErrorUnsupported(CurFuncDecl, "lambda conversion to variadic function"); 179164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 179264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 179364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 179464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman InLambdaConversionToBlock = true; 179564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitFunctionBody(Args); 179664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman InLambdaConversionToBlock = false; 179764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 179864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 179964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedmanvoid CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 180064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman const CXXRecordDecl *Lambda = MD->getParent(); 180164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 180264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Start building arguments for forwarding call 180364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgList CallArgs; 180464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 180564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 180664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 180764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman CallArgs.add(RValue::get(ThisPtr), ThisType); 180864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 180964bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman // Add the rest of the parameters. 181064bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman for (FunctionDecl::param_const_iterator I = MD->param_begin(), 181164bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman E = MD->param_end(); I != E; ++I) { 181264bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman ParmVarDecl *param = *I; 181364bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitDelegateCallArg(CallArgs, param); 181464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman } 181564bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 181664bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman EmitForwardingCallToLambda(Lambda, CallArgs); 181764bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman} 181864bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman 181927dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregorvoid CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { 182027dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor if (MD->isVariadic()) { 182121f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // FIXME: Making this work correctly is nasty because it requires either 182221f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman // cloning the body of the call operator or making the call operator forward. 182321f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 182464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman return; 182521f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman } 182621f6ed94b929beea31622f5e6b3890e51293cfadEli Friedman 182727dd7d962bbf774988bc5e59d04a7743ed503514Douglas Gregor EmitLambdaDelegatingInvokeBody(MD); 1828bd89f8c2caa9550e41daa1aa9bf30f0f1e0dfaf7Eli Friedman} 1829