CGClass.cpp revision 84fcc48817bb04c7de1acafcaa1f54ee3235a97b
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 14d67ef0eed463b43980f04a444155f423114be34bDevang Patel#include "CGDebugInfo.h" 155d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 162f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 177e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "clang/AST/EvaluatedExprVisitor.h" 185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 199fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "clang/AST/StmtCXX.h" 203ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include "clang/Frontend/CodeGenOptions.h" 212f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 225d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 235d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 245d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 2555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyckstatic CharUnits 2634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, 2734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *DerivedClass, 28f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start, 29f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator End) { 3055c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = CharUnits::Zero(); 3134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *RD = DerivedClass; 3334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 34f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 3534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXBaseSpecifier *Base = *I; 3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson assert(!Base->isVirtual() && "Should not see virtual bases here!"); 3734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the layout. 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *BaseDecl = 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Add the offset. 4555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RD = BaseDecl; 4834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 5055c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return Offset; 5134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 525d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 5384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 54a04efdf635d35d88e65041fad007225d8c8d64a5Anders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 55f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 56f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd) { 57f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 58a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 5955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits Offset = 60f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 61f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall PathBegin, PathEnd); 6255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (Offset.isZero()) 63a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson return 0; 64a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 66a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 718561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// Gets the address of a direct base class within a complete object. 72bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 73bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 74bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 75bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 76bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 778561a8666c70f924c8f0209c41b9b77bbbf90607Anders CarlssonCodeGenFunction::GetAddressOfDirectBaseInCompleteClass(llvm::Value *This, 788561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 798561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Base, 808561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson bool BaseIsVirtual) { 81bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 82bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 83bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 84bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 875fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck CharUnits Offset; 88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 898561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (BaseIsVirtual) 905fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getVBaseClassOffset(Base); 91bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 925fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck Offset = Layout.getBaseClassOffset(Base); 93bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 95bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 96bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 975fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck if (Offset.isPositive()) { 982acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 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. 1282acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 1299dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson ThisPtr = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy); 1309dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson ThisPtr = CGF.Builder.CreateGEP(ThisPtr, BaseOffset, "add.ptr"); 1319dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1329dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson return ThisPtr; 1339dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson} 1349dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson 1355d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 13634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 1378561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 138f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 139f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 14034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson bool NullCheckValue) { 141f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 14234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 143f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator Start = PathBegin; 14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CXXRecordDecl *VBase = 0; 14534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 14634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the virtual base. 14734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if ((*Start)->isVirtual()) { 14834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VBase = 14934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl()); 15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson ++Start; 15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 15355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits NonVirtualOffset = 1548561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived, 155f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall Start, PathEnd); 15634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 15734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Get the base pointer type. 1582acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtrTy = 159f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall ConvertType((PathEnd[-1])->getType())->getPointerTo(); 16034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 16155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck if (NonVirtualOffset.isZero() && !VBase) { 16234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Just cast back. 16334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 16434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 16534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 16634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastNull = 0; 16734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 16834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::BasicBlock *CastEnd = 0; 16934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 17034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 17134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNull = createBasicBlock("cast.null"); 17234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 17334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastEnd = createBasicBlock("cast.end"); 17434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 175b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 17634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 17734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastNotNull); 17834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 17934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson llvm::Value *VirtualOffset = 0; 18134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 182336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (VBase) { 183336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson if (Derived->hasAttr<FinalAttr>()) { 184336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson VirtualOffset = 0; 185336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson 186336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 187336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson 18855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck CharUnits VBaseOffset = Layout.getVBaseClassOffset(VBase); 18955c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck NonVirtualOffset += VBaseOffset; 190336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } else 191336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); 192336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson } 19334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 19434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Apply the offsets. 19555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 1969a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck NonVirtualOffset, 19734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson VirtualOffset); 19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 19934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson // Cast back. 20034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 20134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 20234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (NullCheckValue) { 20334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateBr(CastEnd); 20434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastNull); 20534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Builder.CreateBr(CastEnd); 20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson EmitBlock(CastEnd); 20734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 208bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 20934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson PHI->addIncoming(Value, CastNotNull); 21034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 21134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson CastNull); 21234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Value = PHI; 21334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 21434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 21534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return Value; 21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson} 21734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 21834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonllvm::Value * 219a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 2208561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson const CXXRecordDecl *Derived, 221f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathBegin, 222f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CastExpr::path_const_iterator PathEnd, 223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 224f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall assert(PathBegin != PathEnd && "Base path should not be empty!"); 225a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 226a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 2278561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 2282acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 229a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 230a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 231f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 232a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 233a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 234a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 235a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 236a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 237a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 247b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson llvm::Value *IsNull = Builder.CreateIsNull(Value); 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 252a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 253a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType()); 254a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateSub(Value, NonVirtualOffset); 255a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 256a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 257a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 258a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 261a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 262a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 263a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 264a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 265a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 266bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 268a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 26932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 27132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2725d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2745d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 27521c9ad9d29d08a287292c670e7c52bc522c7f8bbAnders Carlsson 276c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a 277c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases. 278314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, 279314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson bool ForVirtualBase) { 280af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (!CodeGenVTables::needsVTTParameter(GD)) { 281c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 282c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 283c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 284c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 285c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); 286c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 2873b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 288c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 289c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2903b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall uint64_t SubVTTIndex; 2913b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 2923b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // If the record matches the base, this is the complete ctor/dtor 2933b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // variant calling the base variant in a class with virtual bases. 2943b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (RD == Base) { 295af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson assert(!CodeGenVTables::needsVTTParameter(CGF.CurGD) && 2963b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "doing no-op VTT offset in base dtor/ctor?"); 297314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson assert(!ForVirtualBase && "Can't have same class as virtual base!"); 2983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall SubVTTIndex = 0; 2993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } else { 300c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson const ASTRecordLayout &Layout = 301c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.getContext().getASTRecordLayout(RD); 3024230d529a8797bbeef2328b60abeae333f7e143fKen Dyck CharUnits BaseOffset = ForVirtualBase ? 3034230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getVBaseClassOffset(Base) : 3044230d529a8797bbeef2328b60abeae333f7e143fKen Dyck Layout.getBaseClassOffset(Base); 305c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 306c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson SubVTTIndex = 307c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson CGF.CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 3083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 3093b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 310c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 311af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) { 312c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 313c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.LoadCXXVTT(); 314c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 315c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 316c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 3171cbce125b91cad81c8be3f8bbae8df917211176cAnders Carlsson VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD); 318c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 319c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 320c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 321c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 323c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 324182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 32550da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the destructor for a direct base class. 3261f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallBaseDtor : EHScopeStack::Cleanup { 32750da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *BaseClass; 32850da2cadcc6da86abff6772de65280ace2cabc94John McCall bool BaseIsVirtual; 32950da2cadcc6da86abff6772de65280ace2cabc94John McCall CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 33050da2cadcc6da86abff6772de65280ace2cabc94John McCall : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 331182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 332ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 33350da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *DerivedClass = 33450da2cadcc6da86abff6772de65280ace2cabc94John McCall cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 33550da2cadcc6da86abff6772de65280ace2cabc94John McCall 33650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *D = BaseClass->getDestructor(); 33750da2cadcc6da86abff6772de65280ace2cabc94John McCall llvm::Value *Addr = 33850da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThis(), 33950da2cadcc6da86abff6772de65280ace2cabc94John McCall DerivedClass, BaseClass, 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseIsVirtual); 34150da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, Addr); 342182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 343182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 3447e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3457e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// A visitor which checks whether an initializer uses 'this' in a 3467e1dff7a68a4d00e71debafa7f5c259473091746John McCall /// way which requires the vtable to be properly set. 3477e1dff7a68a4d00e71debafa7f5c259473091746John McCall struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { 3487e1dff7a68a4d00e71debafa7f5c259473091746John McCall typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; 3497e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3507e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool UsesThis; 3517e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3527e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} 3537e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3547e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Black-list all explicit and implicit references to 'this'. 3557e1dff7a68a4d00e71debafa7f5c259473091746John McCall // 3567e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Do we need to worry about external references to 'this' derived 3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall // from arbitrary code? If so, then anything which runs arbitrary 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall // external code might potentially access the vtable. 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall }; 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCallstatic bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall DynamicThisUseChecker Checker(C); 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall Checker.Visit(const_cast<Expr*>(Init)); 3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall return Checker.UsesThis; 367182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 368182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 369607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 370607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 371cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *BaseInit, 372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 38280638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson bool isBaseVirtual = BaseInit->isBaseVirtual(); 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 3887e1dff7a68a4d00e71debafa7f5c259473091746John McCall // If the initializer for the base (other than the constructor 3897e1dff7a68a4d00e71debafa7f5c259473091746John McCall // itself) accesses 'this' in any way, we need to initialize the 3907e1dff7a68a4d00e71debafa7f5c259473091746John McCall // vtables. 3917e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 3927e1dff7a68a4d00e71debafa7f5c259473091746John McCall CGF.InitializeVTablePointers(ClassDecl); 3937e1dff7a68a4d00e71debafa7f5c259473091746John McCall 394bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 395bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 3968561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson llvm::Value *V = 3978561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 39850da2cadcc6da86abff6772de65280ace2cabc94John McCall BaseClassDecl, 39950da2cadcc6da86abff6772de65280ace2cabc94John McCall isBaseVirtual); 400bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 4017c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot AggSlot = 4027c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::forAddr(V, Qualifiers(), 4037c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 404410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 405410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased); 406558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 407558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 408594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 4097a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson if (CGF.CGM.getLangOptions().Exceptions && 410c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson !BaseClassDecl->hasTrivialDestructor()) 4111f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 4121f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall isBaseVirtual); 413607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 414607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 415fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregorstatic void EmitAggMemberInitializer(CodeGenFunction &CGF, 416fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue LHS, 417fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar, 418cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 419fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType T, 420fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned Index) { 421fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor if (Index == MemberInit->getNumArrayIndices()) { 422f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope Cleanups(CGF); 423fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 424fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Dest = LHS.getAddress(); 425fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor if (ArrayIndexVar) { 426fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If we have an array index variable, load it and use it as an offset. 427fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Then, increment the value. 428fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); 429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); 430fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); 431fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); 432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Next, ArrayIndexVar); 433fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 434558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall 435f85e193739c953358c865005855253af4f68a497John McCall if (!CGF.hasAggregateLLVMType(T)) { 436a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall LValue lvalue = CGF.MakeAddrLValue(Dest, T); 437a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, lvalue, false); 438f85e193739c953358c865005855253af4f68a497John McCall } else if (T->isAnyComplexType()) { 439f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest, 440f85e193739c953358c865005855253af4f68a497John McCall LHS.isVolatileQualified()); 441f85e193739c953358c865005855253af4f68a497John McCall } else { 4427c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot Slot = 4437c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::forAddr(Dest, LHS.getQuals(), 4447c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 445410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 446410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased); 447f85e193739c953358c865005855253af4f68a497John McCall 448f85e193739c953358c865005855253af4f68a497John McCall CGF.EmitAggExpr(MemberInit->getInit(), Slot); 449f85e193739c953358c865005855253af4f68a497John McCall } 450fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 451fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 452fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 453fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 454fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T); 455fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(Array && "Array initialization without the array type?"); 456fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IndexVar 457fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = CGF.GetAddrOfLocalVar(MemberInit->getArrayIndex(Index)); 458fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(IndexVar && "Array index variable not loaded"); 459fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 460fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Initialize this index variable to zero. 461fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value* Zero 462fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = llvm::Constant::getNullValue( 463fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.ConvertType(CGF.getContext().getSizeType())); 464fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, IndexVar); 465fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 466fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Start the loop with a block that tests the condition. 467fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond"); 468fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end"); 469fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 470fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(CondBlock); 471fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 472fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body"); 473fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Generate: if (loop-index < number-of-elements) fall to the loop body, 474fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // otherwise, go to the block after the for-loop. 475fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor uint64_t NumElements = Array->getSize().getZExtValue(); 476fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar); 477985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::Value *NumElementsPtr = 478985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner llvm::ConstantInt::get(Counter->getType(), NumElements); 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr, 480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "isless"); 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 482fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If the condition is true, execute the body. 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor); 484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ForBody); 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor { 489f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CodeGenFunction::RunCleanupsScope Cleanups(CGF); 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Inside the loop body recurse to emit the inner loop or, eventually, the 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // constructor call. 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Array->getElementType(), Index + 1); 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(ContinueBlock); 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the increment of the loop counter. 500fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor Counter = CGF.Builder.CreateLoad(IndexVar); 502fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc"); 503fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(NextVal, IndexVar); 504fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 505fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Finally, branch back up to the condition for the next iteration. 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBranch(CondBlock); 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the fall-through block. 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitBlock(AfterFor, true); 510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor} 511182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 512182ab5112650d3228291c4dadd64a9f77f5aeb51John McCallnamespace { 5131f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallMemberDtor : EHScopeStack::Cleanup { 514182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall FieldDecl *Field; 515182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall CXXDestructorDecl *Dtor; 516182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 517182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor) 518182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall : Field(Field), Dtor(Dtor) {} 519182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 520ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 521182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall // FIXME: Is this OK for C++0x delegating constructors? 522182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall llvm::Value *ThisPtr = CGF.LoadCXXThis(); 523182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0); 524182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 525182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 526182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall LHS.getAddress()); 527182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall } 528182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall }; 529182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall} 53085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl 53185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redlstatic bool hasTrivialCopyOrMoveConstructor(const CXXRecordDecl *Record, 53285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl bool Moving) { 53385ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl return Moving ? Record->hasTrivialMoveConstructor() : 53485ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl Record->hasTrivialCopyConstructor(); 53585ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl} 536fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 539cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *MemberInit, 540fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const CXXConstructorDecl *Constructor, 541fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 54200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet assert(MemberInit->isAnyMemberInitializer() && 543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 5447a614d8380297fcd2bc23986241905d97222948cRichard Smith assert(MemberInit->getInit() && "Must have initializer!"); 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 54700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldDecl *Field = MemberInit->getAnyMember(); 548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = CGF.getContext().getCanonicalType(Field->getType()); 549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 551a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall LValue LHS; 55206a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson 553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we are initializing an anonymous union field, drill down to the field. 55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (MemberInit->isIndirectMemberInitializer()) { 55500eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, 55600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet MemberInit->getIndirectMember(), 0); 55700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); 558a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall } else { 559a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); 560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 561607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 562082aadee6381ec5e99c19c1e4aef41dcc5c00d2bJohn McCall if (!CGF.hasAggregateLLVMType(Field->getType())) { 563f85e193739c953358c865005855253af4f68a497John McCall if (LHS.isSimple()) { 564a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false); 565f85e193739c953358c865005855253af4f68a497John McCall } else { 566f85e193739c953358c865005855253af4f68a497John McCall RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit())); 567545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall CGF.EmitStoreThroughLValue(RHS, LHS); 568f85e193739c953358c865005855253af4f68a497John McCall } 5699db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (MemberInit->getInit()->getType()->isAnyComplexType()) { 5709db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(), 571607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 572607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 573fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *ArrayIndexVar = 0; 574fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor const ConstantArrayType *Array 575fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = CGF.getContext().getAsConstantArrayType(FieldType); 576690b2dbde0ef9eec6b5c950b0c4c7106db37f0a5Douglas Gregor if (Array && Constructor->isImplicitlyDefined() && 577690b2dbde0ef9eec6b5c950b0c4c7106db37f0a5Douglas Gregor Constructor->isCopyOrMoveConstructor()) { 5782acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *SizeTy 579fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor = CGF.ConvertType(CGF.getContext().getSizeType()); 580fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 581fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // The LHS is a pointer to the first object we'll be constructing, as 582fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // a flat array. 583fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 5842acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy); 585fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr = llvm::PointerType::getUnqual(BasePtr); 586fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(LHS.getAddress(), 587fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor BasePtr); 5889f553f5b3bd45304dfda6bdc5cd2baac64b3315bDaniel Dunbar LHS = CGF.MakeAddrLValue(BaseAddrPtr, BaseElementTy); 589fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 590fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Create an array index that will be used to walk over all of the 591fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // objects we're constructing. 592fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor ArrayIndexVar = CGF.CreateTempAlloca(SizeTy, "object.index"); 593fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 594fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.Builder.CreateStore(Zero, ArrayIndexVar); 595fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 596f85e193739c953358c865005855253af4f68a497John McCall // If we are copying an array of PODs or classes with trivial copy 597fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // constructors, perform a single aggregate copy. 598f85e193739c953358c865005855253af4f68a497John McCall const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl(); 599f85e193739c953358c865005855253af4f68a497John McCall if (BaseElementTy.isPODType(CGF.getContext()) || 60085ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl (Record && hasTrivialCopyOrMoveConstructor(Record, 60185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl Constructor->isMoveConstructor()))) { 602fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Find the source pointer. We knows it's the last argument because 603fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // we know we're in a copy constructor. 604fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned SrcArgIndex = Args.size() - 1; 605fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor llvm::Value *SrcPtr 606d26bc76c98006609002d9930f8840490e88ac5b5John McCall = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 607fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0); 608fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 609fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Copy the aggregate. 610fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType, 611fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor LHS.isVolatileQualified()); 612fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor return; 613fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 614fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 615fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Emit the block variables for the array indices, if any. 616fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor for (unsigned I = 0, N = MemberInit->getNumArrayIndices(); I != N; ++I) 617b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall CGF.EmitAutoVarDecl(*MemberInit->getArrayIndex(I)); 618fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor } 619fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0); 6219405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 6227a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson if (!CGF.CGM.getLangOptions().Exceptions) 6239405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 6249405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 625fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // FIXME: If we have an array of classes w/ non-trivial destructors, 626fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // we need to destroy in reverse order of construction along the exception 627fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // path. 6289405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 6299405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson if (!RT) 6309405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 6319405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 6329405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 633182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall if (!RD->hasTrivialDestructor()) 6341f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, Field, 6351f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall RD->getDestructor()); 636607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 638607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 639c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// Checks whether the given constructor is a valid subject for the 640c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// complete-to-base constructor delegation optimization, i.e. 641c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// emitting the complete constructor as a simple call to the base 642c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall/// constructor. 643c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallstatic bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { 644c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 645c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Currently we disable the optimization for classes with virtual 646c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // bases because (1) the addresses of parameter variables need to be 647c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // consistent across all initializers but (2) the delegate function 648c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // call necessarily creates a second copy of the parameter variable. 649c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // 650c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // The limiting example (purely theoretical AFAIK): 651c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct A { A(int &c) { c++; } }; 652c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // struct B : virtual A { 653c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // B(int count) : A(count) { printf("%d\n", count); } 654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // }; 655c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // ...although even this example could in principle be emitted as a 656c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation since the address of the parameter doesn't escape. 657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getParent()->getNumVBases()) { 658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list trivial vbase initializers. This case wouldn't 659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // be subject to the restrictions below. 660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // TODO: white-list cases where: 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - there are no non-reference parameters to the constructor 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't access any non-reference parameters 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - the initializers don't take the address of non-reference 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // parameters 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - etc. 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // If we ever add any of the above cases, remember that: 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - function-try-blocks will always blacklist this optimization 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // - we need to perform the constructor prologue and cleanup in 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // EmitConstructorBody. 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // We also disable the optimization for variadic functions because 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // it's impossible to "re-pass" varargs. 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Ctor->getType()->getAs<FunctionProtoType>()->isVariadic()) 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return false; 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 680059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt // FIXME: Decide if we can do a delegation of a delegating constructor. 681059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (Ctor->isDelegatingConstructor()) 682059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return false; 683059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return true; 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 6879fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitConstructorBody - Emits the body of the current constructor. 6889fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 6899fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 6909fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXCtorType CtorType = CurGD.getCtorType(); 6919fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 692c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Before we go any further, try the complete->base constructor 693c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // delegation optimization. 694c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor)) { 695d67ef0eed463b43980f04a444155f423114be34bDevang Patel if (CGDebugInfo *DI = getDebugInfo()) 696d67ef0eed463b43980f04a444155f423114be34bDevang Patel DI->EmitStopPoint(Builder); 697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args); 698c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall return; 699c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 700c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 7019fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Ctor->getBody(); 7029fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 703c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Enter the function-try-block before the constructor prologue if 704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // applicable. 705c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 706c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 70759a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7089fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 709f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); 7109fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Emit the constructor prologue, i.e. the base and member 712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // initializers. 713fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitCtorPrologue(Ctor, CtorType, Args); 7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit the body of the statement. 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 7179fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 7189fc6a7774643a810c8501dae2323e863fefb623eJohn McCall else if (Body) 7199fc6a7774643a810c8501dae2323e863fefb623eJohn McCall EmitStmt(Body); 7209fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Emit any cleanup blocks associated with the member or base 7229fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // initializers, which includes (along the exceptional path) the 7239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // destructors for those members and bases that were fully 7249fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // constructed. 725f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall PopCleanupBlocks(CleanupDepth); 7269fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 727c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (IsTryBody) 72859a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 7299fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 7309fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 731607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 732607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 733607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 734fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor CXXCtorType CtorType, 735fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor FunctionArgList &Args) { 736059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt if (CD->isDelegatingConstructor()) 737059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt return EmitDelegatingCXXConstructorCall(CD, Args); 738059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 739607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 740a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 7415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer *, 8> MemberInitializers; 742607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 743607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 744607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 745607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 746cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *Member = (*B); 747607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 748d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt if (Member->isBaseInitializer()) { 749607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 750d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } else { 751d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt assert(Member->isAnyMemberInitializer() && 752d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt "Delegating initializer on non-delegating constructor"); 753a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson MemberInitializers.push_back(Member); 754d49bd5515b89bedc57c3d1d3be457e4340dbdb1dSean Hunt } 755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 757603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson InitializeVTablePointers(ClassDecl); 758a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 759f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) 760fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args); 761607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 763adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 764adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 765adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 766adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 767adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonHasTrivialDestructorBody(ASTContext &Context, 768adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *BaseClassDecl, 769adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl) 770adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 771adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // If the destructor is trivial we don't have to check anything else. 772adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 773adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 774adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 775adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 776adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 777adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 778adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check fields. 779adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(), 780adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson E = BaseClassDecl->field_end(); I != E; ++I) { 781adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field = *I; 782adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 783adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 784adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 785adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 786adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 787adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check non-virtual bases. 788adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 789adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end(); 790adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 791adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (I->isVirtual()) 792adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson continue; 793adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 794adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *NonVirtualBase = 795adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 796adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, NonVirtualBase, 797adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 798adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 799adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 800adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 801adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (BaseClassDecl == MostDerivedClassDecl) { 802adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson // Check virtual bases. 803adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 804adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); 805adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson I != E; ++I) { 806adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const CXXRecordDecl *VirtualBase = 807adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 808adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!HasTrivialDestructorBody(Context, VirtualBase, 809adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson MostDerivedClassDecl)) 810adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 811adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 812adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson } 813adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 814adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 815adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 816adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 817adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlssonstatic bool 818adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders CarlssonFieldHasTrivialDestructorBody(ASTContext &Context, 819adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const FieldDecl *Field) 820adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson{ 821adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 822adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 823adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 824adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!RT) 825adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return true; 826adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 827adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 828adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 829adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson} 830adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson 831ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// CanSkipVTablePointerInitialization - Check whether we need to initialize 832ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson/// any vtable pointers before calling this destructor. 833ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlssonstatic bool CanSkipVTablePointerInitialization(ASTContext &Context, 834e3d6cf2149beb1c215ea6e87023c27b4f37712adAnders Carlsson const CXXDestructorDecl *Dtor) { 835ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!Dtor->hasTrivialBody()) 836ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return false; 837ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 838ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson // Check the fields. 839ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const CXXRecordDecl *ClassDecl = Dtor->getParent(); 840ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 841ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 842ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson const FieldDecl *Field = *I; 843ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 844adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson if (!FieldHasTrivialDestructorBody(Context, Field)) 845adf5dc340db3ea99de5fe3f6c42cfee1807d445eAnders Carlsson return false; 846ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson } 847ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 848ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson return true; 849ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson} 850ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson 8519fc6a7774643a810c8501dae2323e863fefb623eJohn McCall/// EmitDestructorBody - Emits the body of the current destructor. 8529fc6a7774643a810c8501dae2323e863fefb623eJohn McCallvoid CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 8539fc6a7774643a810c8501dae2323e863fefb623eJohn McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 8549fc6a7774643a810c8501dae2323e863fefb623eJohn McCall CXXDtorType DtorType = CurGD.getDtorType(); 8559fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 85650da2cadcc6da86abff6772de65280ace2cabc94John McCall // The call to operator delete in a deleting destructor happens 85750da2cadcc6da86abff6772de65280ace2cabc94John McCall // outside of the function-try-block, which means it's always 85850da2cadcc6da86abff6772de65280ace2cabc94John McCall // possible to delegate the destructor body to the complete 85950da2cadcc6da86abff6772de65280ace2cabc94John McCall // destructor. Do so. 86050da2cadcc6da86abff6772de65280ace2cabc94John McCall if (DtorType == Dtor_Deleting) { 86150da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Deleting); 86250da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 86350da2cadcc6da86abff6772de65280ace2cabc94John McCall LoadCXXThis()); 86450da2cadcc6da86abff6772de65280ace2cabc94John McCall PopCleanupBlock(); 86550da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 86650da2cadcc6da86abff6772de65280ace2cabc94John McCall } 86750da2cadcc6da86abff6772de65280ace2cabc94John McCall 8689fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Stmt *Body = Dtor->getBody(); 8699fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 8709fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If the body is a function-try-block, enter the try before 87150da2cadcc6da86abff6772de65280ace2cabc94John McCall // anything else. 87250da2cadcc6da86abff6772de65280ace2cabc94John McCall bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 8739fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 87459a7000a79118e4c140885ccbb2ac6a686a73092John McCall EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8759fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 87650da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the epilogue cleanups. 87750da2cadcc6da86abff6772de65280ace2cabc94John McCall RunCleanupsScope DtorEpilogue(*this); 87850da2cadcc6da86abff6772de65280ace2cabc94John McCall 8799fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // If this is the complete variant, just invoke the base variant; 8809fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // the epilogue will destruct the virtual bases. But we can't do 8819fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // this optimization if the body is a function-try-block, because 8829fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // we'd introduce *two* handler blocks. 88350da2cadcc6da86abff6772de65280ace2cabc94John McCall switch (DtorType) { 88450da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 88550da2cadcc6da86abff6772de65280ace2cabc94John McCall 88650da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Complete: 88750da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for virtual bases. 88850da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Complete); 88950da2cadcc6da86abff6772de65280ace2cabc94John McCall 89050da2cadcc6da86abff6772de65280ace2cabc94John McCall if (!isTryBody) { 89150da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 89250da2cadcc6da86abff6772de65280ace2cabc94John McCall LoadCXXThis()); 89350da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 89450da2cadcc6da86abff6772de65280ace2cabc94John McCall } 89550da2cadcc6da86abff6772de65280ace2cabc94John McCall // Fallthrough: act like we're in the base variant. 8969fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 89750da2cadcc6da86abff6772de65280ace2cabc94John McCall case Dtor_Base: 89850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Enter the cleanup scopes for fields and non-virtual bases. 89950da2cadcc6da86abff6772de65280ace2cabc94John McCall EnterDtorCleanups(Dtor, Dtor_Base); 90050da2cadcc6da86abff6772de65280ace2cabc94John McCall 90150da2cadcc6da86abff6772de65280ace2cabc94John McCall // Initialize the vtable pointers before entering the body. 902ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson if (!CanSkipVTablePointerInitialization(getContext(), Dtor)) 903ffb945ffb5d29b80fd93649c3572b6d87abce3fcAnders Carlsson InitializeVTablePointers(Dtor->getParent()); 9049fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 90550da2cadcc6da86abff6772de65280ace2cabc94John McCall if (isTryBody) 90650da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 90750da2cadcc6da86abff6772de65280ace2cabc94John McCall else if (Body) 90850da2cadcc6da86abff6772de65280ace2cabc94John McCall EmitStmt(Body); 90950da2cadcc6da86abff6772de65280ace2cabc94John McCall else { 91050da2cadcc6da86abff6772de65280ace2cabc94John McCall assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 91150da2cadcc6da86abff6772de65280ace2cabc94John McCall // nothing to do besides what's in the epilogue 91250da2cadcc6da86abff6772de65280ace2cabc94John McCall } 9135abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // -fapple-kext must inline any call to this dtor into 9145abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian // the caller's body. 9155abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian if (getContext().getLangOptions().AppleKext) 9165abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 91750da2cadcc6da86abff6772de65280ace2cabc94John McCall break; 9189fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } 9199fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 92050da2cadcc6da86abff6772de65280ace2cabc94John McCall // Jump out through the epilogue cleanups. 92150da2cadcc6da86abff6772de65280ace2cabc94John McCall DtorEpilogue.ForceCleanup(); 9229fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 9239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall // Exit the try if applicable. 9249fc6a7774643a810c8501dae2323e863fefb623eJohn McCall if (isTryBody) 92559a7000a79118e4c140885ccbb2ac6a686a73092John McCall ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 9269fc6a7774643a810c8501dae2323e863fefb623eJohn McCall} 9279fc6a7774643a810c8501dae2323e863fefb623eJohn McCall 92850da2cadcc6da86abff6772de65280ace2cabc94John McCallnamespace { 92950da2cadcc6da86abff6772de65280ace2cabc94John McCall /// Call the operator delete associated with the current destructor. 9301f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallDtorDelete : EHScopeStack::Cleanup { 93150da2cadcc6da86abff6772de65280ace2cabc94John McCall CallDtorDelete() {} 93250da2cadcc6da86abff6772de65280ace2cabc94John McCall 933ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 93450da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 93550da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = Dtor->getParent(); 93650da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(), 93750da2cadcc6da86abff6772de65280ace2cabc94John McCall CGF.getContext().getTagDeclType(ClassDecl)); 93850da2cadcc6da86abff6772de65280ace2cabc94John McCall } 93950da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 94050da2cadcc6da86abff6772de65280ace2cabc94John McCall 9419928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall class DestroyField : public EHScopeStack::Cleanup { 9429928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field; 9439928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CodeGenFunction::Destroyer &destroyer; 9449928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray; 9459928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 9469928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall public: 9479928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 9489928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall bool useEHCleanupForArray) 9499928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall : field(field), destroyer(*destroyer), 9509928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall useEHCleanupForArray(useEHCleanupForArray) {} 9519928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 952ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 9539928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall // Find the address of the field. 9549928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall llvm::Value *thisValue = CGF.LoadCXXThis(); 9559928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0); 9569928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall assert(LV.isSimple()); 9579928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 9589928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer, 959ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall flags.isForNormalCleanup() && useEHCleanupForArray); 96050da2cadcc6da86abff6772de65280ace2cabc94John McCall } 96150da2cadcc6da86abff6772de65280ace2cabc94John McCall }; 96250da2cadcc6da86abff6772de65280ace2cabc94John McCall} 96350da2cadcc6da86abff6772de65280ace2cabc94John McCall 964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 96750da2cadcc6da86abff6772de65280ace2cabc94John McCallvoid CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 96850da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXDtorType DtorType) { 969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 97250da2cadcc6da86abff6772de65280ace2cabc94John McCall // The deleting-destructor phase just needs to call the appropriate 97350da2cadcc6da86abff6772de65280ace2cabc94John McCall // operator delete that Sema picked up. 9743b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Deleting) { 9753b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DD->getOperatorDelete() && 9763b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall "operator delete missing - EmitDtorEpilogue"); 9771f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 9783b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 9793b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 9803b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 98150da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXRecordDecl *ClassDecl = DD->getParent(); 98250da2cadcc6da86abff6772de65280ace2cabc94John McCall 983416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith // Unions have no bases and do not call field destructors. 984416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith if (ClassDecl->isUnion()) 985416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith return; 986416f63e42d4c34a38833a3aa8fa1ebb3c847722bRichard Smith 98750da2cadcc6da86abff6772de65280ace2cabc94John McCall // The complete-destructor phase just destructs all the virtual bases. 9883b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (DtorType == Dtor_Complete) { 98950da2cadcc6da86abff6772de65280ace2cabc94John McCall 99050da2cadcc6da86abff6772de65280ace2cabc94John McCall // We push them in the forward order so that they'll be popped in 99150da2cadcc6da86abff6772de65280ace2cabc94John McCall // the reverse order. 99250da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 99350da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); 9943b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall I != E; ++I) { 9953b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall const CXXBaseSpecifier &Base = *I; 9963b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall CXXRecordDecl *BaseClassDecl 9973b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 9983b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 9993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Ignore trivial destructors. 10003b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (BaseClassDecl->hasTrivialDestructor()) 10013b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall continue; 100250da2cadcc6da86abff6772de65280ace2cabc94John McCall 10031f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 10041f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 10051f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ true); 10063b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 100750da2cadcc6da86abff6772de65280ace2cabc94John McCall 10083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return; 10093b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall } 10103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 10113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall assert(DtorType == Dtor_Base); 101250da2cadcc6da86abff6772de65280ace2cabc94John McCall 101350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy non-virtual bases. 101450da2cadcc6da86abff6772de65280ace2cabc94John McCall for (CXXRecordDecl::base_class_const_iterator I = 101550da2cadcc6da86abff6772de65280ace2cabc94John McCall ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 101650da2cadcc6da86abff6772de65280ace2cabc94John McCall const CXXBaseSpecifier &Base = *I; 101750da2cadcc6da86abff6772de65280ace2cabc94John McCall 101850da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore virtual bases. 101950da2cadcc6da86abff6772de65280ace2cabc94John McCall if (Base.isVirtual()) 102050da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 102150da2cadcc6da86abff6772de65280ace2cabc94John McCall 102250da2cadcc6da86abff6772de65280ace2cabc94John McCall CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 102350da2cadcc6da86abff6772de65280ace2cabc94John McCall 102450da2cadcc6da86abff6772de65280ace2cabc94John McCall // Ignore trivial destructors. 102550da2cadcc6da86abff6772de65280ace2cabc94John McCall if (BaseClassDecl->hasTrivialDestructor()) 102650da2cadcc6da86abff6772de65280ace2cabc94John McCall continue; 10273b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 10281f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 10291f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall BaseClassDecl, 10301f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall /*BaseIsVirtual*/ false); 103150da2cadcc6da86abff6772de65280ace2cabc94John McCall } 103250da2cadcc6da86abff6772de65280ace2cabc94John McCall 103350da2cadcc6da86abff6772de65280ace2cabc94John McCall // Destroy direct fields. 10345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const FieldDecl *, 16> FieldDecls; 1035607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 1036607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 10379928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall const FieldDecl *field = *I; 10389928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType type = field->getType(); 10399928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 10409928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall if (!dtorKind) continue; 10419928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall 10429928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall CleanupKind cleanupKind = getCleanupKind(dtorKind); 10439928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall EHStack.pushCleanup<DestroyField>(cleanupKind, field, 10449928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall getDestroyer(dtorKind), 10459928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall cleanupKind & EHCleanup); 1046607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1047607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1048607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1049c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1050c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 105159174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor/// 1052c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1053c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param argBegin,argEnd the arguments to evaluate and pass to the 1054c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor 1055c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayType the type of the array to initialize 1056c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin an arrayType* 1057c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1058c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 10593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1060c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1061c3c0766277cd64bf117450a1519c9cf762d994d4John McCall const ConstantArrayType *arrayType, 1062c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1063c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1064c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1065c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1066c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType elementType; 1067c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements = 1068c3c0766277cd64bf117450a1519c9cf762d994d4John McCall emitArrayLength(arrayType, elementType, arrayBegin); 1069c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1070c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, 1071c3c0766277cd64bf117450a1519c9cf762d994d4John McCall argBegin, argEnd, zeroInitialize); 10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1074c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// EmitCXXAggrConstructorCall - Emit a loop to call a particular 1075c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor for each of several members of an array. 1076c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// 1077c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param ctor the constructor to call for each element 1078c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param numElements the number of elements in the array; 1079dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall/// may be zero 1080c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param argBegin,argEnd the arguments to evaluate and pass to the 1081c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// constructor 1082c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param arrayBegin a T*, where T is the type constructed by ctor 1083c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// \param zeroInitialize true if each element should be 1084c3c0766277cd64bf117450a1519c9cf762d994d4John McCall/// zero-initialized before it is constructed 10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 1086c3c0766277cd64bf117450a1519c9cf762d994d4John McCallCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 1087c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *numElements, 1088c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayBegin, 1089c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argBegin, 1090c3c0766277cd64bf117450a1519c9cf762d994d4John McCall CallExpr::const_arg_iterator argEnd, 1091c3c0766277cd64bf117450a1519c9cf762d994d4John McCall bool zeroInitialize) { 1092dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1093dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // It's legal for numElements to be zero. This can happen both 1094dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // dynamically, because x can be zero in 'new A[x]', and statically, 1095dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // because of GCC extensions that permit zero-length arrays. There 1096dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // are probably legitimate places where we could assume that this 1097dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // doesn't happen, but it's not clear that it's worth it. 1098dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BranchInst *zeroCheckBranch = 0; 1099dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1100dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Optimize for a constant count. 1101dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::ConstantInt *constantCount 1102dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall = dyn_cast<llvm::ConstantInt>(numElements); 1103dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount) { 1104dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Just skip out if the constant count is zero. 1105dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (constantCount->isZero()) return; 1106dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1107dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Otherwise, emit the check. 1108dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } else { 1109dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 1110dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 1111dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 1112dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall EmitBlock(loopBB); 1113dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall } 1114dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1115c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Find the end of the array. 1116c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements, 1117c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.end"); 1118c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1119c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Enter the loop, setting up a phi for the current location to initialize. 1120c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 1121c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 1122c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(loopBB); 1123c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 1124c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.cur"); 1125c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(arrayBegin, entryBB); 11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 1128c3c0766277cd64bf117450a1519c9cf762d994d4John McCall 1129c3c0766277cd64bf117450a1519c9cf762d994d4John McCall QualType type = getContext().getTypeDeclType(ctor->getParent()); 11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 113159174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor // Zero initialize the storage, if requested. 1132c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (zeroInitialize) 1133c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitNullInitialization(cur, type); 113459174c0633fb5cde41735cfbff5744bdf837e8d9Douglas Gregor 11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 114344ec82b4a1597802f5bf17721481b8c265bc8dc5Anders Carlsson { 1144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1146c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Evaluate the constructor and its arguments in a regular 1147c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // partial-destroy cleanup. 1148c3c0766277cd64bf117450a1519c9cf762d994d4John McCall if (getLangOptions().Exceptions && 1149c3c0766277cd64bf117450a1519c9cf762d994d4John McCall !ctor->getParent()->hasTrivialDestructor()) { 1150c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Destroyer *destroyer = destroyCXXObject; 1151c3c0766277cd64bf117450a1519c9cf762d994d4John McCall pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer); 1152c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1154c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/ false, 1155c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur, argBegin, argEnd); 1156c3c0766277cd64bf117450a1519c9cf762d994d4John McCall } 11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1158c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Go to the next element. 1159c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *next = 1160c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(SizeTy, 1), 1161c3c0766277cd64bf117450a1519c9cf762d994d4John McCall "arrayctor.next"); 1162c3c0766277cd64bf117450a1519c9cf762d994d4John McCall cur->addIncoming(next, Builder.GetInsertBlock()); 11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1164c3c0766277cd64bf117450a1519c9cf762d994d4John McCall // Check whether that's the end of the loop. 1165c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 1166c3c0766277cd64bf117450a1519c9cf762d994d4John McCall llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 1167c3c0766277cd64bf117450a1519c9cf762d994d4John McCall Builder.CreateCondBr(done, contBB, loopBB); 11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1169dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall // Patch the earlier check to skip over the loop. 1170dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 1171dd376cae98ce4d0ab92c90d3e9c01ee19e919f44John McCall 1172c3c0766277cd64bf117450a1519c9cf762d994d4John McCall EmitBlock(contBB); 11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1175bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 1176bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall llvm::Value *addr, 1177bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall QualType type) { 1178bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const RecordType *rtype = type->castAs<RecordType>(); 1179bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 1180bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall const CXXDestructorDecl *dtor = record->getDestructor(); 1181bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall assert(!dtor->isTrivial()); 1182bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 1183bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall addr); 1184bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall} 1185bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall 11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 1188155ed4a23366f4514befb1c9f5f89d16f8b8b6dbAnders Carlsson CXXCtorType Type, bool ForVirtualBase, 11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 11923ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 11933ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel CGDebugInfo *DI = getDebugInfo(); 11943ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel if (DI && CGM.getCodeGenOpts().LimitDebugInfo) { 11953ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel // If debug info for this class has been emitted then this is the right time 11963ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel // to do so. 11973ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel const CXXRecordDecl *Parent = D->getParent(); 11983ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel DI->getOrCreateRecordType(CGM.getContext().getTypeDeclType(Parent), 11993ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel Parent->getLocation()); 12003ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel } 12013ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel 12028b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 12038b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 12048b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 12058b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 12068b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12098b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12108b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 121185ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl assert(D->isCopyOrMoveConstructor() && 121285ea7aa961deac1d754f610af8062ae3f8b4e2a5Sebastian Redl "trivial 1-arg ctor not a copy/move ctor"); 12138b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12148b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 12158b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 12168b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 12178b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1221314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type), ForVirtualBase); 12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1224c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); 12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1227c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallvoid 122834999876e215b22febc240b1a6dc054215d12f9cFariborz JahanianCodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 122934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *This, llvm::Value *Src, 123034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgBeg, 123134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator ArgEnd) { 123234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian if (D->isTrivial()) { 123334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 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"); 123634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian EmitAggregateCopy(This, Src, (*ArgBeg)->getType()); 123734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian return; 123834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 123934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, 124034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian clang::Ctor_Complete); 124134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(D->isInstance() && 124234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Trying to emit a member call expr on a static method!"); 124334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 124434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>(); 124534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 124634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallArgList Args; 124734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 124834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the this ptr. 124904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(This), D->getThisType(getContext())); 125034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 125134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 125234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Push the src ptr. 125334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType QT = *(FPT->arg_type_begin()); 12542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *t = CGM.getTypes().ConvertType(QT); 125534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian Src = Builder.CreateBitCast(Src, t); 125604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman Args.add(RValue::get(Src), QT); 125734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 125834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Skip over first argument (Src). 125934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian ++ArgBeg; 126034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian CallExpr::const_arg_iterator Arg = ArgBeg; 126134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1, 126234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian E = FPT->arg_type_end(); I != E; ++I, ++Arg) { 126334999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert(Arg != ArgEnd && "Running over edge of argument list!"); 1264413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, *I); 126534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 126634999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // Either we've emitted all the call args, or we have a call to a 126734999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // variadic function. 126834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian assert((Arg == ArgEnd || FPT->isVariadic()) && 126934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian "Extra arguments in non-variadic function!"); 127034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian // If we still have any arguments, emit them using the type of the argument. 127134999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian for (; Arg != ArgEnd; ++Arg) { 127234999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian QualType ArgType = Arg->getType(); 1273413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitCallArg(Args, *Arg, ArgType); 127434999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian } 127534999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 1276c55db3b76df62f2c89e9bcc7437d1065512fb139Eli Friedman EmitCall(CGM.getTypes().getFunctionInfo(Args, FPT), Callee, 1277c55db3b76df62f2c89e9bcc7437d1065512fb139Eli Friedman ReturnValueSlot(), Args, D); 127834999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian} 127934999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanian 128034999876e215b22febc240b1a6dc054215d12f9cFariborz Jahanianvoid 1281c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCallCodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 1282c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CXXCtorType CtorType, 1283c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall const FunctionArgList &Args) { 1284c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CallArgList DelegateArgs; 1285c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1286c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 1287c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "no parameters to constructor"); 1288c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1289c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // this 129004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType()); 1291c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1292c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1293c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // vtt 1294314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson if (llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(Ctor, CtorType), 1295314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson /*ForVirtualBase=*/false)) { 1296c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 129704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman DelegateArgs.add(RValue::get(VTT), VoidPP); 1298c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1299af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD)) { 1300c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(I != E && "cannot skip vtt parameter, already done with args"); 1301d26bc76c98006609002d9930f8840490e88ac5b5John McCall assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type"); 1302c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ++I; 1303c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1304c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1305c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1306c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall // Explicit arguments. 1307c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall for (; I != E; ++I) { 1308413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall const VarDecl *param = *I; 1309413ebdb1af6fb0d81845b61254daf02ba0449afdJohn McCall EmitDelegateCallArg(DelegateArgs, param); 1310c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 1311c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1312c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall EmitCall(CGM.getTypes().getFunctionInfo(Ctor, CtorType), 1313c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall CGM.GetAddrOfCXXConstructor(Ctor, CtorType), 1314c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ReturnValueSlot(), DelegateArgs, Ctor); 1315c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall} 1316c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall 1317b76af9c969558b4484be87933e89e76e7ee87e21Sean Huntnamespace { 1318b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt struct CallDelegatingCtorDtor : EHScopeStack::Cleanup { 1319b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXDestructorDecl *Dtor; 1320b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt llvm::Value *Addr; 1321b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type; 1322b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1323b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr, 1324b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type) 1325b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt : Dtor(D), Addr(Addr), Type(Type) {} 1326b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1327ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1328b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 1329b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt Addr); 1330b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1331b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt }; 1332b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1333b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1334059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Huntvoid 1335059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean HuntCodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 1336059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt const FunctionArgList &Args) { 1337059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt assert(Ctor->isDelegatingConstructor()); 1338059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1339059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt llvm::Value *ThisPtr = LoadCXXThis(); 1340059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1341f85e193739c953358c865005855253af4f68a497John McCall AggValueSlot AggSlot = 13427c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::forAddr(ThisPtr, Qualifiers(), 13437c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 1344410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 1345410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased); 1346059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1347059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 1348059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 1349b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt const CXXRecordDecl *ClassDecl = Ctor->getParent(); 1350b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt if (CGM.getLangOptions().Exceptions && !ClassDecl->hasTrivialDestructor()) { 1351b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CXXDtorType Type = 1352b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 1353b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt 1354b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 1355b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ClassDecl->getDestructor(), 1356b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt ThisPtr, Type); 1357b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt } 1358b76af9c969558b4484be87933e89e76e7ee87e21Sean Hunt} 1359059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt 13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 13628e6404ca28d6bbb76e97ea2a53a74816c2a74665Anders Carlsson bool ForVirtualBase, 13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1364314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type), 1365314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson ForVirtualBase); 1366ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian llvm::Value *Callee = 0; 1367ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (getContext().getLangOptions().AppleKext) 1368771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 1369771c678c04f5f685b4f188ec6c2fd88ad0f7457fFariborz Jahanian DD->getParent()); 1370ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian 1371ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian if (!Callee) 1372ccd5259d33cbbdd6f5fbf7ccab4cb4a2702309eaFariborz Jahanian Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 13733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1374c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); 13753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1377291ae949612e371c41bf771a483b407d49372a4fJohn McCallnamespace { 13781f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallLocalDtor : EHScopeStack::Cleanup { 1379291ae949612e371c41bf771a483b407d49372a4fJohn McCall const CXXDestructorDecl *Dtor; 1380291ae949612e371c41bf771a483b407d49372a4fJohn McCall llvm::Value *Addr; 1381291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1382291ae949612e371c41bf771a483b407d49372a4fJohn McCall CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr) 1383291ae949612e371c41bf771a483b407d49372a4fJohn McCall : Dtor(D), Addr(Addr) {} 1384291ae949612e371c41bf771a483b407d49372a4fJohn McCall 1385ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall void Emit(CodeGenFunction &CGF, Flags flags) { 1386291ae949612e371c41bf771a483b407d49372a4fJohn McCall CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 1387291ae949612e371c41bf771a483b407d49372a4fJohn McCall /*ForVirtualBase=*/false, Addr); 1388291ae949612e371c41bf771a483b407d49372a4fJohn McCall } 1389291ae949612e371c41bf771a483b407d49372a4fJohn McCall }; 1390291ae949612e371c41bf771a483b407d49372a4fJohn McCall} 1391291ae949612e371c41bf771a483b407d49372a4fJohn McCall 139281407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCallvoid CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 139381407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall llvm::Value *Addr) { 13941f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); 139581407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall} 139681407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall 1397f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { 1398f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 1399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!ClassDecl) return; 1400f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ClassDecl->hasTrivialDestructor()) return; 1401f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1402f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall const CXXDestructorDecl *D = ClassDecl->getDestructor(); 1403642a75f883e644bcfbb82e7af0313776ad1ce33cJohn McCall assert(D && D->isUsed() && "destructor not marked as used!"); 140481407d404a3fc8d24d0e2a052d85cae183033e2bJohn McCall PushDestructorCleanup(D, Addr); 1405f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 1406f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 14073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1408bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1409bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 14103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 1411043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); 141214c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck CharUnits VBaseOffsetOffset = 14131d2b31710539d705a3850c9fc3aa1804c2a5efeePeter Collingbourne CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); 14143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 141614c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), 141714c65ca4cd914f3090d7eedb9bff4deb0ffc7927Ken Dyck "vbase.offset.ptr"); 14182acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrDiffTy = 14193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 14203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 14223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 14233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 14253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 14273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 14283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1429d103f9f9b401b419e756f8c1849683cd77586067Anders Carlssonvoid 1430d103f9f9b401b419e756f8c1849683cd77586067Anders CarlssonCodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 1431b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1432d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1433d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson llvm::Constant *VTable, 1434d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson const CXXRecordDecl *VTableClass) { 1435c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 1436c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1437d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute the address point. 1438c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTableAddressPoint; 1439851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson 1440c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Check if we need to use a vtable from the VTT. 1441851853d8b71f5bf2f24705c8dc2df54b2af88d71Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && 1442b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson (RD->getNumVBases() || NearestVBase)) { 1443c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // Get the secondary vpointer index. 1444c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson uint64_t VirtualPointerIndex = 1445c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); 1446c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1447c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson /// Load the VTT. 1448c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson llvm::Value *VTT = LoadCXXVTT(); 1449c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson if (VirtualPointerIndex) 1450c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); 1451c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson 1452c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson // And load the address point from the VTT. 1453c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = Builder.CreateLoad(VTT); 1454c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } else { 145584fcc48817bb04c7de1acafcaa1f54ee3235a97bPeter Collingbourne uint64_t AddressPoint = 145684fcc48817bb04c7de1acafcaa1f54ee3235a97bPeter Collingbourne CGM.getVTableContext().getAddressPoint(Base, VTableClass); 1457c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson VTableAddressPoint = 1458d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); 1459c83f1061fedc223ad661e25337cc853f54671d8aAnders Carlsson } 1460d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1461d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Compute where to store the address point. 14628246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VirtualOffset = 0; 14639a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck CharUnits NonVirtualOffset = CharUnits::Zero(); 14643e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson 14653e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { 14663e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // We need to use the virtual base offset offset because the virtual base 14673e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson // might have a different offset in the most derived class. 14688246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass, 14698246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NearestVBase); 1470d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck NonVirtualOffset = OffsetFromNearestVBase; 14713e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } else { 14728246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // We can just use the base offset in the complete class. 14734230d529a8797bbeef2328b60abeae333f7e143fKen Dyck NonVirtualOffset = Base.getBaseOffset(); 14743e79c30807c516e8d32e4ed08408b30605df5997Anders Carlsson } 14758246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 14768246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson // Apply the offsets. 14778246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson llvm::Value *VTableField = LoadCXXThis(); 14788246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson 14799a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck if (!NonVirtualOffset.isZero() || VirtualOffset) 14808246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VTableField = ApplyNonVirtualAndVirtualOffset(*this, VTableField, 14818246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson NonVirtualOffset, 14828246cc7f85a9b307900e9c05e7e1bb8a40b2b7a5Anders Carlsson VirtualOffset); 148336fd6beef1ffaf93217d8ce96d900d4ed817e463Anders Carlsson 1484d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson // Finally, store the address point. 14852acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *AddressPointPtrTy = 1486d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableAddressPoint->getType()->getPointerTo(); 1487d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy); 1488d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson Builder.CreateStore(VTableAddressPoint, VTableField); 1489d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson} 1490d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson 1491603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid 1492603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders CarlssonCodeGenFunction::InitializeVTablePointers(BaseSubobject Base, 1493b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson const CXXRecordDecl *NearestVBase, 1494d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits OffsetFromNearestVBase, 1495603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson bool BaseIsNonVirtualPrimaryBase, 1496603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable, 1497603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *VTableClass, 1498603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy& VBases) { 1499603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // If this base is a non-virtual primary base the address point has already 1500603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // been set. 1501603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseIsNonVirtualPrimaryBase) { 1502603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointer for this base. 15034235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, 15044235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson VTable, VTableClass); 1505603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 15064658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1507603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const CXXRecordDecl *RD = Base.getBase(); 15084658990ac17046bfe7a30c45c9faea9e617eb479Anders Carlsson 1509603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Traverse bases. 1510603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1511603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson E = RD->bases_end(); I != E; ++I) { 15120703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson CXXRecordDecl *BaseDecl 15130703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1514603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1515603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 1516603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!BaseDecl->isDynamicClass()) 1517603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1518603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1519d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffset; 1520d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck CharUnits BaseOffsetFromNearestVBase; 152114da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson bool BaseDeclIsNonVirtualPrimaryBase; 1522603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1523603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (I->isVirtual()) { 1524603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Check if we've visited this virtual base before. 1525603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson if (!VBases.insert(BaseDecl)) 1526603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson continue; 1527603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1528603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = 1529603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson getContext().getASTRecordLayout(VTableClass); 1530603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 1531d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 1532d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck BaseOffsetFromNearestVBase = CharUnits::Zero(); 153314da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = false; 1534603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } else { 1535603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1536603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson 15374230d529a8797bbeef2328b60abeae333f7e143fKen Dyck BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 15384235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase = 1539d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 154014da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 1541603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson } 15420703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson 15434230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 1544b3b772ea15a4cd54879e244629aa685ead9548bbAnders Carlsson I->isVirtual() ? BaseDecl : NearestVBase, 15454235840554aaed11efd479df9e622dc82ab77e6dAnders Carlsson BaseOffsetFromNearestVBase, 154614da9de3ad9a451ed58f0196eea945c8393d5762Anders Carlsson BaseDeclIsNonVirtualPrimaryBase, 1547603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, VTableClass, VBases); 15483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 15493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 15503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1551603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlssonvoid CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 1552603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Ignore classes without a vtable. 15530703690603bd197b581ceb2fb9a020aa88b9a106Anders Carlsson if (!RD->isDynamicClass()) 15543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 15553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1556603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Get the VTable. 1557603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD); 15583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1559603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson // Initialize the vtable pointers for this class and all of its bases. 1560603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VisitedVirtualBasesSetTy VBases; 15614230d529a8797bbeef2328b60abeae333f7e143fKen Dyck InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 15624230d529a8797bbeef2328b60abeae333f7e143fKen Dyck /*NearestVBase=*/0, 1563d6fb21fa1053e5d616af55b181bb03c50d4b0d24Ken Dyck /*OffsetFromNearestVBase=*/CharUnits::Zero(), 1564603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson /*BaseIsNonVirtualPrimaryBase=*/false, 1565603d6d12cc4cba1ef219a3d55c698c7c87f87adfAnders Carlsson VTable, RD, VBases); 15663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1567043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman 1568043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohmanllvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, 15692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty) { 1570043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo()); 1571043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman return Builder.CreateLoad(VTablePtrSrc, "vtable"); 1572043fb9a1fc0609285f60f0f87e5a18195408f34cDan Gohman} 1573a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1574a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { 1575a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const Expr *E = Base; 1576a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1577a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 1578a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = E->IgnoreParens(); 1579a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 1580a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_DerivedToBase || 1581a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_UncheckedDerivedToBase || 1582a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CE->getCastKind() == CK_NoOp) { 1583a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 1584a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1585a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1586a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1587a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1588a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson break; 1589a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1590a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1591a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson QualType DerivedType = E->getType(); 1592a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const PointerType *PTy = DerivedType->getAs<PointerType>()) 1593a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson DerivedType = PTy->getPointeeType(); 1594a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1595a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return cast<CXXRecordDecl>(DerivedType->castAs<RecordType>()->getDecl()); 1596a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1597a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1598a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do 1599a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson// quite what we want. 1600a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic const Expr *skipNoOpCastsAndParens(const Expr *E) { 1601a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson while (true) { 1602a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { 1603a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = PE->getSubExpr(); 1604a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1605a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1606a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1607a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { 1608a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (CE->getCastKind() == CK_NoOp) { 1609a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = CE->getSubExpr(); 1610a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1611a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1612a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1613a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 1614a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UO->getOpcode() == UO_Extension) { 1615a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson E = UO->getSubExpr(); 1616a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson continue; 1617a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1618a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1619a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return E; 1620a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1621a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1622a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1623a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// canDevirtualizeMemberFunctionCall - Checks whether the given virtual member 1624a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// function call on the given expr can be devirtualized. 1625a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson/// expr can be devirtualized. 1626a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool canDevirtualizeMemberFunctionCall(const Expr *Base, 1627a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 1628a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the most derived class is marked final, we know that no subclass can 1629a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // override this member function and so we can devirtualize it. For example: 1630a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1631a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct A { virtual void f(); } 1632a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // struct B final : A { }; 1633a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1634a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // void f(B *b) { 1635a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // b->f(); 1636a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // } 1637a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // 1638a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base); 1639a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MostDerivedClassDecl->hasAttr<FinalAttr>()) 1640a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1641a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1642a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // If the member function is marked 'final', we know that it can't be 1643a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // overridden and can therefore devirtualize it. 1644a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->hasAttr<FinalAttr>()) 1645a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1646a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1647a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Similarly, if the class itself is marked 'final' it can't be overridden 1648a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // and we can therefore devirtualize the member function call. 1649a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (MD->getParent()->hasAttr<FinalAttr>()) 1650a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1651a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1652a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson Base = skipNoOpCastsAndParens(Base); 1653a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 1654a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 1655a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // This is a record decl. We know the type and can devirtualize it. 1656a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return VD->getType()->isRecordType(); 1657a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1658a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1659a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1660a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson } 1661a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1662a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can always devirtualize calls on temporary object expressions. 1663a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXConstructExpr>(Base)) 1664a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1665a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1666a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // And calls on bound temporaries. 1667a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (isa<CXXBindTemporaryExpr>(Base)) 1668a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1669a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1670a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // Check if this is a call expr that returns a record type. 1671a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) 1672a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CE->getCallReturnType()->isRecordType(); 1673a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1674a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // We can't devirtualize the call. 1675a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1676a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1677a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1678a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonstatic bool UseVirtualCall(ASTContext &Context, 1679a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXOperatorCallExpr *CE, 1680a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD) { 1681a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (!MD->isVirtual()) 1682a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return false; 1683a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1684a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // When building with -fapple-kext, all calls must go through the vtable since 1685a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson // the kernel linker can do runtime patching of vtables. 1686a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (Context.getLangOptions().AppleKext) 1687a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return true; 1688a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1689a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD); 1690a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1691a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1692a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlssonllvm::Value * 1693a2447e0d1e28669cd637204a871f15b1215277fdAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, 1694a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const CXXMethodDecl *MD, 1695a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson llvm::Value *This) { 1696a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 16972acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = 1698a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 1699a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson FPT->isVariadic()); 1700a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1701a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson if (UseVirtualCall(getContext(), E, MD)) 1702a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return BuildVirtualCall(MD, This, Ty); 1703a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson 1704a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson return CGM.GetAddrOfFunction(MD, Ty); 1705a2447e0d1e28669cd637204a871f15b1215277fdAnders Carlsson} 1706