CGClass.cpp revision 9cfe0ec4decfd19a0387bb737f28eb0ea2c3a476
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}
272607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
273607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
274607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
275607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy or via a copy constructor call.
276607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson//  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
277607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
278607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            llvm::Value *Src,
279607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const ArrayType *Array,
280607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const CXXRecordDecl *BaseClassDecl,
281607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            QualType Ty) {
282607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
283607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(CA && "VLA cannot be copied over");
284607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
285607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
286607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Create a temporary for the loop index and initialize it with 0.
287607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
288607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           "loop.index");
289607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value* zeroConstant =
290607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
291607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(zeroConstant, IndexPtr);
292607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Start the loop with a block that tests the condition.
293607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
294607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
295607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
296607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(CondBlock);
297607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
298607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
299607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
300607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // otherwise, go to the block after the for-loop.
301607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
302607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value * NumElementsPtr =
303607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
304607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
305607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
306607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              "isless");
307607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the condition is true, execute the body.
308607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
309607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
310607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ForBody);
311607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
312607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Inside the loop body, emit the constructor call on the array element.
313607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
314607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
315607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
316607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BitwiseCopy)
317607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
318607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  else if (CXXConstructorDecl *BaseCopyCtor =
319607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           BaseClassDecl->getCopyConstructor(getContext(), 0)) {
320607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
321607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                      Ctor_Complete);
322607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
323607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
324607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
325607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      BaseCopyCtor->getThisType(getContext())));
326607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
327607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
328607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Src),
329607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                     BaseCopyCtor->getParamDecl(0)->getType()));
330607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType ResultType =
331607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType();
332607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
333607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
334607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
335607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ContinueBlock);
336607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
337607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the increment of the loop counter.
338607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
339607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
340607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
341607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
342607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
343607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Finally, branch back up to the condition for the next iteration.
344607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBranch(CondBlock);
345607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
346607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the fall-through block.
347607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(AfterFor, true);
348607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
349607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
350607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
351607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Assignment can be either a
352607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// bitwise assignment or via a copy assignment operator function call.
353607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
354607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
355607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            llvm::Value *Src,
356607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const ArrayType *Array,
357607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const CXXRecordDecl *BaseClassDecl,
358607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            QualType Ty) {
359607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
360607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(CA && "VLA cannot be asssigned");
361607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
362607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
363607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Create a temporary for the loop index and initialize it with 0.
364607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
365607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           "loop.index");
366607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value* zeroConstant =
367607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
368607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(zeroConstant, IndexPtr);
369607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Start the loop with a block that tests the condition.
370607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
371607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(CondBlock);
374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // otherwise, go to the block after the for-loop.
378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value * NumElementsPtr =
380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              "isless");
384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the condition is true, execute the body.
385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ForBody);
388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Inside the loop body, emit the assignment operator call on array element.
390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXMethodDecl *MD = 0;
394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BitwiseAssign)
395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  else {
3978a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
3988a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    assert(MD && "EmitClassAggrCopyAssignment - No user assign");
399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const llvm::Type *LTy =
401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
402607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                   FPT->isVariadic());
403607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
404607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
405607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
406607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
407607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
408607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      MD->getThisType(getContext())));
409607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
410607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
4118a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    QualType SrcTy = MD->getParamDecl(0)->getType();
4128a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
4138a850baa41ea9015b949183667ad96a981f10b09Eli Friedman                                                 RValue::getAggregate(Src);
4148a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
415607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType();
416607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
417607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, MD);
418607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
419607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ContinueBlock);
420607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
421607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the increment of the loop counter.
422607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
423607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Finally, branch back up to the condition for the next iteration.
428607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBranch(CondBlock);
429607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
430607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the fall-through block.
431607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(AfterFor, true);
432607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
433607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
434c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a
435c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases.
436c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) {
437c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (!CGVtableInfo::needsVTTParameter(GD)) {
438c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // This constructor/destructor does not need a VTT parameter.
439c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return 0;
440c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  }
441c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
442c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent();
443c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
444c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
445c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT;
446c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
447c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  uint64_t SubVTTIndex =
448c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base);
449c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
450c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
451c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) {
452c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // A VTT parameter was passed to the constructor, use it.
453c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.LoadCXXVTT();
454c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
455c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  } else {
456c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // We're the complete constructor, so get the VTT by name.
457c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.CGM.getVtableInfo().getVTT(RD);
458c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
459c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  }
460c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
461c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  return VTT;
462c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson}
463c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
464c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
465607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassMemberwiseCopy - This routine generates code to copy a class
466607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Copying can be either a bitwise copy
467607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// or via a copy constructor call.
468607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassMemberwiseCopy(
469607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        llvm::Value *Dest, llvm::Value *Src,
470607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        const CXXRecordDecl *ClassDecl,
471607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
472c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  CXXCtorType CtorType = Ctor_Complete;
473c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
474607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (ClassDecl) {
475607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
476607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 /*NullCheckValue=*/false);
477607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
478607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                /*NullCheckValue=*/false);
479c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
480c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // We want to call the base constructor.
481c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    CtorType = Ctor_Base;
482607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
483607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BaseClassDecl->hasTrivialCopyConstructor()) {
484607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
485607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
486607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
487607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
488607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (CXXConstructorDecl *BaseCopyCtor =
489607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
490c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType);
491607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
492607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
493607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
494607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      BaseCopyCtor->getThisType(getContext())));
495607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
496c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // Push the VTT parameter, if necessary.
497c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    if (llvm::Value *VTT =
498c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson          GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) {
499c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      QualType T = getContext().getPointerType(getContext().VoidPtrTy);
500c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      CallArgs.push_back(std::make_pair(RValue::get(VTT), T));
501c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    }
502c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
503607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
504607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Src),
505607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                       BaseCopyCtor->getParamDecl(0)->getType()));
506607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType ResultType =
507607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType();
508607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
509607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
510607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
511607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
512607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
513607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassCopyAssignment - This routine generates code to copy assign a class
514607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Assignment can be either a bitwise
515607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assignment of via an assignment operator call.
516607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
517607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassCopyAssignment(
518607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        llvm::Value *Dest, llvm::Value *Src,
519607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        const CXXRecordDecl *ClassDecl,
520607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        const CXXRecordDecl *BaseClassDecl,
521607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        QualType Ty) {
522607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (ClassDecl) {
523607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
524607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 /*NullCheckValue=*/false);
525607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
526607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                /*NullCheckValue=*/false);
527607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
528607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BaseClassDecl->hasTrivialCopyAssignment()) {
529607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
530607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
531607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
532607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
533607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXMethodDecl *MD = 0;
5348a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
5358a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  assert(MD && "EmitClassCopyAssignment - missing copy assign");
536607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const llvm::Type *LTy =
539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                   FPT->isVariadic());
541607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
542607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CallArgList CallArgs;
544607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Push the this (Dest) ptr.
545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CallArgs.push_back(std::make_pair(RValue::get(Dest),
546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    MD->getThisType(getContext())));
547607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Push the Src ptr.
5498a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  QualType SrcTy = MD->getParamDecl(0)->getType();
5508a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
5518a850baa41ea9015b949183667ad96a981f10b09Eli Friedman                                               RValue::getAggregate(Src);
5528a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  QualType ResultType =
554607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    MD->getType()->getAs<FunctionType>()->getResultType();
555607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
556607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           Callee, ReturnValueSlot(), CallArgs, MD);
557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
558607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
559607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeDefaultConstructor - synthesize a default constructor
560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid
561607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor,
562607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              CXXCtorType Type,
563607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              llvm::Function *Fn,
564607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              const FunctionArgList &Args) {
565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args,
567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitCtorPrologue(Ctor, Type);
569607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
570607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
571607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
572607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a
573607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03
574607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy constructor for class X performs a memberwise
575607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy of its subobjects. The order of copying is the same as the order of
576607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// initialization of bases and members in a user-defined constructor
577607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Each subobject is copied in the manner appropriate to its type:
578607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is of class type, the copy constructor for the class is
579607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  used;
580607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is an array, each element is copied, in the manner
581607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  appropriate to the element type;
582607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is of scalar type, the built-in assignment operator is
583607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  used.
584607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Virtual base class subobjects shall be copied only once by the
585607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly-defined copy constructor
586607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
587607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid
588607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
589607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              CXXCtorType Type,
590607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              llvm::Function *Fn,
591607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              const FunctionArgList &Args) {
592607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = Ctor->getParent();
593607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
594607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      "SynthesizeCXXCopyConstructor - copy constructor has definition already");
595607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
596607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args,
597607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
598607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
599607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FunctionArgList::const_iterator i = Args.begin();
600607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *ThisArg = i->first;
601607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
602607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
603607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *SrcArg = (i+1)->first;
604607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
605607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
606607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
607607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
608607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Base != ClassDecl->bases_end(); ++Base) {
609607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // FIXME. copy constrution of virtual base NYI
610607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base->isVirtual())
611607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
612607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
613607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
615607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
616607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Base->getType());
617607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
618607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
619607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
620607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->field_end(); I != E; ++I) {
621607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = *I;
622607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
623607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType(Field->getType());
624607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
625607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
626607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
627607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
628607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
629607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
630607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CXXRecordDecl *FieldClassDecl
631607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        = cast<CXXRecordDecl>(FieldClassType->getDecl());
632e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue LHS = EmitLValueForField(LoadOfThis, Field, 0);
633e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue RHS = EmitLValueForField(LoadOfSrc, Field, 0);
634607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      if (Array) {
635607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        const llvm::Type *BasePtr = ConvertType(FieldType);
636607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        BasePtr = llvm::PointerType::getUnqual(BasePtr);
637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *DestBaseAddrPtr =
638607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
639607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *SrcBaseAddrPtr =
640607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
641607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    FieldClassDecl, FieldType);
643607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      }
644607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      else
645607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
646607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
647607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
648607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Do a built-in assignment of scalar data members.
6519cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson    LValue LHS = EmitLValueForFieldInitialization(LoadOfThis, Field, 0);
6529cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson    LValue RHS = EmitLValueForFieldInitialization(LoadOfSrc, Field, 0);
653607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
654607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!hasAggregateLLVMType(Field->getType())) {
655607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
656607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
657607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else if (Field->getType()->isAnyComplexType()) {
658607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
659607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                               RHS.isVolatileQualified());
660607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
661607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else {
662607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
663607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
664607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
665607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
666607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  InitializeVtablePtrs(ClassDecl);
667607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
668607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
669607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
670607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
671607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Before the implicitly-declared copy assignment operator for a class is
672607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined, all implicitly- declared copy assignment operators for
673607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// its direct base classes and its nonstatic data members shall have been
674607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined. [12.8-p12]
675607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy assignment operator for class X performs
676607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// memberwise assignment of its subob- jects. The direct base classes of X are
677607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assigned first, in the order of their declaration in
678607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// the base-specifier-list, and then the immediate nonstatic data members of X
679607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// are assigned, in the order in which they were declared in the class
680607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// definition.Each subobject is assigned in the manner appropriate to its type:
681607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is of class type, the copy assignment operator for the
682607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   class is used (as if by explicit qualification; that is, ignoring any
683607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   possible virtual overriding functions in more derived classes);
684607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///
685607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is an array, each element is assigned, in the manner
686607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   appropriate to the element type;
687607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///
688607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is of scalar type, the built-in assignment operator is
689607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   used.
690607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
691607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  llvm::Function *Fn,
692607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  const FunctionArgList &Args) {
693607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
694607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
695607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
696607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
697607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation());
698607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
699607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FunctionArgList::const_iterator i = Args.begin();
700607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *ThisArg = i->first;
701607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
702607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
703607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *SrcArg = (i+1)->first;
704607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
705607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
706607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
707607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
708607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Base != ClassDecl->bases_end(); ++Base) {
709607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // FIXME. copy assignment of virtual base NYI
710607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base->isVirtual())
711607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
712607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
713607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
714607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
715607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
716607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Base->getType());
717607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
718607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
719607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
720607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       FieldEnd = ClassDecl->field_end();
721607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Field != FieldEnd; ++Field) {
722607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
723607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
724607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
725607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
726607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
727607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
728607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
729607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CXXRecordDecl *FieldClassDecl
730607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(FieldClassType->getDecl());
731e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
732e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
733607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      if (Array) {
734607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        const llvm::Type *BasePtr = ConvertType(FieldType);
735607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        BasePtr = llvm::PointerType::getUnqual(BasePtr);
736607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *DestBaseAddrPtr =
737607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
738607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *SrcBaseAddrPtr =
739607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
740607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
741607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    FieldClassDecl, FieldType);
742607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      }
743607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      else
744607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
745607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
746607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
747607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
748607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Do a built-in assignment of scalar data members.
749e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
750e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
751607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!hasAggregateLLVMType(Field->getType())) {
752607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
753607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
754607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else if (Field->getType()->isAnyComplexType()) {
755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                               RHS.isVolatileQualified());
757607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
758607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else {
759607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
760607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
761607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
763607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // return *this;
764607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(LoadOfThis, ReturnValue);
765607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
766607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
767607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
768607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
769607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF,
770607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                const CXXRecordDecl *ClassDecl,
771607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                CXXBaseOrMemberInitializer *BaseInit,
772607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                CXXCtorType CtorType) {
773607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(BaseInit->isBaseInitializer() &&
774607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Must have base initializer!");
775607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
776607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisPtr = CGF.LoadCXXThis();
777607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
778607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const Type *BaseType = BaseInit->getBaseClass();
779607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CXXRecordDecl *BaseClassDecl =
780607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
781607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
782607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: This method of determining whether a base is virtual is ridiculous;
783607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // it should be part of BaseInit.
784607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool isBaseVirtual = false;
785607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(),
786607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->vbases_end(); I != E; ++I)
787607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (I->getType()->getAs<RecordType>()->getDecl() == BaseClassDecl) {
788607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      isBaseVirtual = true;
789607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      break;
790607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
791607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
792607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // The base constructor doesn't construct virtual bases.
793607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (CtorType == Ctor_Base && isBaseVirtual)
794607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
795607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
796607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Compute the offset to the base; we do this directly instead of using
797607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // GetAddressOfBaseClass because the class doesn't have a vtable pointer
798607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // at this point.
799607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: This could be refactored back into GetAddressOfBaseClass if it took
800607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // an extra parameter for whether the derived class is the complete object
801607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // class.
802607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ASTRecordLayout &Layout =
803607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.getContext().getASTRecordLayout(ClassDecl);
804607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  uint64_t Offset;
805607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (isBaseVirtual)
806607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Offset = Layout.getVBaseClassOffset(BaseClassDecl);
807607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  else
808607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Offset = Layout.getBaseClassOffset(BaseClassDecl);
809607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
810607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const llvm::Type *BaseClassType = CGF.ConvertType(QualType(BaseType, 0));
811607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *V = CGF.Builder.CreateBitCast(ThisPtr, Int8PtrTy);
812607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset/8);
813607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo());
814607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CGF.EmitCXXConstructorCall(BaseInit->getConstructor(),
816c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson                             Ctor_Base, V,
817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                             BaseInit->const_arg_begin(),
818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                             BaseInit->const_arg_end());
819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF,
822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  const CXXRecordDecl *ClassDecl,
823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  CXXBaseOrMemberInitializer *MemberInit) {
824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(MemberInit->isMemberInitializer() &&
825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Must have member initializer!");
826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // non-static data member initializers.
828607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FieldDecl *Field = MemberInit->getMember();
829607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
830607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
831607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisPtr = CGF.LoadCXXThis();
83206a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson  LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
83306a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson
834607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we are initializing an anonymous union field, drill down to the field.
835607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (MemberInit->getAnonUnionMember()) {
836607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Field = MemberInit->getAnonUnionMember();
837e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0);
838607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = Field->getType();
839607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
840607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
841607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the field is an array, branch based on the element type.
842607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *Array =
843607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.getContext().getAsConstantArrayType(FieldType);
844607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (Array)
845607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = CGF.getContext().getBaseElementType(FieldType);
846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
847607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // We lose the constructor for anonymous union members, so handle them
848607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // explicitly.
849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: This is somwhat ugly.
850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (MemberInit->getAnonUnionMember() && FieldType->getAs<RecordType>()) {
851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (MemberInit->getNumArgs())
852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.EmitAggExpr(*MemberInit->arg_begin(), LHS.getAddress(),
853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                      LHS.isVolatileQualified());
854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
855607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.EmitAggregateClear(LHS.getAddress(), Field->getType());
856607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
858607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
859607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (FieldType->getAs<RecordType>()) {
860607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(MemberInit->getConstructor() &&
861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "EmitCtorPrologue - no constructor to initialize member");
862607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array) {
863607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      const llvm::Type *BasePtr = CGF.ConvertType(FieldType);
864607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BasePtr = llvm::PointerType::getUnqual(BasePtr);
865607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      llvm::Value *BaseAddrPtr =
866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        CGF.Builder.CreateBitCast(LHS.getAddress(), BasePtr);
867607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.EmitCXXAggrConstructorCall(MemberInit->getConstructor(),
868607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                     Array, BaseAddrPtr,
869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                     MemberInit->const_arg_begin(),
870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                     MemberInit->const_arg_end());
871607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
872607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.EmitCXXConstructorCall(MemberInit->getConstructor(),
874607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 Ctor_Complete, LHS.getAddress(),
875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 MemberInit->const_arg_begin(),
876607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 MemberInit->const_arg_end());
877607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
879607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
880607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(MemberInit->getNumArgs() == 1 && "Initializer count must be 1 only");
881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Expr *RhsExpr = *MemberInit->arg_begin();
882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  RValue RHS;
883607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (FieldType->isReferenceType()) {
884607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    RHS = CGF.EmitReferenceBindingToExpr(RhsExpr, FieldType,
885607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    /*IsInitializer=*/true);
886607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
887607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else if (Array) {
888607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
889607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else if (!CGF.hasAggregateLLVMType(RhsExpr->getType())) {
890607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    RHS = RValue::get(CGF.EmitScalarExpr(RhsExpr, true));
891607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
892607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else if (RhsExpr->getType()->isAnyComplexType()) {
893607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitComplexExprIntoAddr(RhsExpr, LHS.getAddress(),
894607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                LHS.isVolatileQualified());
895607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else {
896607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Handle member function pointers; other aggregates shouldn't get this far.
897607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitAggExpr(RhsExpr, LHS.getAddress(), LHS.isVolatileQualified());
898607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
899607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
900607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
901607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize
902607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor.
903607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXCtorType.
904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXCtorType CtorType) {
906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = CD->getParent();
907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: Add vbase initialization
909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = CD->init_end();
912607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       B != E; ++B) {
913607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXBaseOrMemberInitializer *Member = (*B);
914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(LiveTemporaries.empty() &&
916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "Should not have any live temporaries at initializer start!");
917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Member->isBaseInitializer())
919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitMemberInitializer(*this, ClassDecl, Member);
922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Pop any live temporaries that the initializers might have pushed.
924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    while (!LiveTemporaries.empty())
925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      PopCXXTemporary();
926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
928607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  InitializeVtablePtrs(ClassDecl);
929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's
932607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes
933607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction.
934607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType.
935607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
936607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXDtorType DtorType) {
937607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!DD->isTrivial() &&
938607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Should not emit dtor epilogue for trivial dtor!");
939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = DD->getParent();
941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Collect the fields.
943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->field_end(); I != E; ++I) {
946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = *I;
947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType(Field->getType());
949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = getContext().getBaseElementType(FieldType);
950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!RT)
953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (FieldClassDecl->hasTrivialDestructor())
957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        continue;
958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldDecls.push_back(Field);
960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Now destroy the fields.
963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (size_t i = FieldDecls.size(); i > 0; --i) {
964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = FieldDecls[i - 1];
965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = Field->getType();
967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *ThisPtr = LoadCXXThis();
976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    LValue LHS = EmitLValueForField(ThisPtr, Field,
978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    // FIXME: Qualifiers?
979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    /*CVRQualifiers=*/0);
980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array) {
981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      const llvm::Type *BasePtr = ConvertType(FieldType);
982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BasePtr = llvm::PointerType::getUnqual(BasePtr);
983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      llvm::Value *BaseAddrPtr =
984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                Array, BaseAddrPtr);
987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else
988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Dtor_Complete, LHS.getAddress());
990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Destroy non-virtual bases.
993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) {
995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore virtual bases.
998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base.isVirtual())
999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           ClassDecl, BaseClassDecl,
1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           /*NullCheckValue=*/false);
1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we're emitting a base destructor, we don't want to emit calls to the
1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // virtual bases.
1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Base)
1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Handle virtual bases.
1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) {
1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           ClassDecl, BaseClassDecl,
1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           /*NullCheckValue=*/false);
1034607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
1035607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1036607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1037607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we have a deleting destructor, emit a call to the delete operator.
1038607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Deleting) {
1039607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(DD->getOperatorDelete() &&
1040607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "operator delete missing - EmitDtorEpilogue");
1041607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
1042607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                   getContext().getTagDeclType(ClassDecl));
1043607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1044607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
1045607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1046607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
1047607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  CXXDtorType DtorType,
1048607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  llvm::Function *Fn,
1049607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  const FunctionArgList &Args) {
1050607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Dtor->getParent()->hasUserDeclaredDestructor() &&
1051607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "SynthesizeDefaultDestructor - destructor has user declaration");
1052607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1053607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
1054607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
1055607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1056607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitDtorEpilogue(Dtor, DtorType);
1057607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
1058607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
10593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
10613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the
10623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array.
10633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the
10643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array.
10653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller.
10663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10673b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          const ConstantArrayType *ArrayTy,
10693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value * NumElements =
10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::ConstantInt::get(SizeTy,
10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           getContext().getConstantArrayElementCount(ArrayTy));
10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *NumElements,
10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with 0.
10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index");
10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Zero, IndexPtr);
10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless");
11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter,
11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                   "arrayidx");
11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // C++ [class.temporary]p4:
11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // There are two contexts in which temporaries are destroyed at a different
11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // point than the end of the full-expression. The first context is when a
11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // default constructor is called to initialize an element of an array.
11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the constructor has one or more default arguments, the destruction of
11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // every temporary created in a default argument expression is sequenced
11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // before the construction of the next array element, if any.
11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Keep track of the current number of live temporaries.
11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  unsigned OldNumLiveTemporaries = LiveTemporaries.size();
11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Pop temporaries.
11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  while (LiveTemporaries.size() > OldNumLiveTemporaries)
11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    PopCXXTemporary();
11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the increment of the loop counter.
11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1);
11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const ArrayType *Array,
11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(CA && "Do we support VLA for destruction ?");
11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *UpperCount,
11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with count of
11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // array elements.
11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store the number of elements in the index pointer.
11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(UpperCount, IndexPtr);
11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index != 0 fall to the loop body,
11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* zeroConstant =
11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Constant::getNullValue(SizeLTy);
11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            "isne");
11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One);
12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXDestructorCall(D, Dtor_Complete, Address);
12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the decrement of the loop counter.
12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One, "dec");
12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Counter, IndexPtr);
12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of
12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction.
12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant *
12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 const ArrayType *Array,
12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 llvm::Value *This) {
12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionArgList Args;
12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  ImplicitParamDecl *Dst =
12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ImplicitParamDecl::Create(getContext(), 0,
12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              SourceLocation(), 0,
12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              getContext().getPointerType(getContext().VoidTy));
12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Args.push_back(std::make_pair(Dst, Dst->getType()));
12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::SmallString<16> Name;
12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType R = getContext().VoidTy;
12383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args);
12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Function *Fn =
12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           Name.str(),
12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           &CGM.getModule());
12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str());
12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionDecl *FD = FunctionDecl::Create(getContext(),
12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          getContext().getTranslationUnitDecl(),
12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          SourceLocation(), II, R, 0,
12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          FunctionDecl::Static,
12493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          false, true);
12503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  StartFunction(FD, R, Fn, Args, SourceLocation());
12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType BaseElementTy = getContext().getBaseElementType(Array);
12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *BasePtr = ConvertType(BaseElementTy);
12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FinishFunction();
12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                              0);
12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return m;
12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1263c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
12653b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CXXCtorType Type,
12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        llvm::Value *This,
12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (D->isCopyConstructor()) {
12713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    if (ClassDecl->hasTrivialCopyConstructor()) {
12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
12743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson             "EmitCXXConstructorCall - user declared copy constructor");
12753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      const Expr *E = (*ArgBeg);
12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      QualType Ty = E->getType();
12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      llvm::Value *Src = EmitLValue(E).getAddress();
12783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      EmitAggregateCopy(This, Src, Ty);
12793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      return;
12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    }
12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  } else if (D->isTrivial()) {
12823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    // FIXME: Track down why we're trying to generate calls to the trivial
12833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    // default constructor!
12843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
12853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
12863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1287c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
12893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
12913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
12943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            CXXDtorType Type,
12953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            llvm::Value *This) {
1296c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1299c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
13003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value *
13033b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GetVirtualCXXBaseClassOffset(llvm::Value *This,
13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                              const CXXRecordDecl *ClassDecl,
13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const CXXRecordDecl *BaseClassDecl) {
13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy =
13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Type::getInt8Ty(VMContext)->getPointerTo();
13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VTablePtr = Builder.CreateBitCast(This,
13103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 Int8PtrTy->getPointerTo());
13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
13123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  int64_t VBaseOffsetIndex =
13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffsetPtr =
13173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr");
13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *PtrDiffTy =
13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ConvertType(getContext().getPointerDiffType());
13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr,
13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                         PtrDiffTy->getPointerTo());
13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return VBaseOffset;
13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) {
13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl);
133421431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson  CGVtableInfo::AddrSubMap_t& AddressPoints =
133521431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson      *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl];
13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *ThisPtr = LoadCXXThis();
13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for virtual bases
13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) {
13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl);
13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, Offset);
13483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases and current class
13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0);
13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive(
13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        const CXXRecordDecl *ClassDecl,
13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Constant *Vtable,
135721431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson        CGVtableInfo::AddrSubMap_t& AddressPoints,
13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Value *ThisPtr,
13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        uint64_t Offset) {
13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases
13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    if (Base.isVirtual())
13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      continue;
13703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl);
13733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, NewOffset);
13753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address point
13783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) &&
13793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson         "Missing address point for class");
13803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
13813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableAddressPoint =
13823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
13833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address to store the address point
13853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
13863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
13873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8);
13883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *AddressPointPtrTy =
13893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      VtableAddressPoint->getType()->getPointerTo();
13903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy);
13913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address point
13933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(VtableAddressPoint, VtableField);
13943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
1395c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1396c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() {
1397c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
1398c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson          isa<CXXDestructorDecl>(CurFuncDecl)) &&
1399c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson         "Must be in a C++ ctor or dtor to load the vtt parameter");
1400c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1401c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
1402c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson}
1403