CGClass.cpp revision 9db7dbb918ca49f4ee6c181e4917e7b6ec547353
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 * 47bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class, 48bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *BaseClass) { 49bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (Class == BaseClass) 5084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 5184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 522f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 532f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 54bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (!const_cast<CXXRecordDecl *>(Class)-> 55bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), 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 709fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on 719fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that 729fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well. 739fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment 749fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl, 759fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 769fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 779fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 789fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 799fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 809fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson assert(false && "Class must be derived from the passed in base class!"); 819fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(); 829fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 839fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 849fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson unsigned Start = 0; 859fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t VirtualOffset = 0; 869fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 879fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePath &Path = Paths.front(); 889fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *VBase = 0; 899fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson for (unsigned i = 0, e = Path.size(); i != e; ++i) { 909fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePathElement& Element = Path[i]; 919fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (Element.Base->isVirtual()) { 929fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson Start = i+1; 939fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson QualType VBaseType = Element.Base->getType(); 949fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 959fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 969fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 979fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (VBase) 989fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VirtualOffset = 999fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 1009fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1019fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t Offset = 1029fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start); 1039fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(Offset, VirtualOffset); 1049fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson} 1059fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1065d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 107a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 108bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *Class, 109bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *BaseClass, 110a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 111dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson QualType BTy = 112dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getCanonicalType( 113bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClass))); 114dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy)); 1155d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 116bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (Class == BaseClass) { 117dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson // Just cast back. 118a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 119dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson } 120905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 121905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 122905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 123905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (!const_cast<CXXRecordDecl *>(Class)-> 124905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) { 125905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 126905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson return 0; 127905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 128905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 129905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson unsigned Start = 0; 130905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *VirtualOffset = 0; 131905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 132905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXBasePath &Path = Paths.front(); 133905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXRecordDecl *VBase = 0; 134905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson for (unsigned i = 0, e = Path.size(); i != e; ++i) { 135905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXBasePathElement& Element = Path[i]; 136905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (Element.Base->isVirtual()) { 137905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Start = i+1; 138905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson QualType VBaseType = Element.Base->getType(); 139905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 140905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 141905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 142905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 143905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson uint64_t Offset = 144905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start); 1454a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 146905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (!Offset && !VBase) { 147905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson // Just cast back. 148905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 149905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 150905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 15132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNull = 0; 15232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 15332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastEnd = 0; 15432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 15532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 15632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull = createBasicBlock("cast.null"); 15732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 15832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastEnd = createBasicBlock("cast.end"); 15932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 16032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::Value *IsNull = 161a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 162a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 16332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 16432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNotNull); 16532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 16632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 167905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (VBase) 168905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase); 1694a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 170905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); 171905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *NonVirtualOffset = 0; 172905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (Offset) 173905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset); 1745d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 175905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *BaseOffset; 176905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (VBase) { 177905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (NonVirtualOffset) 178905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = Builder.CreateAdd(VirtualOffset, NonVirtualOffset); 179905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson else 180905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = VirtualOffset; 181905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } else 182905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = NonVirtualOffset; 183905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 184905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson // Apply the base offset. 185905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 186905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Value = Builder.CreateBitCast(Value, Int8PtrTy); 187905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Value = Builder.CreateGEP(Value, BaseOffset, "add.ptr"); 1885d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1895d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson // Cast back. 190a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 19132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 19232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 19332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 19432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNull); 19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastEnd); 19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 198a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 199a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->reserveOperandSpace(2); 200a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 201a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 202a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull); 203a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 204a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 205a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 206a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 207a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson} 208a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 209a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value * 210a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 211bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *Class, 212bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *DerivedClass, 213a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 214a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 215a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getCanonicalType( 216bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass))); 217a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 218a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 219bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (Class == DerivedClass) { 220a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast back. 221a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 224a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 225a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class); 226a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 227a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 228a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 229a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 230a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 231a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 233a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *IsNull = 242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 248a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 249a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType()); 250a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateSub(Value, NonVirtualOffset); 251a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 252a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 253a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 254a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 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()); 8149db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true); 815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 816607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *MemberInit) { 820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(MemberInit->isMemberInitializer() && 821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecl *Field = MemberInit->getMember(); 825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = CGF.getContext().getCanonicalType(Field->getType()); 826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 82806a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); 82906a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson 830607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we are initializing an anonymous union field, drill down to the field. 831607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getAnonUnionMember()) { 832607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Field = MemberInit->getAnonUnionMember(); 833e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0); 834607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = Field->getType(); 835607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 836607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 837607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the field is an array, branch based on the element type. 838607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 839607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.getContext().getAsConstantArrayType(FieldType); 840607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 841607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = CGF.getContext().getBaseElementType(FieldType); 842607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 843607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // We lose the constructor for anonymous union members, so handle them 844607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // explicitly. 8459db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor // FIXME: This is somwhat ugly, and doesn't seem necessary at all. 846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getAnonUnionMember() && FieldType->getAs<RecordType>()) { 8479db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor if (MemberInit->getInit()) 8489db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), 849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitAggregateClear(LHS.getAddress(), Field->getType()); 852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 8559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer 8569db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor // was implicitly generated, we shouldn't be zeroing memory. 857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RHS; 858607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldType->isReferenceType()) { 8599db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(), FieldType, 8609db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor /*IsInitializer=*/true); 861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 8629db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (Array && !MemberInit->getInit()) { 863607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType()); 8649db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (!CGF.hasAggregateLLVMType(Field->getType())) { 8659db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true)); 866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 8679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (MemberInit->getInit()->getType()->isAnyComplexType()) { 8689db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(), 869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 8719db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), 8729db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor LHS.isVolatileQualified(), false, true); 873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 874607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 876607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 877607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXCtorType. 879607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 880607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 883607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Add vbase initialization 884607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 885607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 886607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 887607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 888607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *Member = (*B); 889607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 890607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(LiveTemporaries.empty() && 891607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not have any live temporaries at initializer start!"); 892607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 893607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Member->isBaseInitializer()) 894607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 895607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 896607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitMemberInitializer(*this, ClassDecl, Member); 897607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 898607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Pop any live temporaries that the initializers might have pushed. 899607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson while (!LiveTemporaries.empty()) 900607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson PopCXXTemporary(); 901607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 902607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 903607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson InitializeVtablePtrs(ClassDecl); 904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType. 910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD, 911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType) { 912607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 913607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = DD->getParent(); 916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Collect the fields. 918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::SmallVector<const FieldDecl *, 16> FieldDecls; 919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = *I; 922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType(Field->getType()); 924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!RT) 928607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldClassDecl->hasTrivialDestructor()) 932607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 933607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 934607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecls.push_back(Field); 935607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 936607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 937607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Now destroy the fields. 938607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (size_t i = FieldDecls.size(); i > 0; --i) { 939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = FieldDecls[i - 1]; 940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = Field->getType(); 942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LValue LHS = EmitLValueForField(ThisPtr, Field, 953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Qualifiers? 954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*CVRQualifiers=*/0); 955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *BaseAddrPtr = 959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Array, BaseAddrPtr); 962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else 963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dtor_Complete, LHS.getAddress()); 965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Destroy non-virtual bases. 968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) { 970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore virtual bases. 973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base.isVirtual()) 974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), 985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl, BaseClassDecl, 986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we're emitting a base destructor, we don't want to emit calls to the 991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // virtual bases. 992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Base) 993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Handle virtual bases. 996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) { 998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), 1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl, BaseClassDecl, 1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we have a deleting destructor, emit a call to the delete operator. 1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Deleting) { 1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(DD->getOperatorDelete() && 1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "operator delete missing - EmitDtorEpilogue"); 1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(), 1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getTagDeclType(ClassDecl)); 1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor, 1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType, 1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Dtor->getParent()->hasUserDeclaredDestructor() && 1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeDefaultDestructor - destructor has user declaration"); 1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args, 1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDtorEpilogue(Dtor, DtorType); 1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 10343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested) 10363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the 10373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array. 10383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the 10393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array. 10403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller. 10413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10423b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *ArrayTy, 10443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value * NumElements = 10503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::ConstantInt::get(SizeTy, 10513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getConstantArrayElementCount(ArrayTy)); 10523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd); 10543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 10553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10573b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NumElements, 10593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with 0. 10653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index"); 10663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 10673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Zero, IndexPtr); 10683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless"); 10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "arrayidx"); 10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Keep track of the current number of live temporaries. 11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson unsigned OldNumLiveTemporaries = LiveTemporaries.size(); 11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd); 11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Pop temporaries. 11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson while (LiveTemporaries.size() > OldNumLiveTemporaries) 11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PopCXXTemporary(); 11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the increment of the loop counter. 11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1); 11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(NextVal, IndexPtr); 11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(CA && "Do we support VLA for destruction ?"); 11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); 11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount); 11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, ElementCountPtr, This); 11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *UpperCount, 11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1); 11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with count of 11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // array elements. 11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index"); 11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store the number of elements in the index pointer. 11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(UpperCount, IndexPtr); 11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index != 0 fall to the loop body, 11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* zeroConstant = 11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant::getNullValue(SizeLTy); 11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, 11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "isne"); 11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsNE, ForBody, AfterFor); 11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One); 11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); 11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXDestructorCall(D, Dtor_Complete, Address); 11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the decrement of the loop counter. 11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One, "dec"); 11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Counter, IndexPtr); 11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction. 11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant * 12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionArgList Args; 12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl *Dst = 12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl::Create(getContext(), 0, 12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), 0, 12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getPointerType(getContext().VoidTy)); 12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::SmallString<16> Name; 12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount); 12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType R = getContext().VoidTy; 12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args); 12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function *Fn = 12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Name.str(), 12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson &CGM.getModule()); 12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str()); 12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl *FD = FunctionDecl::Create(getContext(), 12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getTranslationUnitDecl(), 12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), II, R, 0, 12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl::Static, 12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson false, true); 12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson StartFunction(FD, R, Fn, Args, SourceLocation()); 12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy); 12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FinishFunction(); 12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 0); 12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return m; 12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1238c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXCtorType Type, 12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (D->isCopyConstructor()) { 12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext()); 12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (ClassDecl->hasTrivialCopyConstructor()) { 12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 12493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "EmitCXXConstructorCall - user declared copy constructor"); 12503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const Expr *E = (*ArgBeg); 12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType Ty = E->getType(); 12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Src = EmitLValue(E).getAddress(); 12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitAggregateCopy(This, Src, Ty); 12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } else if (D->isTrivial()) { 12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // FIXME: Track down why we're trying to generate calls to the trivial 12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor! 12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1262c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type)); 12633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1265c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); 12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1271c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type)); 12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1274c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); 12753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1278bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1279bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = 12823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 12833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VTablePtr = Builder.CreateBitCast(This, 12853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Int8PtrTy->getPointerTo()); 12863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VTablePtr = Builder.CreateLoad(VTablePtr, "vtable"); 12873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson int64_t VBaseOffsetIndex = 12893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 12903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 12923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr"); 12933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *PtrDiffTy = 12943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 12953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 13003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { 13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl); 130921431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints = 131021431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl]; 13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 13123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for virtual bases 13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) { 13173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl); 13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, Offset); 13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases and current class 13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0); 13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive( 13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl, 13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable, 133221431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints, 13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr, 13343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset) { 13353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases 13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (Base.isVirtual()) 13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson continue; 13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl); 13483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, NewOffset); 13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address point 13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && 13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "Missing address point for class"); 13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; 13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableAddressPoint = 13573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); 13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address to store the address point 13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy); 13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8); 13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *AddressPointPtrTy = 13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableAddressPoint->getType()->getPointerTo(); 13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy); 13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address point 13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(VtableAddressPoint, VtableField); 13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1370c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1371c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() { 1372c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson assert((isa<CXXConstructorDecl>(CurFuncDecl) || 1373c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson isa<CXXDestructorDecl>(CurFuncDecl)) && 1374c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson "Must be in a C++ ctor or dtor to load the vtt parameter"); 1375c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1376c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); 1377c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 1378