CGClass.cpp revision 9cfe0ec4decfd19a0387bb737f28eb0ea2c3a476
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 145d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 152f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 165d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 172f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 195d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 212f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic uint64_t 222f1986b557fa671c4f8c9dd0d071398edfc073d5Anders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths, 232f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson unsigned Start) { 242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = 0; 255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 262f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBasePath &Path = Paths.front(); 272f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson for (unsigned i = Start, e = Path.size(); i != e; ++i) { 282f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBasePathElement& Element = Path[i]; 295d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 302f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson // Get the layout. 312f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 325d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 332f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBaseSpecifier *BS = Element.Base; 342f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(!BS->isVirtual() && "Should not see virtual bases here!"); 355d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 362f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *Base = 372f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl()); 382f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 392f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson // Add the offset. 402f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson Offset += Layout.getBaseClassOffset(Base) / 8; 412f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 422f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 432f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return Offset; 445d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 455d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 4684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 472b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders CarlssonCodeGenModule::GetCXXBaseClassOffset(const CXXRecordDecl *ClassDecl, 482b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson const CXXRecordDecl *BaseClassDecl) { 4984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson if (ClassDecl == BaseClassDecl) 5084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 5184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 522f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 532f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 542f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 552f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 562f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 572f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return 0; 582f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 5984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 602f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), Paths, 0); 6184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson if (!Offset) 6284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 6384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 642b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson const llvm::Type *PtrDiffTy = 652b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 6684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 6784080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return llvm::ConstantInt::get(PtrDiffTy, Offset); 6884080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 702f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic llvm::Value *GetCXXBaseClassOffset(CodeGenFunction &CGF, 712f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *BaseValue, 722f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *ClassDecl, 732f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *BaseClassDecl) { 742f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 758432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman /*RecordPaths=*/true, /*DetectVirtual=*/false); 762f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 772f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 782f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 792f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return 0; 802f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 812f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 822f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson unsigned Start = 0; 832f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *VirtualOffset = 0; 848432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman 858432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXBasePath &Path = Paths.front(); 868432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXRecordDecl *VBase = 0; 878432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman for (unsigned i = 0, e = Path.size(); i != e; ++i) { 888432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXBasePathElement& Element = Path[i]; 898432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman if (Element.Base->isVirtual()) { 908432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman Start = i+1; 918432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman QualType VBaseType = Element.Base->getType(); 928432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 932f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 942f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 958432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman if (VBase) 968432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman VirtualOffset = 978432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman CGF.GetVirtualCXXBaseClassOffset(BaseValue, ClassDecl, VBase); 982f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 992f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = 1002f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson ComputeNonVirtualBaseClassOffset(CGF.getContext(), Paths, Start); 1012f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1022f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!Offset) 1032f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return VirtualOffset; 1042f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1052f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const llvm::Type *PtrDiffTy = 1062f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1072f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset); 1082f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1092f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (VirtualOffset) 1102f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return CGF.Builder.CreateAdd(VirtualOffset, NonVirtualOffset); 1112f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1122f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return NonVirtualOffset; 1132f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson} 1142f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1159fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on 1169fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that 1179fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well. 1189fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment 1199fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl, 1209fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 1219fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 1229fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 1239fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 1249fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 1259fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson assert(false && "Class must be derived from the passed in base class!"); 1269fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(); 1279fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 1289fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1299fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson unsigned Start = 0; 1309fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t VirtualOffset = 0; 1319fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1329fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePath &Path = Paths.front(); 1339fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *VBase = 0; 1349fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson for (unsigned i = 0, e = Path.size(); i != e; ++i) { 1359fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePathElement& Element = Path[i]; 1369fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (Element.Base->isVirtual()) { 1379fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson Start = i+1; 1389fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson QualType VBaseType = Element.Base->getType(); 1399fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 1409fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 1419fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 1429fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (VBase) 1439fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VirtualOffset = 1449fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 1459fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1469fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t Offset = 1479fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start); 1489fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(Offset, VirtualOffset); 1499fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson} 1509fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1515d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 152a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 153a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *ClassDecl, 154a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *BaseClassDecl, 155a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 156dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson QualType BTy = 157dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getCanonicalType( 158dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 159dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy)); 1605d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1612f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (ClassDecl == BaseClassDecl) { 162dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson // Just cast back. 163a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 164dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson } 1654a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 16632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNull = 0; 16732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 16832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastEnd = 0; 16932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 17032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 17132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull = createBasicBlock("cast.null"); 17232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 17332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastEnd = createBasicBlock("cast.end"); 17432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 17532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::Value *IsNull = 176a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 177a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 17832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 17932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNotNull); 18032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 18132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 1823c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 1834a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 1844a5dc242545222aef6313cc4297708f524e10c6fEli Friedman llvm::Value *Offset = 185a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson GetCXXBaseClassOffset(*this, Value, ClassDecl, BaseClassDecl); 1865d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1874a5dc242545222aef6313cc4297708f524e10c6fEli Friedman if (Offset) { 1884a5dc242545222aef6313cc4297708f524e10c6fEli Friedman // Apply the offset. 189a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, Int8PtrTy); 190a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateGEP(Value, Offset, "add.ptr"); 1914a5dc242545222aef6313cc4297708f524e10c6fEli Friedman } 1925d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1935d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson // Cast back. 194a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 19832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNull); 19932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 20032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastEnd); 20132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 202a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 203a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->reserveOperandSpace(2); 204a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 205a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 206a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull); 207a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 208a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 209a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 210a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 211a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson} 212a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 213a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value * 214a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 215a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *ClassDecl, 216a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *DerivedClassDecl, 217a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 218a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 219a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getCanonicalType( 220a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClassDecl))); 221a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (ClassDecl == DerivedClassDecl) { 224a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast back. 225a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 226a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 228a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 229a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 230a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 233a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *IsNull = 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *Offset = GetCXXBaseClassOffset(*this, Value, DerivedClassDecl, 245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson ClassDecl); 246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (Offset) { 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Apply the offset. 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreatePtrToInt(Value, Offset->getType()); 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateSub(Value, Offset); 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } else { 252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast. 253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 261a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 262a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 26332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson PHI->reserveOperandSpace(2); 264a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 265a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 26632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 26832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2695d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2715d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 272607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 273607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class 274607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Copying can be either a bitwise 275607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy or via a copy constructor call. 276607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitCXXAggrConstructorCall. 277607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest, 278607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Src, 279607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ArrayType *Array, 280607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 281607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 282607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 283607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(CA && "VLA cannot be copied over"); 284607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor(); 285607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 286607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Create a temporary for the loop index and initialize it with 0. 287607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 288607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "loop.index"); 289607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value* zeroConstant = 290607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 291607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(zeroConstant, IndexPtr); 292607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Start the loop with a block that tests the condition. 293607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 294607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 295607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 296607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(CondBlock); 297607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 298607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 299607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 300607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // otherwise, go to the block after the for-loop. 301607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 302607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value * NumElementsPtr = 303607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 304607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 305607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 306607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "isless"); 307607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the condition is true, execute the body. 308607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 309607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 310607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ForBody); 311607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 312607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Inside the loop body, emit the constructor call on the array element. 313607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 314607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 315607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 316607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BitwiseCopy) 317607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 318607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else if (CXXConstructorDecl *BaseCopyCtor = 319607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseClassDecl->getCopyConstructor(getContext(), 0)) { 320607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, 321607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Ctor_Complete); 322607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 323607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 324607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 325607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getThisType(getContext()))); 326607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 327607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 328607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Src), 329607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getParamDecl(0)->getType())); 330607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType ResultType = 331607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType(); 332607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 333607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor); 334607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 335607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ContinueBlock); 336607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 337607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the increment of the loop counter. 338607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 339607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 340607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 341607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(NextVal, IndexPtr); 342607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 343607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Finally, branch back up to the condition for the next iteration. 344607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBranch(CondBlock); 345607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 346607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the fall-through block. 347607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(AfterFor, true); 348607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 349607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 350607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrCopyAssignment - This routine generates code to assign a class 351607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Assignment can be either a 352607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// bitwise assignment or via a copy assignment operator function call. 353607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy 354607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest, 355607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Src, 356607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ArrayType *Array, 357607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 358607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 359607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 360607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(CA && "VLA cannot be asssigned"); 361607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment(); 362607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 363607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Create a temporary for the loop index and initialize it with 0. 364607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 365607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "loop.index"); 366607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value* zeroConstant = 367607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 368607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(zeroConstant, IndexPtr); 369607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Start the loop with a block that tests the condition. 370607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 371607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(CondBlock); 374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // otherwise, go to the block after the for-loop. 378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value * NumElementsPtr = 380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "isless"); 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the condition is true, execute the body. 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ForBody); 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Inside the loop body, emit the assignment operator call on array element. 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXMethodDecl *MD = 0; 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BitwiseAssign) 395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else { 3978a850baa41ea9015b949183667ad96a981f10b09Eli Friedman BaseClassDecl->hasConstCopyAssignment(getContext(), MD); 3988a850baa41ea9015b949183667ad96a981f10b09Eli Friedman assert(MD && "EmitClassAggrCopyAssignment - No user assign"); 399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *LTy = 401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 402607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FPT->isVariadic()); 403607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy); 404607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 405607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 406607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 407607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 408607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MD->getThisType(getContext()))); 409607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 410607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 4118a850baa41ea9015b949183667ad96a981f10b09Eli Friedman QualType SrcTy = MD->getParamDecl(0)->getType(); 4128a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) : 4138a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue::getAggregate(Src); 4148a850baa41ea9015b949183667ad96a981f10b09Eli Friedman CallArgs.push_back(std::make_pair(SrcValue, SrcTy)); 415607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType(); 416607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 417607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, MD); 418607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 419607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ContinueBlock); 420607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 421607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the increment of the loop counter. 422607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 423607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(NextVal, IndexPtr); 426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Finally, branch back up to the condition for the next iteration. 428607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBranch(CondBlock); 429607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 430607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the fall-through block. 431607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(AfterFor, true); 432607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 433607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 434c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a 435c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases. 436c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) { 437c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (!CGVtableInfo::needsVTTParameter(GD)) { 438c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 439c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 440c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 441c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 442c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); 443c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 444c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 445c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 446c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 447c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson uint64_t SubVTTIndex = 448c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base); 449c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 450c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 451c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) { 452c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 453c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.LoadCXXVTT(); 454c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 455c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 456c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 457c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.CGM.getVtableInfo().getVTT(RD); 458c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 459c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 460c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 461c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 462c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 463c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 464c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 465607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassMemberwiseCopy - This routine generates code to copy a class 466607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Copying can be either a bitwise copy 467607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// or via a copy constructor call. 468607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassMemberwiseCopy( 469607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Dest, llvm::Value *Src, 470607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 471607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, QualType Ty) { 472c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CXXCtorType CtorType = Ctor_Complete; 473c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 474607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (ClassDecl) { 475607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl, 476607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 477607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl, 478607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 479c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 480c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We want to call the base constructor. 481c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CtorType = Ctor_Base; 482607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 483607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialCopyConstructor()) { 484607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 485607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 486607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 487607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 488607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CXXConstructorDecl *BaseCopyCtor = 489607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseClassDecl->getCopyConstructor(getContext(), 0)) { 490c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType); 491607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 492607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 493607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 494607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getThisType(getContext()))); 495607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 496c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // Push the VTT parameter, if necessary. 497c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (llvm::Value *VTT = 498c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) { 499c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson QualType T = getContext().getPointerType(getContext().VoidPtrTy); 500c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CallArgs.push_back(std::make_pair(RValue::get(VTT), T)); 501c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 502c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 503607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 504607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Src), 505607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getParamDecl(0)->getType())); 506607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType ResultType = 507607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType(); 508607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 509607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor); 510607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 511607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 512607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 513607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassCopyAssignment - This routine generates code to copy assign a class 514607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Assignment can be either a bitwise 515607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assignment of via an assignment operator call. 516607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot. 517607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassCopyAssignment( 518607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Dest, llvm::Value *Src, 519607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 520607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 521607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 522607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (ClassDecl) { 523607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl, 524607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 525607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl, 526607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 527607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 528607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialCopyAssignment()) { 529607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 530607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 531607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 532607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 533607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXMethodDecl *MD = 0; 5348a850baa41ea9015b949183667ad96a981f10b09Eli Friedman BaseClassDecl->hasConstCopyAssignment(getContext(), MD); 5358a850baa41ea9015b949183667ad96a981f10b09Eli Friedman assert(MD && "EmitClassCopyAssignment - missing copy assign"); 536607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *LTy = 539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FPT->isVariadic()); 541607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy); 542607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 544607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MD->getThisType(getContext()))); 547607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 5498a850baa41ea9015b949183667ad96a981f10b09Eli Friedman QualType SrcTy = MD->getParamDecl(0)->getType(); 5508a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) : 5518a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue::getAggregate(Src); 5528a850baa41ea9015b949183667ad96a981f10b09Eli Friedman CallArgs.push_back(std::make_pair(SrcValue, SrcTy)); 553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType ResultType = 554607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MD->getType()->getAs<FunctionType>()->getResultType(); 555607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 556607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, MD); 557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 558607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 559607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeDefaultConstructor - synthesize a default constructor 560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid 561607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor, 562607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType Type, 563607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 564607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); 566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCtorPrologue(Ctor, Type); 569607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 570607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 571607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 572607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a 573607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03 574607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy constructor for class X performs a memberwise 575607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy of its subobjects. The order of copying is the same as the order of 576607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// initialization of bases and members in a user-defined constructor 577607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Each subobject is copied in the manner appropriate to its type: 578607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of class type, the copy constructor for the class is 579607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used; 580607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is an array, each element is copied, in the manner 581607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// appropriate to the element type; 582607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of scalar type, the built-in assignment operator is 583607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used. 584607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Virtual base class subobjects shall be copied only once by the 585607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly-defined copy constructor 586607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 587607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid 588607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor, 589607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType Type, 590607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 591607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 592607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = Ctor->getParent(); 593607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 594607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeCXXCopyConstructor - copy constructor has definition already"); 595607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); 596607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 597607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 598607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 599607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FunctionArgList::const_iterator i = Args.begin(); 600607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *ThisArg = i->first; 601607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 602607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 603607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *SrcArg = (i+1)->first; 604607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 605607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 606607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 607607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 608607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base != ClassDecl->bases_end(); ++Base) { 609607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME. copy constrution of virtual base NYI 610607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base->isVirtual()) 611607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 612607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 613607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 615607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 616607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base->getType()); 617607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 618607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 619607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 620607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 621607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = *I; 622607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 623607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType(Field->getType()); 624607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 625607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 626607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 627607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 628607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 629607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 630607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl 631607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(FieldClassType->getDecl()); 632e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, Field, 0); 633e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, Field, 0); 634607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 635607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 636607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *DestBaseAddrPtr = 638607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 639607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcBaseAddrPtr = 640607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(RHS.getAddress(), BasePtr); 641607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldClassDecl, FieldType); 643607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 644607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 645607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(), 646607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 0 /*ClassDecl*/, FieldClassDecl, FieldType); 647607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 648607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Do a built-in assignment of scalar data members. 6519cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson LValue LHS = EmitLValueForFieldInitialization(LoadOfThis, Field, 0); 6529cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson LValue RHS = EmitLValueForFieldInitialization(LoadOfSrc, Field, 0); 653607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 654607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!hasAggregateLLVMType(Field->getType())) { 655607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType()); 656607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitStoreThroughLValue(RVRHS, LHS, Field->getType()); 657607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (Field->getType()->isAnyComplexType()) { 658607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(), 659607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS.isVolatileQualified()); 660607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified()); 661607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 662607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType()); 663607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 664607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 665607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 666607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson InitializeVtablePtrs(ClassDecl); 667607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 668607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 669607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 670607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator. 671607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Before the implicitly-declared copy assignment operator for a class is 672607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined, all implicitly- declared copy assignment operators for 673607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// its direct base classes and its nonstatic data members shall have been 674607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined. [12.8-p12] 675607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy assignment operator for class X performs 676607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// memberwise assignment of its subob- jects. The direct base classes of X are 677607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assigned first, in the order of their declaration in 678607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// the base-specifier-list, and then the immediate nonstatic data members of X 679607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// are assigned, in the order in which they were declared in the class 680607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// definition.Each subobject is assigned in the manner appropriate to its type: 681607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of class type, the copy assignment operator for the 682607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// class is used (as if by explicit qualification; that is, ignoring any 683607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// possible virtual overriding functions in more derived classes); 684607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// 685607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is an array, each element is assigned, in the manner 686607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// appropriate to the element type; 687607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// 688607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of scalar type, the built-in assignment operator is 689607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used. 690607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD, 691607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 692607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 693607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 694607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 695607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!ClassDecl->hasUserDeclaredCopyAssignment() && 696607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeCXXCopyAssignment - copy assignment has user declaration"); 697607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation()); 698607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 699607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FunctionArgList::const_iterator i = Args.begin(); 700607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *ThisArg = i->first; 701607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 702607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 703607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *SrcArg = (i+1)->first; 704607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 705607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 706607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 707607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 708607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base != ClassDecl->bases_end(); ++Base) { 709607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME. copy assignment of virtual base NYI 710607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base->isVirtual()) 711607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 712607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 713607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 714607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 715607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 716607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base->getType()); 717607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 718607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 719607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 720607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldEnd = ClassDecl->field_end(); 721607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Field != FieldEnd; ++Field) { 722607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 723607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 724607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 725607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 726607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 727607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 728607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 729607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl 730607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(FieldClassType->getDecl()); 731e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0); 732e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0); 733607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 734607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 735607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 736607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *DestBaseAddrPtr = 737607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 738607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcBaseAddrPtr = 739607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(RHS.getAddress(), BasePtr); 740607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 741607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldClassDecl, FieldType); 742607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 743607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 744607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(), 745607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 0 /*ClassDecl*/, FieldClassDecl, FieldType); 746607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 747607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 748607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Do a built-in assignment of scalar data members. 749e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0); 750e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0); 751607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!hasAggregateLLVMType(Field->getType())) { 752607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType()); 753607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitStoreThroughLValue(RVRHS, LHS, Field->getType()); 754607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (Field->getType()->isAnyComplexType()) { 755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(), 756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS.isVolatileQualified()); 757607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified()); 758607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 759607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType()); 760607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 761607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 763607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // return *this; 764607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(LoadOfThis, ReturnValue); 765607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 766607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 767607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 768607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 769607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 770607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 771607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *BaseInit, 772607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 773607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 774607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 775607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 776607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 777607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 778607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 779607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 780607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 781607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 782607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: This method of determining whether a base is virtual is ridiculous; 783607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // it should be part of BaseInit. 784607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool isBaseVirtual = false; 785607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), 786607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->vbases_end(); I != E; ++I) 787607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (I->getType()->getAs<RecordType>()->getDecl() == BaseClassDecl) { 788607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson isBaseVirtual = true; 789607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson break; 790607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 791607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 792607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 793607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 794607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 795607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 796607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Compute the offset to the base; we do this directly instead of using 797607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // GetAddressOfBaseClass because the class doesn't have a vtable pointer 798607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // at this point. 799607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: This could be refactored back into GetAddressOfBaseClass if it took 800607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // an extra parameter for whether the derived class is the complete object 801607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // class. 802607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ASTRecordLayout &Layout = 803607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.getContext().getASTRecordLayout(ClassDecl); 804607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson uint64_t Offset; 805607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (isBaseVirtual) 806607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Offset = Layout.getVBaseClassOffset(BaseClassDecl); 807607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 808607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Offset = Layout.getBaseClassOffset(BaseClassDecl); 809607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 810607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BaseClassType = CGF.ConvertType(QualType(BaseType, 0)); 811607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy); 812607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset/8); 813607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo()); 814607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitCXXConstructorCall(BaseInit->getConstructor(), 816c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Ctor_Base, V, 817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseInit->const_arg_begin(), 818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseInit->const_arg_end()); 819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *MemberInit) { 824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(MemberInit->isMemberInitializer() && 825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 828607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecl *Field = MemberInit->getMember(); 829607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = CGF.getContext().getCanonicalType(Field->getType()); 830607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 831607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 83206a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); 83306a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson 834607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we are initializing an anonymous union field, drill down to the field. 835607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getAnonUnionMember()) { 836607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Field = MemberInit->getAnonUnionMember(); 837e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0); 838607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = Field->getType(); 839607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 840607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 841607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the field is an array, branch based on the element type. 842607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 843607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.getContext().getAsConstantArrayType(FieldType); 844607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 845607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = CGF.getContext().getBaseElementType(FieldType); 846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 847607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // We lose the constructor for anonymous union members, so handle them 848607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // explicitly. 849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: This is somwhat ugly. 850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getAnonUnionMember() && FieldType->getAs<RecordType>()) { 851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getNumArgs()) 852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitAggExpr(*MemberInit->arg_begin(), LHS.getAddress(), 853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 855607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitAggregateClear(LHS.getAddress(), Field->getType()); 856607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 858607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 859607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldType->getAs<RecordType>()) { 860607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(MemberInit->getConstructor() && 861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "EmitCtorPrologue - no constructor to initialize member"); 862607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 863607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = CGF.ConvertType(FieldType); 864607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 865607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *BaseAddrPtr = 866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr); 867607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitCXXAggrConstructorCall(MemberInit->getConstructor(), 868607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Array, BaseAddrPtr, 869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MemberInit->const_arg_begin(), 870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MemberInit->const_arg_end()); 871607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 872607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitCXXConstructorCall(MemberInit->getConstructor(), 874607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Ctor_Complete, LHS.getAddress(), 875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MemberInit->const_arg_begin(), 876607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MemberInit->const_arg_end()); 877607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 879607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 880607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(MemberInit->getNumArgs() == 1 && "Initializer count must be 1 only"); 881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Expr *RhsExpr = *MemberInit->arg_begin(); 882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RHS; 883607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldType->isReferenceType()) { 884607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS = CGF.EmitReferenceBindingToExpr(RhsExpr, FieldType, 885607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*IsInitializer=*/true); 886607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 887607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (Array) { 888607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType()); 889607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (!CGF.hasAggregateLLVMType(RhsExpr->getType())) { 890607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS = RValue::get(CGF.EmitScalarExpr(RhsExpr, true)); 891607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 892607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (RhsExpr->getType()->isAnyComplexType()) { 893607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitComplexExprIntoAddr(RhsExpr, LHS.getAddress(), 894607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 895607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 896607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Handle member function pointers; other aggregates shouldn't get this far. 897607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitAggExpr(RhsExpr, LHS.getAddress(), LHS.isVolatileQualified()); 898607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 899607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 900607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 901607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 902607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 903607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXCtorType. 904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Add vbase initialization 909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 912607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 913607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *Member = (*B); 914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(LiveTemporaries.empty() && 916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not have any live temporaries at initializer start!"); 917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Member->isBaseInitializer()) 919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitMemberInitializer(*this, ClassDecl, Member); 922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Pop any live temporaries that the initializers might have pushed. 924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson while (!LiveTemporaries.empty()) 925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson PopCXXTemporary(); 926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 928607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson InitializeVtablePtrs(ClassDecl); 929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 932607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 933607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 934607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType. 935607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD, 936607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType) { 937607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 938607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = DD->getParent(); 941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Collect the fields. 943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::SmallVector<const FieldDecl *, 16> FieldDecls; 944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = *I; 947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType(Field->getType()); 949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!RT) 953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldClassDecl->hasTrivialDestructor()) 957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecls.push_back(Field); 960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Now destroy the fields. 963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (size_t i = FieldDecls.size(); i > 0; --i) { 964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = FieldDecls[i - 1]; 965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = Field->getType(); 967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LValue LHS = EmitLValueForField(ThisPtr, Field, 978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Qualifiers? 979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*CVRQualifiers=*/0); 980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *BaseAddrPtr = 984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Array, BaseAddrPtr); 987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else 988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dtor_Complete, LHS.getAddress()); 990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Destroy non-virtual bases. 993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) { 995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore virtual bases. 998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base.isVirtual()) 999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), 1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl, BaseClassDecl, 1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we're emitting a base destructor, we don't want to emit calls to the 1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // virtual bases. 1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Base) 1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Handle virtual bases. 1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) { 1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), 1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl, BaseClassDecl, 1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 1034607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 1035607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1036607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1037607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we have a deleting destructor, emit a call to the delete operator. 1038607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Deleting) { 1039607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(DD->getOperatorDelete() && 1040607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "operator delete missing - EmitDtorEpilogue"); 1041607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(), 1042607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getTagDeclType(ClassDecl)); 1043607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1044607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1045607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1046607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor, 1047607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType, 1048607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 1049607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 1050607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Dtor->getParent()->hasUserDeclaredDestructor() && 1051607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeDefaultDestructor - destructor has user declaration"); 1052607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1053607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args, 1054607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 1055607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1056607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDtorEpilogue(Dtor, DtorType); 1057607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 1058607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 10593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested) 10613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the 10623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array. 10633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the 10643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array. 10653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller. 10663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10673b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *ArrayTy, 10693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value * NumElements = 10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::ConstantInt::get(SizeTy, 10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getConstantArrayElementCount(ArrayTy)); 10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd); 10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NumElements, 10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with 0. 10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index"); 10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Zero, IndexPtr); 10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless"); 11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "arrayidx"); 11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Keep track of the current number of live temporaries. 11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson unsigned OldNumLiveTemporaries = LiveTemporaries.size(); 11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd); 11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Pop temporaries. 11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson while (LiveTemporaries.size() > OldNumLiveTemporaries) 11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PopCXXTemporary(); 11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the increment of the loop counter. 11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1); 11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(NextVal, IndexPtr); 11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(CA && "Do we support VLA for destruction ?"); 11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); 11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount); 11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, ElementCountPtr, This); 11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *UpperCount, 11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1); 11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with count of 11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // array elements. 11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index"); 11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store the number of elements in the index pointer. 11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(UpperCount, IndexPtr); 11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index != 0 fall to the loop body, 11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* zeroConstant = 11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant::getNullValue(SizeLTy); 11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, 11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "isne"); 11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsNE, ForBody, AfterFor); 11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One); 12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); 12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXDestructorCall(D, Dtor_Complete, Address); 12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the decrement of the loop counter. 12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One, "dec"); 12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Counter, IndexPtr); 12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction. 12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant * 12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionArgList Args; 12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl *Dst = 12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl::Create(getContext(), 0, 12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), 0, 12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getPointerType(getContext().VoidTy)); 12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::SmallString<16> Name; 12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount); 12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType R = getContext().VoidTy; 12383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args); 12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function *Fn = 12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Name.str(), 12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson &CGM.getModule()); 12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str()); 12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl *FD = FunctionDecl::Create(getContext(), 12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getTranslationUnitDecl(), 12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), II, R, 0, 12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl::Static, 12493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson false, true); 12503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson StartFunction(FD, R, Fn, Args, SourceLocation()); 12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy); 12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FinishFunction(); 12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 0); 12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return m; 12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1263c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 12653b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXCtorType Type, 12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (D->isCopyConstructor()) { 12713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext()); 12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (ClassDecl->hasTrivialCopyConstructor()) { 12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 12743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "EmitCXXConstructorCall - user declared copy constructor"); 12753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const Expr *E = (*ArgBeg); 12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType Ty = E->getType(); 12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Src = EmitLValue(E).getAddress(); 12783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitAggregateCopy(This, Src, Ty); 12793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } else if (D->isTrivial()) { 12823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // FIXME: Track down why we're trying to generate calls to the trivial 12833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor! 12843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1287c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type)); 12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 12893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); 12913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 12943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 12953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1296c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type)); 12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1299c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); 13003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 13033b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GetVirtualCXXBaseClassOffset(llvm::Value *This, 13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl, 13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = 13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VTablePtr = Builder.CreateBitCast(This, 13103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Int8PtrTy->getPointerTo()); 13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VTablePtr = Builder.CreateLoad(VTablePtr, "vtable"); 13123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson int64_t VBaseOffsetIndex = 13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 13173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr"); 13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *PtrDiffTy = 13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { 13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl); 133421431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints = 133521431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl]; 13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for virtual bases 13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) { 13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl); 13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, Offset); 13483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases and current class 13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0); 13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive( 13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl, 13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable, 135721431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints, 13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr, 13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset) { 13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases 13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (Base.isVirtual()) 13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson continue; 13703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl); 13733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, NewOffset); 13753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address point 13783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && 13793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "Missing address point for class"); 13803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; 13813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableAddressPoint = 13823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); 13833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address to store the address point 13853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 13863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy); 13873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8); 13883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *AddressPointPtrTy = 13893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableAddressPoint->getType()->getPointerTo(); 13903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy); 13913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address point 13933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(VtableAddressPoint, VtableField); 13943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1395c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1396c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() { 1397c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson assert((isa<CXXConstructorDecl>(CurFuncDecl) || 1398c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson isa<CXXDestructorDecl>(CurFuncDecl)) && 1399c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson "Must be in a C++ ctor or dtor to load the vtt parameter"); 1400c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1401c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); 1402c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 1403