CGClass.cpp revision 9fcfc421d3bf124beed5b185b8d6d795edcbf83a
15b955920c1d8f2cd35aae3c85b656578286a8bc1Anders Carlsson//===--- CGClass.cpp - Emit LLVM Code for C++ classes ---------------------===//
25d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
35d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//                     The LLVM Compiler Infrastructure
45d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
55d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is distributed under the University of Illinois Open Source
65d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// License. See LICENSE.TXT for details.
75d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
85d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===//
95d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
105d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This contains code dealing with C++ code generation of classes
115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
125d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===//
135d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
145d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "CodeGenFunction.h"
152f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "clang/AST/CXXInheritance.h"
165d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "clang/AST/RecordLayout.h"
172f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
185d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace clang;
195d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace CodeGen;
205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
212f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic uint64_t
222f1986b557fa671c4f8c9dd0d071398edfc073d5Anders CarlssonComputeNonVirtualBaseClassOffset(ASTContext &Context, CXXBasePaths &Paths,
232f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                                 unsigned Start) {
242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  uint64_t Offset = 0;
255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
262f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  const CXXBasePath &Path = Paths.front();
272f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  for (unsigned i = Start, e = Path.size(); i != e; ++i) {
282f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    const CXXBasePathElement& Element = Path[i];
295d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
302f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    // Get the layout.
312f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class);
325d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
332f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    const CXXBaseSpecifier *BS = Element.Base;
342f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    assert(!BS->isVirtual() && "Should not see virtual bases here!");
355d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
362f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    const CXXRecordDecl *Base =
372f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson      cast<CXXRecordDecl>(BS->getType()->getAs<RecordType>()->getDecl());
382f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
392f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    // Add the offset.
402f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    Offset += Layout.getBaseClassOffset(Base) / 8;
412f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  }
422f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
432f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  return Offset;
445d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson}
455d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
4684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlssonllvm::Constant *
472b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders CarlssonCodeGenModule::GetCXXBaseClassOffset(const CXXRecordDecl *ClassDecl,
482b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson                                     const CXXRecordDecl *BaseClassDecl) {
4984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson  if (ClassDecl == BaseClassDecl)
5084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson    return 0;
5184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
522f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
532f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
542f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  if (!const_cast<CXXRecordDecl *>(ClassDecl)->
552f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
562f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    assert(false && "Class must be derived from the passed in base class!");
572f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    return 0;
582f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  }
5984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
602f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(), Paths, 0);
6184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson  if (!Offset)
6284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson    return 0;
6384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
642b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson  const llvm::Type *PtrDiffTy =
652b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson    Types.ConvertType(getContext().getPointerDiffType());
6684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
6784080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson  return llvm::ConstantInt::get(PtrDiffTy, Offset);
6884080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson}
6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
702f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlssonstatic llvm::Value *GetCXXBaseClassOffset(CodeGenFunction &CGF,
712f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                                          llvm::Value *BaseValue,
722f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                                          const CXXRecordDecl *ClassDecl,
732f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                                          const CXXRecordDecl *BaseClassDecl) {
742f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
758432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
762f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  if (!const_cast<CXXRecordDecl *>(ClassDecl)->
772f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
782f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    assert(false && "Class must be derived from the passed in base class!");
792f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    return 0;
802f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  }
812f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
822f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  unsigned Start = 0;
832f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  llvm::Value *VirtualOffset = 0;
848432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman
858432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman  const CXXBasePath &Path = Paths.front();
868432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman  const CXXRecordDecl *VBase = 0;
878432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
888432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman    const CXXBasePathElement& Element = Path[i];
898432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman    if (Element.Base->isVirtual()) {
908432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman      Start = i+1;
918432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman      QualType VBaseType = Element.Base->getType();
928432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
932f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    }
942f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  }
958432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman  if (VBase)
968432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman    VirtualOffset =
978432f25cb242cbc809f9b10672e8e2074d362f80Eli Friedman      CGF.GetVirtualCXXBaseClassOffset(BaseValue, ClassDecl, VBase);
982f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
992f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  uint64_t Offset =
1002f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    ComputeNonVirtualBaseClassOffset(CGF.getContext(), Paths, Start);
1012f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
1022f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  if (!Offset)
1032f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    return VirtualOffset;
1042f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
1052f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  const llvm::Type *PtrDiffTy =
1062f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    CGF.ConvertType(CGF.getContext().getPointerDiffType());
1072f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  llvm::Value *NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset);
1082f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
1092f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  if (VirtualOffset)
1102f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    return CGF.Builder.CreateAdd(VirtualOffset, NonVirtualOffset);
1112f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
1122f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  return NonVirtualOffset;
1132f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson}
1142f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
1159fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on
1169fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that
1179fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well.
1189fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment
1199fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl,
1209fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                                      const CXXRecordDecl *BaseClassDecl) {
1219fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
1229fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
1239fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (!const_cast<CXXRecordDecl *>(ClassDecl)->
1249fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
1259fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    assert(false && "Class must be derived from the passed in base class!");
1269fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    return ThunkAdjustment();
1279fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
1289fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1299fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  unsigned Start = 0;
1309fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t VirtualOffset = 0;
1319fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1329fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXBasePath &Path = Paths.front();
1339fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXRecordDecl *VBase = 0;
1349fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
1359fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    const CXXBasePathElement& Element = Path[i];
1369fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    if (Element.Base->isVirtual()) {
1379fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      Start = i+1;
1389fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      QualType VBaseType = Element.Base->getType();
1399fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
1409fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    }
1419fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
1429fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (VBase)
1439fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    VirtualOffset =
1449fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
1459fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1469fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t Offset =
1479fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start);
1489fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  return ThunkAdjustment(Offset, VirtualOffset);
1499fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson}
1509fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1515d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value *
152a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
153a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                       const CXXRecordDecl *ClassDecl,
154a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                       const CXXRecordDecl *BaseClassDecl,
155a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                       bool NullCheckValue) {
156dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  QualType BTy =
157dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    getContext().getCanonicalType(
158dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
159dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
1605d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
1612f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  if (ClassDecl == BaseClassDecl) {
162dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    // Just cast back.
163a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, BasePtrTy);
164dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  }
1654a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
16632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNull = 0;
16732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNotNull = 0;
16832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastEnd = 0;
16932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
17032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
17132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNull = createBasicBlock("cast.null");
17232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
17332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastEnd = createBasicBlock("cast.end");
17432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
17532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    llvm::Value *IsNull =
176a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      Builder.CreateICmpEQ(Value,
177a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                           llvm::Constant::getNullValue(Value->getType()));
17832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
17932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNotNull);
18032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  }
18132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
1823c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
1834a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
1844a5dc242545222aef6313cc4297708f524e10c6fEli Friedman  llvm::Value *Offset =
185a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    GetCXXBaseClassOffset(*this, Value, ClassDecl, BaseClassDecl);
1865d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
1874a5dc242545222aef6313cc4297708f524e10c6fEli Friedman  if (Offset) {
1884a5dc242545222aef6313cc4297708f524e10c6fEli Friedman    // Apply the offset.
189a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreateBitCast(Value, Int8PtrTy);
190a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreateGEP(Value, Offset, "add.ptr");
1914a5dc242545222aef6313cc4297708f524e10c6fEli Friedman  }
1925d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
1935d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson  // Cast back.
194a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  Value = Builder.CreateBitCast(Value, BasePtrTy);
19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
19832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNull);
19932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
20032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastEnd);
20132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
202a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
203a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->reserveOperandSpace(2);
204a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(Value, CastNotNull);
205a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
206a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                     CastNull);
207a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = PHI;
208a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
209a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
210a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  return Value;
211a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson}
212a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
213a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value *
214a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
215a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                          const CXXRecordDecl *ClassDecl,
216a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                          const CXXRecordDecl *DerivedClassDecl,
217a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                          bool NullCheckValue) {
218a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  QualType DerivedTy =
219a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    getContext().getCanonicalType(
220a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClassDecl)));
221a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (ClassDecl == DerivedClassDecl) {
224a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    // Just cast back.
225a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, DerivedPtrTy);
226a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
228a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNull = 0;
229a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNotNull = 0;
230a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastEnd = 0;
231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (NullCheckValue) {
233a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNull = createBasicBlock("cast.null");
234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastEnd = createBasicBlock("cast.end");
236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::Value *IsNull =
238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateICmpEQ(Value,
239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                         llvm::Constant::getNullValue(Value->getType()));
240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastNotNull);
242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::Value *Offset = GetCXXBaseClassOffset(*this, Value, DerivedClassDecl,
245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                              ClassDecl);
246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (Offset) {
247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    // Apply the offset.
248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreatePtrToInt(Value, Offset->getType());
249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreateSub(Value, Offset);
250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  } else {
252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    // Just cast.
253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = Builder.CreateBitCast(Value, DerivedPtrTy);
254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (NullCheckValue) {
257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateBr(CastEnd);
258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastNull);
259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateBr(CastEnd);
260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastEnd);
261a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
262a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
26332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    PHI->reserveOperandSpace(2);
264a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(Value, CastNotNull);
265a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
26632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson                     CastNull);
267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = PHI;
26832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  }
2695d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  return Value;
2715d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson}
272