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