CGClass.cpp revision bff225ecf77fb891596ecb1b27196310d268365e
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 22bff225ecf77fb891596ecb1b27196310d268365eJohn McCallComputeNonVirtualBaseClassOffset(ASTContext &Context, 23bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const CXXBasePath &Path, 242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson unsigned Start) { 252f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = 0; 265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 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 60bff225ecf77fb891596ecb1b27196310d268365eJohn McCall uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), 61bff225ecf77fb891596ecb1b27196310d268365eJohn McCall Paths.front(), 0); 6284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson if (!Offset) 6384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 6484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 652b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson const llvm::Type *PtrDiffTy = 662b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 6784080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 6884080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return llvm::ConstantInt::get(PtrDiffTy, Offset); 6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 719fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on 729fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that 739fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well. 749fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment 759fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl, 769fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 779fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 789fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 799fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 809fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 819fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson assert(false && "Class must be derived from the passed in base class!"); 829fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(); 839fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 849fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 859fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson unsigned Start = 0; 869fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t VirtualOffset = 0; 879fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 889fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePath &Path = Paths.front(); 899fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXRecordDecl *VBase = 0; 909fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson for (unsigned i = 0, e = Path.size(); i != e; ++i) { 919fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson const CXXBasePathElement& Element = Path[i]; 929fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (Element.Base->isVirtual()) { 939fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson Start = i+1; 949fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson QualType VBaseType = Element.Base->getType(); 959fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 969fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 979fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson } 989fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson if (VBase) 999fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson VirtualOffset = 1009fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 1019fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 1029fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson uint64_t Offset = 103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start); 1049fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson return ThunkAdjustment(Offset, VirtualOffset); 1059fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson} 1069fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson 107bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// Gets the address of a virtual base class within a complete object. 108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases 109bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors). 110bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// 111bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null. 112bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value * 113bff225ecf77fb891596ecb1b27196310d268365eJohn McCallCodeGenFunction::GetAddressOfBaseOfCompleteClass(llvm::Value *This, 114bff225ecf77fb891596ecb1b27196310d268365eJohn McCall bool isBaseVirtual, 115bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const CXXRecordDecl *Derived, 116bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const CXXRecordDecl *Base) { 117bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // 'this' must be a pointer (in some address space) to Derived. 118bff225ecf77fb891596ecb1b27196310d268365eJohn McCall assert(This->getType()->isPointerTy() && 119bff225ecf77fb891596ecb1b27196310d268365eJohn McCall cast<llvm::PointerType>(This->getType())->getElementType() 120bff225ecf77fb891596ecb1b27196310d268365eJohn McCall == ConvertType(Derived)); 121bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 122bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Compute the offset of the virtual base. 123bff225ecf77fb891596ecb1b27196310d268365eJohn McCall uint64_t Offset; 124bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 125bff225ecf77fb891596ecb1b27196310d268365eJohn McCall if (isBaseVirtual) 126bff225ecf77fb891596ecb1b27196310d268365eJohn McCall Offset = Layout.getVBaseClassOffset(Base); 127bff225ecf77fb891596ecb1b27196310d268365eJohn McCall else 128bff225ecf77fb891596ecb1b27196310d268365eJohn McCall Offset = Layout.getBaseClassOffset(Base); 129bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 130bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // Shift and cast down to the base type. 131bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // TODO: for complete types, this should be possible with a GEP. 132bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = This; 133bff225ecf77fb891596ecb1b27196310d268365eJohn McCall if (Offset) { 134bff225ecf77fb891596ecb1b27196310d268365eJohn McCall const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 135bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, Int8PtrTy); 136bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateConstInBoundsGEP1_64(V, Offset / 8); 137bff225ecf77fb891596ecb1b27196310d268365eJohn McCall } 138bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo()); 139bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 140bff225ecf77fb891596ecb1b27196310d268365eJohn McCall return V; 141bff225ecf77fb891596ecb1b27196310d268365eJohn McCall} 142bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1435d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 144a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 145bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *Class, 146bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *BaseClass, 147a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 148dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson QualType BTy = 149dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getCanonicalType( 150bff225ecf77fb891596ecb1b27196310d268365eJohn McCall getContext().getTypeDeclType(BaseClass)); 151dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy)); 1525d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 153bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (Class == BaseClass) { 154dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson // Just cast back. 155a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 156dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson } 157905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 158905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 159905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 160905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (!const_cast<CXXRecordDecl *>(Class)-> 161905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) { 162905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 163905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson return 0; 164905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 165905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 166905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson unsigned Start = 0; 167905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *VirtualOffset = 0; 168905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 169905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXBasePath &Path = Paths.front(); 170905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXRecordDecl *VBase = 0; 171905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson for (unsigned i = 0, e = Path.size(); i != e; ++i) { 172905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const CXXBasePathElement& Element = Path[i]; 173905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (Element.Base->isVirtual()) { 174905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Start = i+1; 175905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson QualType VBaseType = Element.Base->getType(); 176905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 177905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 178905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 179905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 180905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson uint64_t Offset = 181bff225ecf77fb891596ecb1b27196310d268365eJohn McCall ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start); 1824a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 183905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (!Offset && !VBase) { 184905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson // Just cast back. 185905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 186905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } 187905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 18832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNull = 0; 18932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 19032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastEnd = 0; 19132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 19232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 19332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull = createBasicBlock("cast.null"); 19432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastEnd = createBasicBlock("cast.end"); 19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::Value *IsNull = 198a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 199a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 20032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 20132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNotNull); 20232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 20332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 204905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (VBase) 205905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase); 2064a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 207905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType()); 208905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *NonVirtualOffset = 0; 209905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (Offset) 210905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset); 2115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 212905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson llvm::Value *BaseOffset; 213905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (VBase) { 214905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson if (NonVirtualOffset) 215905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = Builder.CreateAdd(VirtualOffset, NonVirtualOffset); 216905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson else 217905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = VirtualOffset; 218905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson } else 219905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson BaseOffset = NonVirtualOffset; 220905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson 221905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson // Apply the base offset. 222905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 223905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Value = Builder.CreateBitCast(Value, Int8PtrTy); 224905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson Value = Builder.CreateGEP(Value, BaseOffset, "add.ptr"); 2255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 2265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson // Cast back. 227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 22832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 22932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 23032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 23132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNull); 23232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 23332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastEnd); 23432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->reserveOperandSpace(2); 237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull); 240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson} 245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value * 247a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 248bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *Class, 249bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *DerivedClass, 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getCanonicalType( 253bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass))); 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 256bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson if (Class == DerivedClass) { 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast back. 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 261a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson llvm::Value *NonVirtualOffset = 262a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class); 263a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (!NonVirtualOffset) { 265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // No offset, we can just cast back. 266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 267a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } 268a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 274a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 277a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 278a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *IsNull = 279a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 280a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 281a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 282a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 283a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 284a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 285a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Apply the offset. 286a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType()); 287a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateSub(Value, NonVirtualOffset); 288a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 289a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 290a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson // Just cast. 291a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 292a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 293a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 294a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 295a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 296a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 297a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 298a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 299a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 30032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson PHI->reserveOperandSpace(2); 301a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 302a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 30332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 304a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 30532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 3065d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 307a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 3085d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 309607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 310607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class 311607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Copying can be either a bitwise 312607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy or via a copy constructor call. 313607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitCXXAggrConstructorCall. 314607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest, 315607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Src, 316607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ArrayType *Array, 317607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 318607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 319607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 320607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(CA && "VLA cannot be copied over"); 321607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor(); 322607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 323607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Create a temporary for the loop index and initialize it with 0. 324607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 325607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "loop.index"); 326607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value* zeroConstant = 327607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 328607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(zeroConstant, IndexPtr); 329607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Start the loop with a block that tests the condition. 330607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 331607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 332607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 333607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(CondBlock); 334607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 335607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 336607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 337607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // otherwise, go to the block after the for-loop. 338607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 339607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value * NumElementsPtr = 340607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 341607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 342607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 343607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "isless"); 344607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the condition is true, execute the body. 345607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 346607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 347607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ForBody); 348607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 349607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Inside the loop body, emit the constructor call on the array element. 350607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 351607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 352607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 353607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BitwiseCopy) 354607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 355607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else if (CXXConstructorDecl *BaseCopyCtor = 356607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseClassDecl->getCopyConstructor(getContext(), 0)) { 357607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, 358607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Ctor_Complete); 359607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 360607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 361607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 362607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getThisType(getContext()))); 363607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 364607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 365607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Src), 366607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getParamDecl(0)->getType())); 36704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall const FunctionProtoType *FPT 36804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall = BaseCopyCtor->getType()->getAs<FunctionProtoType>(); 36904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT), 370607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor); 371607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ContinueBlock); 373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the increment of the loop counter. 375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(NextVal, IndexPtr); 379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Finally, branch back up to the condition for the next iteration. 381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBranch(CondBlock); 382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the fall-through block. 384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(AfterFor, true); 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrCopyAssignment - This routine generates code to assign a class 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Assignment can be either a 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// bitwise assignment or via a copy assignment operator function call. 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest, 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Src, 393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ArrayType *Array, 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(CA && "VLA cannot be asssigned"); 398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment(); 399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Create a temporary for the loop index and initialize it with 0. 401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 402607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "loop.index"); 403607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value* zeroConstant = 404607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 405607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(zeroConstant, IndexPtr); 406607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Start the loop with a block that tests the condition. 407607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 408607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 409607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 410607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(CondBlock); 411607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 412607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 413607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 414607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // otherwise, go to the block after the for-loop. 415607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 416607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value * NumElementsPtr = 417607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 418607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 419607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 420607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "isless"); 421607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If the condition is true, execute the body. 422607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 423607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ForBody); 425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Inside the loop body, emit the assignment operator call on array element. 427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 428607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 429607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 430607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXMethodDecl *MD = 0; 431607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BitwiseAssign) 432607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 433607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else { 4348a850baa41ea9015b949183667ad96a981f10b09Eli Friedman BaseClassDecl->hasConstCopyAssignment(getContext(), MD); 4358a850baa41ea9015b949183667ad96a981f10b09Eli Friedman assert(MD && "EmitClassAggrCopyAssignment - No user assign"); 436607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 437607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *LTy = 438607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 439607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FPT->isVariadic()); 440607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy); 441607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 442607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 443607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 444607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 445607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MD->getThisType(getContext()))); 446607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 447607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 4488a850baa41ea9015b949183667ad96a981f10b09Eli Friedman QualType SrcTy = MD->getParamDecl(0)->getType(); 4498a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) : 4508a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue::getAggregate(Src); 4518a850baa41ea9015b949183667ad96a981f10b09Eli Friedman CallArgs.push_back(std::make_pair(SrcValue, SrcTy)); 45204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT), 453607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, MD); 454607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 455607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(ContinueBlock); 456607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 457607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the increment of the loop counter. 458607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 459607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Counter = Builder.CreateLoad(IndexPtr); 460607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 461607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(NextVal, IndexPtr); 462607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 463607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Finally, branch back up to the condition for the next iteration. 464607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBranch(CondBlock); 465607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 466607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Emit the fall-through block. 467607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBlock(AfterFor, true); 468607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 469607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 470c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a 471c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases. 472c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) { 473c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (!CGVtableInfo::needsVTTParameter(GD)) { 474c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // This constructor/destructor does not need a VTT parameter. 475c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return 0; 476c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 477c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 478c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent(); 479c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 480c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 481c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT; 482c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 483c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson uint64_t SubVTTIndex = 484c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base); 485c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 486c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 487c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) { 488c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // A VTT parameter was passed to the constructor, use it. 489c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.LoadCXXVTT(); 490c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); 491c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } else { 492c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We're the complete constructor, so get the VTT by name. 493c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.CGM.getVtableInfo().getVTT(RD); 494c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex); 495c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 496c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 497c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return VTT; 498c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 499c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 500c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 501607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassMemberwiseCopy - This routine generates code to copy a class 502607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Copying can be either a bitwise copy 503607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// or via a copy constructor call. 504607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassMemberwiseCopy( 505607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Dest, llvm::Value *Src, 506607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 507607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, QualType Ty) { 508c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CXXCtorType CtorType = Ctor_Complete; 509c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 510607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (ClassDecl) { 511607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl, 512607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 513607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl, 514607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 515c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 516c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // We want to call the base constructor. 517c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CtorType = Ctor_Base; 518607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 519607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialCopyConstructor()) { 520607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 521607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 522607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 523607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 524607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CXXConstructorDecl *BaseCopyCtor = 525607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseClassDecl->getCopyConstructor(getContext(), 0)) { 526c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType); 527607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 528607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 529607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 530607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getThisType(getContext()))); 531607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 532c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // Push the VTT parameter, if necessary. 533c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (llvm::Value *VTT = 534c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) { 535c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson QualType T = getContext().getPointerType(getContext().VoidPtrTy); 536c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson CallArgs.push_back(std::make_pair(RValue::get(VTT), T)); 537c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson } 538c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Src), 541607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BaseCopyCtor->getParamDecl(0)->getType())); 54204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall const FunctionProtoType *FPT = 54304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall BaseCopyCtor->getType()->getAs<FunctionProtoType>(); 54404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT), 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor); 546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 547607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassCopyAssignment - This routine generates code to copy assign a class 550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Assignment can be either a bitwise 551607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assignment of via an assignment operator call. 552607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot. 553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassCopyAssignment( 554607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *Dest, llvm::Value *Src, 555607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 556607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *BaseClassDecl, 557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType Ty) { 558607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (ClassDecl) { 559607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl, 560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 561607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl, 562607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 563607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 564607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialCopyAssignment()) { 565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(Dest, Src, Ty); 566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 569607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXMethodDecl *MD = 0; 5708a850baa41ea9015b949183667ad96a981f10b09Eli Friedman BaseClassDecl->hasConstCopyAssignment(getContext(), MD); 5718a850baa41ea9015b949183667ad96a981f10b09Eli Friedman assert(MD && "EmitClassCopyAssignment - missing copy assign"); 572607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 573607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); 574607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *LTy = 575607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 576607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FPT->isVariadic()); 577607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy); 578607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 579607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgList CallArgs; 580607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the this (Dest) ptr. 581607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CallArgs.push_back(std::make_pair(RValue::get(Dest), 582607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson MD->getThisType(getContext()))); 583607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 584607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Push the Src ptr. 5858a850baa41ea9015b949183667ad96a981f10b09Eli Friedman QualType SrcTy = MD->getParamDecl(0)->getType(); 5868a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) : 5878a850baa41ea9015b949183667ad96a981f10b09Eli Friedman RValue::getAggregate(Src); 5888a850baa41ea9015b949183667ad96a981f10b09Eli Friedman CallArgs.push_back(std::make_pair(SrcValue, SrcTy)); 58904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT), 590607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Callee, ReturnValueSlot(), CallArgs, MD); 591607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 592607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 593607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeDefaultConstructor - synthesize a default constructor 594607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid 595607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor, 596607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType Type, 597607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 598607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 599607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); 600607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 601607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 602607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCtorPrologue(Ctor, Type); 603607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 604607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 605607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 606607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a 607607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03 608607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy constructor for class X performs a memberwise 609607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy of its subobjects. The order of copying is the same as the order of 610607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// initialization of bases and members in a user-defined constructor 611607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Each subobject is copied in the manner appropriate to its type: 612607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of class type, the copy constructor for the class is 613607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used; 614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is an array, each element is copied, in the manner 615607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// appropriate to the element type; 616607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of scalar type, the built-in assignment operator is 617607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used. 618607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Virtual base class subobjects shall be copied only once by the 619607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly-defined copy constructor 620607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 621607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid 622607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor, 623607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType Type, 624607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 625607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 626607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = Ctor->getParent(); 627607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 628607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeCXXCopyConstructor - copy constructor has definition already"); 629607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); 630607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 631607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 632607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 633607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FunctionArgList::const_iterator i = Args.begin(); 634607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *ThisArg = i->first; 635607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 636607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *SrcArg = (i+1)->first; 638607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 639607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 640607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 641607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base != ClassDecl->bases_end(); ++Base) { 643607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME. copy constrution of virtual base NYI 644607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base->isVirtual()) 645607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 646607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 647607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 648607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base->getType()); 651607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 652607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 653607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 654607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 655607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = *I; 656607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 657607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType(Field->getType()); 658607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 659607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 660607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 661607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 662607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 663607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 664607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl 665607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(FieldClassType->getDecl()); 666e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, Field, 0); 667e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, Field, 0); 668607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 669607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 670607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 671607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *DestBaseAddrPtr = 672607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 673607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcBaseAddrPtr = 674607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(RHS.getAddress(), BasePtr); 675607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 676607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldClassDecl, FieldType); 677607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 678607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 679607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(), 680607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 0 /*ClassDecl*/, FieldClassDecl, FieldType); 681607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 682607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 683607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 684607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Do a built-in assignment of scalar data members. 6859cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson LValue LHS = EmitLValueForFieldInitialization(LoadOfThis, Field, 0); 6869cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson LValue RHS = EmitLValueForFieldInitialization(LoadOfSrc, Field, 0); 687607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 688607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!hasAggregateLLVMType(Field->getType())) { 689607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType()); 690607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitStoreThroughLValue(RVRHS, LHS, Field->getType()); 691607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (Field->getType()->isAnyComplexType()) { 692607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(), 693607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS.isVolatileQualified()); 694607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified()); 695607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 696607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType()); 697607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 698607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 699607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 700607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson InitializeVtablePtrs(ClassDecl); 701607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 702607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 703607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 704607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator. 705607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Before the implicitly-declared copy assignment operator for a class is 706607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined, all implicitly- declared copy assignment operators for 707607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// its direct base classes and its nonstatic data members shall have been 708607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined. [12.8-p12] 709607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy assignment operator for class X performs 710607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// memberwise assignment of its subob- jects. The direct base classes of X are 711607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assigned first, in the order of their declaration in 712607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// the base-specifier-list, and then the immediate nonstatic data members of X 713607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// are assigned, in the order in which they were declared in the class 714607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// definition.Each subobject is assigned in the manner appropriate to its type: 715607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of class type, the copy assignment operator for the 716607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// class is used (as if by explicit qualification; that is, ignoring any 717607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// possible virtual overriding functions in more derived classes); 718607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// 719607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is an array, each element is assigned, in the manner 720607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// appropriate to the element type; 721607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// 722607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// if the subobject is of scalar type, the built-in assignment operator is 723607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// used. 724607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD, 725607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 726607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 727607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 728607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 729607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!ClassDecl->hasUserDeclaredCopyAssignment() && 730607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeCXXCopyAssignment - copy assignment has user declaration"); 731607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation()); 732607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 733607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FunctionArgList::const_iterator i = Args.begin(); 734607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *ThisArg = i->first; 735607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 736607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 737607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const VarDecl *SrcArg = (i+1)->first; 738607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 739607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 740607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 741607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 742607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base != ClassDecl->bases_end(); ++Base) { 743607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME. copy assignment of virtual base NYI 744607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base->isVirtual()) 745607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 746607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 747607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 748607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 749607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 750607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Base->getType()); 751607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 752607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 753607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 754607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldEnd = ClassDecl->field_end(); 755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Field != FieldEnd; ++Field) { 756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 757607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 758607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 759607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 760607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 761607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 763607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl 764607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(FieldClassType->getDecl()); 765e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0); 766e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0); 767607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 768607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 769607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 770607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *DestBaseAddrPtr = 771607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 772607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *SrcBaseAddrPtr = 773607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(RHS.getAddress(), BasePtr); 774607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 775607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldClassDecl, FieldType); 776607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 777607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 778607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(), 779607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 0 /*ClassDecl*/, FieldClassDecl, FieldType); 780607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 781607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 782607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Do a built-in assignment of scalar data members. 783e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0); 784e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0); 785607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!hasAggregateLLVMType(Field->getType())) { 786607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType()); 787607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitStoreThroughLValue(RVRHS, LHS, Field->getType()); 788607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else if (Field->getType()->isAnyComplexType()) { 789607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(), 790607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RHS.isVolatileQualified()); 791607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified()); 792607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 793607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType()); 794607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 795607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 796607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 797607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // return *this; 798607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateStore(LoadOfThis, ReturnValue); 799607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 800607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 801607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 802607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 803607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF, 804607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 805607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *BaseInit, 806607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 807607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(BaseInit->isBaseInitializer() && 808607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have base initializer!"); 809607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 810607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 811607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 812607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const Type *BaseType = BaseInit->getBaseClass(); 813607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl = 814607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 816607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: This method of determining whether a base is virtual is ridiculous; 817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // it should be part of BaseInit. 818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson bool isBaseVirtual = false; 819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), 820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->vbases_end(); I != E; ++I) 821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (I->getType()->getAs<RecordType>()->getDecl() == BaseClassDecl) { 822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson isBaseVirtual = true; 823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson break; 824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // The base constructor doesn't construct virtual bases. 827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (CtorType == Ctor_Base && isBaseVirtual) 828607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 829607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 830bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // We can pretend to be a complete class because it only matters for 831bff225ecf77fb891596ecb1b27196310d268365eJohn McCall // virtual bases, and we only do virtual bases for complete ctors. 832bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = ThisPtr; 833bff225ecf77fb891596ecb1b27196310d268365eJohn McCall V = CGF.GetAddressOfBaseOfCompleteClass(V, isBaseVirtual, 834bff225ecf77fb891596ecb1b27196310d268365eJohn McCall ClassDecl, BaseClassDecl); 835bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 8369db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true); 837594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 838594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) { 839594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson // FIXME: Is this OK for C++0x delegating constructors? 840594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson CodeGenFunction::EHCleanupBlock Cleanup(CGF); 841594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson 842594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson CXXDestructorDecl *DD = BaseClassDecl->getDestructor(CGF.getContext()); 843594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson CGF.EmitCXXDestructorCall(DD, Dtor_Base, V); 844594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson } 845607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 847607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF, 848607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl, 849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *MemberInit) { 850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(MemberInit->isMemberInitializer() && 851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Must have member initializer!"); 852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // non-static data member initializers. 854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecl *Field = MemberInit->getMember(); 855607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = CGF.getContext().getCanonicalType(Field->getType()); 856607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 85806a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0); 85906a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson 860607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we are initializing an anonymous union field, drill down to the field. 861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (MemberInit->getAnonUnionMember()) { 862607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Field = MemberInit->getAnonUnionMember(); 863e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0); 864607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = Field->getType(); 865607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 8679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer 8689db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor // was implicitly generated, we shouldn't be zeroing memory. 869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson RValue RHS; 870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldType->isReferenceType()) { 871a64a869312066ff6119d1d7ae03f88ce499e3f82Anders Carlsson RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(), 8729db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor /*IsInitializer=*/true); 873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 8743bb9412788e04755cb509ec576f41afbed4efdd3Eli Friedman } else if (FieldType->isArrayType() && !MemberInit->getInit()) { 875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType()); 8769db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (!CGF.hasAggregateLLVMType(Field->getType())) { 8779db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true)); 878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); 8799db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor } else if (MemberInit->getInit()->getType()->isAnyComplexType()) { 8809db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(), 881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LHS.isVolatileQualified()); 882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else { 8839db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), 8849db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor LHS.isVolatileQualified(), false, true); 8859405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 8869405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson if (!CGF.Exceptions) 8879405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 8889405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 8899405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 8909405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson if (!RT) 8919405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson return; 8929405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 8939405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 8949405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson if (!RD->hasTrivialDestructor()) { 8959405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson // FIXME: Is this OK for C++0x delegating constructors? 8969405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CodeGenFunction::EHCleanupBlock Cleanup(CGF); 8979405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 8989405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson llvm::Value *ThisPtr = CGF.LoadCXXThis(); 8999405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0); 9009405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson 9019405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CXXDestructorDecl *DD = RD->getDestructor(CGF.getContext()); 9029405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson CGF.EmitCXXDestructorCall(DD, Dtor_Complete, LHS.getAddress()); 9039405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson } 904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize 908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor. 909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXCtorType CtorType) { 911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = CD->getParent(); 912a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 913a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> MemberInitializers; 914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Add vbase initialization 916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = CD->init_end(); 919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson B != E; ++B) { 920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXBaseOrMemberInitializer *Member = (*B); 921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(LiveTemporaries.empty() && 923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not have any live temporaries at initializer start!"); 924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Member->isBaseInitializer()) 926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitBaseInitializer(*this, ClassDecl, Member, CtorType); 927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson else 928a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson MemberInitializers.push_back(Member); 929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson InitializeVtablePtrs(ClassDecl); 932a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 933a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) { 934a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson assert(LiveTemporaries.empty() && 935a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson "Should not have any live temporaries at initializer start!"); 936a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson 937a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I]); 938a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson } 939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's 942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes 943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction. 944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType. 945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD, 946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType) { 947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!DD->isTrivial() && 948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Should not emit dtor epilogue for trivial dtor!"); 949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXRecordDecl *ClassDecl = DD->getParent(); 951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Collect the fields. 953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::SmallVector<const FieldDecl *, 16> FieldDecls; 954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), 955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson E = ClassDecl->field_end(); I != E; ++I) { 956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = *I; 957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = getContext().getCanonicalType(Field->getType()); 959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (!RT) 963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (FieldClassDecl->hasTrivialDestructor()) 967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldDecls.push_back(Field); 970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Now destroy the fields. 973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (size_t i = FieldDecls.size(); i > 0; --i) { 974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FieldDecl *Field = FieldDecls[i - 1]; 975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson QualType FieldType = Field->getType(); 977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const ConstantArrayType *Array = 978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getAsConstantArrayType(FieldType); 979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) 980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FieldType = getContext().getBaseElementType(FieldType); 981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const RecordType *RT = FieldType->getAs<RecordType>(); 983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson LValue LHS = EmitLValueForField(ThisPtr, Field, 988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: Qualifiers? 989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*CVRQualifiers=*/0); 990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Array) { 991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const llvm::Type *BasePtr = ConvertType(FieldType); 992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *BaseAddrPtr = 994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Builder.CreateBitCast(LHS.getAddress(), BasePtr); 995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Array, BaseAddrPtr); 997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } else 998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Dtor_Complete, LHS.getAddress()); 1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Destroy non-virtual bases. 1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) { 1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore virtual bases. 1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (Base.isVirtual()) 1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), 1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl, BaseClassDecl, 1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson /*NullCheckValue=*/false); 1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we're emitting a base destructor, we don't want to emit calls to the 1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // virtual bases. 1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Base) 1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Handle virtual bases. 1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson for (CXXRecordDecl::reverse_base_class_const_iterator I = 1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) { 1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXBaseSpecifier &Base = *I; 1034607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXRecordDecl *BaseClassDecl 1035bff225ecf77fb891596ecb1b27196310d268365eJohn McCall = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 1036607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1037607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Ignore trivial destructors. 1038607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (BaseClassDecl->hasTrivialDestructor()) 1039607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson continue; 1040607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); 1041bff225ecf77fb891596ecb1b27196310d268365eJohn McCall llvm::Value *V = GetAddressOfBaseOfCompleteClass(LoadCXXThis(), 1042bff225ecf77fb891596ecb1b27196310d268365eJohn McCall true, 1043bff225ecf77fb891596ecb1b27196310d268365eJohn McCall ClassDecl, 1044bff225ecf77fb891596ecb1b27196310d268365eJohn McCall BaseClassDecl); 1045607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitCXXDestructorCall(D, Dtor_Base, V); 1046607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1047607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1048607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // If we have a deleting destructor, emit a call to the delete operator. 1049607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (DtorType == Dtor_Deleting) { 1050607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(DD->getOperatorDelete() && 1051607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "operator delete missing - EmitDtorEpilogue"); 1052607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(), 1053607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson getContext().getTagDeclType(ClassDecl)); 1054607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 1055607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 1056607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1057607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor, 1058607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson CXXDtorType DtorType, 1059607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson llvm::Function *Fn, 1060607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const FunctionArgList &Args) { 1061607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(!Dtor->getParent()->hasUserDeclaredDestructor() && 1062607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "SynthesizeDefaultDestructor - destructor has user declaration"); 1063607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 1064607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args, 1065607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson SourceLocation()); 10661851a12605bc6f1ea70d11974a315340ebaab6ebAnders Carlsson InitializeVtablePtrs(Dtor->getParent()); 1067607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson EmitDtorEpilogue(Dtor, DtorType); 1068607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson FinishFunction(); 1069607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson} 10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested) 10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the 10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array. 10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the 10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array. 10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller. 10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *ArrayTy, 10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value * NumElements = 10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::ConstantInt::get(SizeTy, 10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getConstantArrayElementCount(ArrayTy)); 10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd); 10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NumElements, 10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ArrayPtr, 10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with 0. 11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index"); 11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy); 11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Zero, IndexPtr); 11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index < number-of-elements fall to the loop body, 11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless"); 11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsLess, ForBody, AfterFor); 11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter, 11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "arrayidx"); 11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // C++ [class.temporary]p4: 11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // There are two contexts in which temporaries are destroyed at a different 11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // point than the end of the full-expression. The first context is when a 11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // default constructor is called to initialize an element of an array. 11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the constructor has one or more default arguments, the destruction of 11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // every temporary created in a default argument expression is sequenced 11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // before the construction of the next array element, if any. 11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Keep track of the current number of live temporaries. 11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson unsigned OldNumLiveTemporaries = LiveTemporaries.size(); 11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd); 11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Pop temporaries. 11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson while (LiveTemporaries.size() > OldNumLiveTemporaries) 11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PopCXXTemporary(); 11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the increment of the loop counter. 11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1); 11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(NextVal, IndexPtr); 11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(CA && "Do we support VLA for destruction ?"); 11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); 11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount); 11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, ElementCountPtr, This); 11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array 11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction. 11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *UpperCount, 11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType()); 11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1); 11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Create a temporary for the loop index and initialize it with count of 11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // array elements. 11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index"); 11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store the number of elements in the index pointer. 11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(UpperCount, IndexPtr); 11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Start the loop with a block that tests the condition. 11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(CondBlock); 11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Generate: if (loop-index != 0 fall to the loop body, 12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // otherwise, go to the block after the for-loop. 12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value* zeroConstant = 12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant::getNullValue(SizeLTy); 12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, 12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "isne"); 12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // If the condition is true, execute the body. 12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateCondBr(IsNE, ForBody, AfterFor); 12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ForBody); 12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Inside the loop body, emit the constructor call on the array element. 12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One); 12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); 12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXDestructorCall(D, Dtor_Complete, Address); 12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(ContinueBlock); 12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the decrement of the loop counter. 12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateLoad(IndexPtr); 12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Counter = Builder.CreateSub(Counter, One, "dec"); 12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(Counter, IndexPtr); 12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Finally, branch back up to the condition for the next iteration. 12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBranch(CondBlock); 12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Emit the fall-through block. 12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitBlock(AfterFor, true); 12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction. 12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant * 12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ArrayType *Array, 12383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionArgList Args; 12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl *Dst = 12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ImplicitParamDecl::Create(getContext(), 0, 12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), 0, 12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getPointerType(getContext().VoidTy)); 12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::SmallString<16> Name; 12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount); 12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType R = getContext().VoidTy; 124904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall const CGFunctionInfo &FI 125004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall = CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); 12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function *Fn = 12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Name.str(), 12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson &CGM.getModule()); 12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str()); 12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl *FD = FunctionDecl::Create(getContext(), 12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson getContext().getTranslationUnitDecl(), 12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson SourceLocation(), II, R, 0, 12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FunctionDecl::Static, 12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson false, true); 12623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson StartFunction(FD, R, Fn, Args, SourceLocation()); 12633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy); 12653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson BasePtr = llvm::PointerType::getUnqual(BasePtr); 12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson FinishFunction(); 12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 0); 12713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return m; 12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 12743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1275c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid 12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 12783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXCtorType Type, 12793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This, 12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgBeg, 12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CallExpr::const_arg_iterator ArgEnd) { 12828b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (D->isTrivial()) { 12838b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall if (ArgBeg == ArgEnd) { 12848b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall // Trivial default constructor, no codegen required. 12858b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isDefaultConstructor() && 12868b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall "trivial 0-arg ctor not a default ctor"); 12873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12898b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12908b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor"); 12918b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall assert(D->isCopyConstructor() && "trivial 1-arg ctor not a copy ctor"); 12928b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall 12938b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall const Expr *E = (*ArgBeg); 12948b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall QualType Ty = E->getType(); 12958b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall llvm::Value *Src = EmitLValue(E).getAddress(); 12968b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall EmitAggregateCopy(This, Src, Ty); 12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 12993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1300c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type)); 13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1303c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd); 13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXDtorType Type, 13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *This) { 1309c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type)); 13103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); 13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 1312c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0); 13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value * 1316bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, 1317bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson const CXXRecordDecl *ClassDecl, 13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *BaseClassDecl) { 13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = 13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VTablePtr = Builder.CreateBitCast(This, 13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Int8PtrTy->getPointerTo()); 13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VTablePtr = Builder.CreateLoad(VTablePtr, "vtable"); 13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson int64_t VBaseOffsetIndex = 13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl); 13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffsetPtr = 13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr"); 13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *PtrDiffTy = 13323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ConvertType(getContext().getPointerDiffType()); 13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr, 13353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson PtrDiffTy->getPointerTo()); 13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); 13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return VBaseOffset; 13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { 13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl); 134721431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints = 134821431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl]; 13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr = LoadCXXThis(); 13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for virtual bases 13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) { 13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl); 13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, Offset); 13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases and current class 13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0); 13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive( 13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXRecordDecl *ClassDecl, 13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Constant *Vtable, 137021431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson CGVtableInfo::AddrSubMap_t& AddressPoints, 13713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *ThisPtr, 13723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t Offset) { 13733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (!ClassDecl->isDynamicClass()) 13743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson return; 13753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address points for non-virtual bases 13773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); 13783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = 13793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) { 13803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const CXXBaseSpecifier &Base = *I; 13813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson if (Base.isVirtual()) 13823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson continue; 13833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson CXXRecordDecl *BaseClassDecl 13843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl()); 13853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl); 13863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints, 13873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson ThisPtr, NewOffset); 13883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson } 13893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address point 13913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && 13923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson "Missing address point for class"); 13933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; 13943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableAddressPoint = 13953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); 13963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 13973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Compute the address to store the address point 13983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 13993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy); 14003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8); 14013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson const llvm::Type *AddressPointPtrTy = 14023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableAddressPoint->getType()->getPointerTo(); 14033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy); 14043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson 14053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson // Store address point 14063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson Builder.CreateStore(VtableAddressPoint, VtableField); 14073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson} 1408c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1409c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() { 1410c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson assert((isa<CXXConstructorDecl>(CurFuncDecl) || 1411c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson isa<CXXDestructorDecl>(CurFuncDecl)) && 1412c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson "Must be in a C++ ctor or dtor to load the vtt parameter"); 1413c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 1414c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); 1415c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson} 1416