CGClass.cpp revision 8432f25cb242cbc809f9b10672e8e2074d362f80
15b955920c1d8f2cd35aae3c85b656578286a8bc1Anders Carlsson//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===// 25d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 35d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// The LLVM Compiler Infrastructure 45d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 55d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is distributed under the University of Illinois Open Source 65d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// License. See LICENSE.TXT for details. 75d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 85d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===// 95d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 105d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This contains code dealing with C++ code generation of classes 115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 125d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===// 135d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 145d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h" 152f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h" 165d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h" 172f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang; 195d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen; 205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 212f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic uint64_t 222f1986b557fa671c4f8c9dd0d071398edfc073d5Anders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths, 232f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson unsigned Start) { 242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = 0; 255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 262f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBasePath &Path = Paths.front(); 272f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson for (unsigned i = Start, e = Path.size(); i != e; ++i) { 282f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBasePathElement& Element = Path[i]; 295d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 302f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson // Get the layout. 312f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); 325d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 332f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXBaseSpecifier *BS = Element.Base; 34a660440263ceb3a2502f5dbd48b4e166544ed9feMike Stump // FIXME: enable test3 from virt.cc to not abort. 35a660440263ceb3a2502f5dbd48b4e166544ed9feMike Stump if (BS->isVirtual()) 36a660440263ceb3a2502f5dbd48b4e166544ed9feMike Stump return 0; 372f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(!BS->isVirtual() && "Should not see virtual bases here!"); 385d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 392f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *Base = 402f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl()); 412f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 422f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson // Add the offset. 432f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson Offset += Layout.getBaseClassOffset(Base) / 8; 442f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 452f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 462f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return Offset; 475d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 485d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 4984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant * 502b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders CarlssonCodeGenModule::GetCXXBaseClassOffset(const CXXRecordDecl *ClassDecl, 512b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson const CXXRecordDecl *BaseClassDecl) { 5284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson if (ClassDecl == BaseClassDecl) 5384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 5484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 552f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 562f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson /*RecordPaths=*/true, /*DetectVirtual=*/false); 572f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 582f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 592f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 602f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return 0; 612f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 6284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 632f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), Paths, 0); 6484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson if (!Offset) 6584080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return 0; 6684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 672b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson const llvm::Type *PtrDiffTy = 682b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson Types.ConvertType(getContext().getPointerDiffType()); 6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 7084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson return llvm::ConstantInt::get(PtrDiffTy, Offset); 7184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson} 7284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 732f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic llvm::Value *GetCXXBaseClassOffset(CodeGenFunction &CGF, 742f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *BaseValue, 752f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *ClassDecl, 762f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const CXXRecordDecl *BaseClassDecl) { 772f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CXXBasePaths Paths(/*FindAmbiguities=*/false, 788432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman /*RecordPaths=*/true, /*DetectVirtual=*/false); 792f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!const_cast<CXXRecordDecl *>(ClassDecl)-> 802f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) { 812f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson assert(false && "Class must be derived from the passed in base class!"); 822f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return 0; 832f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 842f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 852f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson unsigned Start = 0; 862f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *VirtualOffset = 0; 878432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman 888432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXBasePath &Path = Paths.front(); 898432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXRecordDecl *VBase = 0; 908432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman for (unsigned i = 0, e = Path.size(); i != e; ++i) { 918432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman const CXXBasePathElement& Element = Path[i]; 928432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman if (Element.Base->isVirtual()) { 938432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman Start = i+1; 948432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman QualType VBaseType = Element.Base->getType(); 958432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); 962f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 972f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson } 988432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman if (VBase) 998432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman VirtualOffset = 1008432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman CGF.GetVirtualCXXBaseClassOffset(BaseValue, ClassDecl, VBase); 1012f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1022f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson uint64_t Offset = 1032f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson ComputeNonVirtualBaseClassOffset(CGF.getContext(), Paths, Start); 1042f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1052f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (!Offset) 1062f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return VirtualOffset; 1072f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1082f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson const llvm::Type *PtrDiffTy = 1092f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson CGF.ConvertType(CGF.getContext().getPointerDiffType()); 1102f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson llvm::Value *NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset); 1112f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1122f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (VirtualOffset) 1132f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return CGF.Builder.CreateAdd(VirtualOffset, NonVirtualOffset); 1142f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1152f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson return NonVirtualOffset; 1162f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson} 1172f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 1185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value * 119a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 120a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *ClassDecl, 121a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *BaseClassDecl, 122a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 123dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson QualType BTy = 124dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getCanonicalType( 125dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 126dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy)); 1275d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1282f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson if (ClassDecl == BaseClassDecl) { 129dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson // Just cast back. 130a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, BasePtrTy); 131dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson } 1324a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 13332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNull = 0; 13432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastNotNull = 0; 13532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::BasicBlock *CastEnd = 0; 13632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 13732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 13832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull = createBasicBlock("cast.null"); 13932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 14032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastEnd = createBasicBlock("cast.end"); 14132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 14232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson llvm::Value *IsNull = 143a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 144a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 14532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 14632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNotNull); 14732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 14832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 1493c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 1504a5dc242545222aef6313cc4297708f524e10c6fEli Friedman 1514a5dc242545222aef6313cc4297708f524e10c6fEli Friedman llvm::Value *Offset = 152a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson GetCXXBaseClassOffset(*this, Value, ClassDecl, BaseClassDecl); 1535d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1544a5dc242545222aef6313cc4297708f524e10c6fEli Friedman if (Offset) { 1554a5dc242545222aef6313cc4297708f524e10c6fEli Friedman // Apply the offset. 156a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, Int8PtrTy); 157a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateGEP(Value, Offset, "add.ptr"); 1584a5dc242545222aef6313cc4297708f524e10c6fEli Friedman } 1595d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 1605d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson // Cast back. 161a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, BasePtrTy); 16232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 16332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson if (NullCheckValue) { 16432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 16532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastNull); 16632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson Builder.CreateBr(CastEnd); 16732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson EmitBlock(CastEnd); 16832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 169a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 170a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->reserveOperandSpace(2); 171a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 172a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 173a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull); 174a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 175a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 176a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 177a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 178a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson} 179a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 180a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value * 181a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, 182a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *ClassDecl, 183a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CXXRecordDecl *DerivedClassDecl, 184a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson bool NullCheckValue) { 185a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson QualType DerivedTy = 186a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getCanonicalType( 187a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClassDecl))); 188a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); 189a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 190a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (ClassDecl == DerivedClassDecl) { 191a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast back. 192a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Builder.CreateBitCast(Value, DerivedPtrTy); 193a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 194a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 195a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNull = 0; 196a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastNotNull = 0; 197a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::BasicBlock *CastEnd = 0; 198a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 199a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 200a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNull = createBasicBlock("cast.null"); 201a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastNotNull = createBasicBlock("cast.notnull"); 202a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson CastEnd = createBasicBlock("cast.end"); 203a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 204a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *IsNull = 205a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateICmpEQ(Value, 206a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Constant::getNullValue(Value->getType())); 207a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 208a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNotNull); 209a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 210a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 211a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::Value *Offset = GetCXXBaseClassOffset(*this, Value, DerivedClassDecl, 212a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson ClassDecl); 213a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (Offset) { 214a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Apply the offset. 215a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreatePtrToInt(Value, Offset->getType()); 216a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateSub(Value, Offset); 217a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateIntToPtr(Value, DerivedPtrTy); 218a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } else { 219a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Just cast. 220a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = Builder.CreateBitCast(Value, DerivedPtrTy); 221a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (NullCheckValue) { 224a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 225a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastNull); 226a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Builder.CreateBr(CastEnd); 227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson EmitBlock(CastEnd); 228a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 229a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(Value->getType()); 23032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson PHI->reserveOperandSpace(2); 231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(Value, CastNotNull); 232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 23332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson CastNull); 234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson Value = PHI; 23532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson } 2365d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson return Value; 2385d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson} 239