CGClass.cpp revision 9db7dbb918ca49f4ee6c181e4917e7b6ec547353
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 *
47bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class,
48bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                            const CXXRecordDecl *BaseClass) {
49bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (Class == BaseClass)
5084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson    return 0;
5184080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
522f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
532f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
54bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (!const_cast<CXXRecordDecl *>(Class)->
55bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
562f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    assert(false && "Class must be derived from the passed in base class!");
572f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson    return 0;
582f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  }
5984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
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
709fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on
719fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that
729fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well.
739fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment
749fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl,
759fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                                      const CXXRecordDecl *BaseClassDecl) {
769fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
779fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
789fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (!const_cast<CXXRecordDecl *>(ClassDecl)->
799fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
809fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    assert(false && "Class must be derived from the passed in base class!");
819fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    return ThunkAdjustment();
829fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
839fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
849fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  unsigned Start = 0;
859fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t VirtualOffset = 0;
869fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
879fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXBasePath &Path = Paths.front();
889fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXRecordDecl *VBase = 0;
899fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
909fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    const CXXBasePathElement& Element = Path[i];
919fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    if (Element.Base->isVirtual()) {
929fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      Start = i+1;
939fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      QualType VBaseType = Element.Base->getType();
949fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
959fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    }
969fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
979fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (VBase)
989fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    VirtualOffset =
999fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
1009fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1019fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t Offset =
1029fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start);
1039fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  return ThunkAdjustment(Offset, VirtualOffset);
1049fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson}
1059fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1065d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value *
107a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
108bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                       const CXXRecordDecl *Class,
109bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                       const CXXRecordDecl *BaseClass,
110a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                       bool NullCheckValue) {
111dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  QualType BTy =
112dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    getContext().getCanonicalType(
113bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClass)));
114dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
1155d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
116bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (Class == BaseClass) {
117dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    // Just cast back.
118a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, BasePtrTy);
119dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  }
120905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
121905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
122905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
123905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (!const_cast<CXXRecordDecl *>(Class)->
124905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
125905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    assert(false && "Class must be derived from the passed in base class!");
126905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    return 0;
127905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
128905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
129905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  unsigned Start = 0;
130905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *VirtualOffset = 0;
131905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
132905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const CXXBasePath &Path = Paths.front();
133905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const CXXRecordDecl *VBase = 0;
134905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
135905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    const CXXBasePathElement& Element = Path[i];
136905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    if (Element.Base->isVirtual()) {
137905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      Start = i+1;
138905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      QualType VBaseType = Element.Base->getType();
139905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
140905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    }
141905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
142905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
143905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  uint64_t Offset =
144905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    ComputeNonVirtualBaseClassOffset(getContext(), Paths, Start);
1454a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
146905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (!Offset && !VBase) {
147905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    // Just cast back.
148905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    return Builder.CreateBitCast(Value, BasePtrTy);
149905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
150905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
15132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNull = 0;
15232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNotNull = 0;
15332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastEnd = 0;
15432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
15532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
15632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNull = createBasicBlock("cast.null");
15732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
15832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastEnd = createBasicBlock("cast.end");
15932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
16032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    llvm::Value *IsNull =
161a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      Builder.CreateICmpEQ(Value,
162a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                           llvm::Constant::getNullValue(Value->getType()));
16332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
16432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNotNull);
16532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  }
16632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
167905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (VBase)
168905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase);
1694a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
170905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
171905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *NonVirtualOffset = 0;
172905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (Offset)
173905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset);
1745d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
175905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *BaseOffset;
176905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (VBase) {
177905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    if (NonVirtualOffset)
178905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      BaseOffset = Builder.CreateAdd(VirtualOffset, NonVirtualOffset);
179905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    else
180905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      BaseOffset = VirtualOffset;
181905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  } else
182905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    BaseOffset = NonVirtualOffset;
183905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
184905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  // Apply the base offset.
185905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
186905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  Value = Builder.CreateBitCast(Value, Int8PtrTy);
187905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  Value = Builder.CreateGEP(Value, BaseOffset, "add.ptr");
1885d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
1895d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson  // Cast back.
190a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  Value = Builder.CreateBitCast(Value, BasePtrTy);
19132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
19232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
19332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
19432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNull);
19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastEnd);
19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
198a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
199a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->reserveOperandSpace(2);
200a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(Value, CastNotNull);
201a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
202a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                     CastNull);
203a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = PHI;
204a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
205a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
206a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  return Value;
207a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson}
208a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
209a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value *
210a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
211bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                          const CXXRecordDecl *Class,
212bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                          const CXXRecordDecl *DerivedClass,
213a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                          bool NullCheckValue) {
214a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  QualType DerivedTy =
215a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    getContext().getCanonicalType(
216bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson    getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass)));
217a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
218a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
219bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (Class == DerivedClass) {
220a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    // Just cast back.
221a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, DerivedPtrTy);
222a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
223a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
224a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  llvm::Value *NonVirtualOffset =
225a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class);
226a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
227a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  if (!NonVirtualOffset) {
228a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    // No offset, we can just cast back.
229a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    return Builder.CreateBitCast(Value, DerivedPtrTy);
230a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  }
231a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
232a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNull = 0;
233a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNotNull = 0;
234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastEnd = 0;
235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (NullCheckValue) {
237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNull = createBasicBlock("cast.null");
238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastEnd = createBasicBlock("cast.end");
240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::Value *IsNull =
242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateICmpEQ(Value,
243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                         llvm::Constant::getNullValue(Value->getType()));
244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastNotNull);
246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
248a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  // Apply the offset.
249a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
250a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateSub(Value, NonVirtualOffset);
251a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
252a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
253a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  // Just cast.
254a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateBitCast(Value, DerivedPtrTy);
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());
8149db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
816607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF,
818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  const CXXRecordDecl *ClassDecl,
819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  CXXBaseOrMemberInitializer *MemberInit) {
820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(MemberInit->isMemberInitializer() &&
821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Must have member initializer!");
822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // non-static data member initializers.
824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FieldDecl *Field = MemberInit->getMember();
825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisPtr = CGF.LoadCXXThis();
82806a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson  LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
82906a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson
830607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we are initializing an anonymous union field, drill down to the field.
831607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (MemberInit->getAnonUnionMember()) {
832607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Field = MemberInit->getAnonUnionMember();
833e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0);
834607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = Field->getType();
835607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
836607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
837607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the field is an array, branch based on the element type.
838607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *Array =
839607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.getContext().getAsConstantArrayType(FieldType);
840607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (Array)
841607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = CGF.getContext().getBaseElementType(FieldType);
842607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
843607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // We lose the constructor for anonymous union members, so handle them
844607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // explicitly.
8459db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  // FIXME: This is somwhat ugly, and doesn't seem necessary at all.
846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (MemberInit->getAnonUnionMember() && FieldType->getAs<RecordType>()) {
8479db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    if (MemberInit->getInit())
8489db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor      CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(),
849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                      LHS.isVolatileQualified());
850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CGF.EmitAggregateClear(LHS.getAddress(), Field->getType());
852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
8559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer
8569db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  // was implicitly generated, we shouldn't be zeroing memory.
857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  RValue RHS;
858607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (FieldType->isReferenceType()) {
8599db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(), FieldType,
8609db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                                         /*IsInitializer=*/true);
861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
8629db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  } else if (Array && !MemberInit->getInit()) {
863607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
8649db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
8659db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
8679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
8689db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                LHS.isVolatileQualified());
870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else {
8719db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(),
8729db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                    LHS.isVolatileQualified(), false, true);
873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
874607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
876607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize
877607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor.
878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXCtorType.
879607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
880607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXCtorType CtorType) {
881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = CD->getParent();
882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
883607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: Add vbase initialization
884607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
885607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
886607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = CD->init_end();
887607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       B != E; ++B) {
888607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXBaseOrMemberInitializer *Member = (*B);
889607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
890607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(LiveTemporaries.empty() &&
891607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "Should not have any live temporaries at initializer start!");
892607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
893607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Member->isBaseInitializer())
894607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
895607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
896607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitMemberInitializer(*this, ClassDecl, Member);
897607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
898607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Pop any live temporaries that the initializers might have pushed.
899607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    while (!LiveTemporaries.empty())
900607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      PopCXXTemporary();
901607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
902607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
903607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  InitializeVtablePtrs(ClassDecl);
904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's
907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes
908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction.
909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType.
910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXDtorType DtorType) {
912607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!DD->isTrivial() &&
913607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Should not emit dtor epilogue for trivial dtor!");
914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = DD->getParent();
916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Collect the fields.
918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->field_end(); I != E; ++I) {
921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = *I;
922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType(Field->getType());
924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = getContext().getBaseElementType(FieldType);
925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!RT)
928607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (FieldClassDecl->hasTrivialDestructor())
932607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        continue;
933607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
934607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldDecls.push_back(Field);
935607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
936607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
937607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Now destroy the fields.
938607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (size_t i = FieldDecls.size(); i > 0; --i) {
939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = FieldDecls[i - 1];
940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = Field->getType();
942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *ThisPtr = LoadCXXThis();
951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    LValue LHS = EmitLValueForField(ThisPtr, Field,
953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    // FIXME: Qualifiers?
954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    /*CVRQualifiers=*/0);
955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array) {
956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      const llvm::Type *BasePtr = ConvertType(FieldType);
957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BasePtr = llvm::PointerType::getUnqual(BasePtr);
958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      llvm::Value *BaseAddrPtr =
959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                Array, BaseAddrPtr);
962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else
963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Dtor_Complete, LHS.getAddress());
965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Destroy non-virtual bases.
968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) {
970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore virtual bases.
973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base.isVirtual())
974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           ClassDecl, BaseClassDecl,
986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           /*NullCheckValue=*/false);
987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we're emitting a base destructor, we don't want to emit calls to the
991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // virtual bases.
992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Base)
993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Handle virtual bases.
996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) {
998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           ClassDecl, BaseClassDecl,
1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           /*NullCheckValue=*/false);
1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we have a deleting destructor, emit a call to the delete operator.
1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Deleting) {
1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(DD->getOperatorDelete() &&
1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "operator delete missing - EmitDtorEpilogue");
1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                   getContext().getTagDeclType(ClassDecl));
1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  CXXDtorType DtorType,
1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  llvm::Function *Fn,
1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  const FunctionArgList &Args) {
1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Dtor->getParent()->hasUserDeclaredDestructor() &&
1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "SynthesizeDefaultDestructor - destructor has user declaration");
1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitDtorEpilogue(Dtor, DtorType);
1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
10343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
10363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the
10373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array.
10383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the
10393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array.
10403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller.
10413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10423b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          const ConstantArrayType *ArrayTy,
10443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value * NumElements =
10503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::ConstantInt::get(SizeTy,
10513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           getContext().getConstantArrayElementCount(ArrayTy));
10523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
10543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
10553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10573b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *NumElements,
10593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with 0.
10653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index");
10663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
10673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Zero, IndexPtr);
10683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless");
10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter,
10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                   "arrayidx");
10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // C++ [class.temporary]p4:
10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // There are two contexts in which temporaries are destroyed at a different
10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // point than the end of the full-expression. The first context is when a
10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // default constructor is called to initialize an element of an array.
10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the constructor has one or more default arguments, the destruction of
10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // every temporary created in a default argument expression is sequenced
10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // before the construction of the next array element, if any.
10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Keep track of the current number of live temporaries.
11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  unsigned OldNumLiveTemporaries = LiveTemporaries.size();
11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Pop temporaries.
11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  while (LiveTemporaries.size() > OldNumLiveTemporaries)
11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    PopCXXTemporary();
11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the increment of the loop counter.
11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1);
11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const ArrayType *Array,
11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(CA && "Do we support VLA for destruction ?");
11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *UpperCount,
11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with count of
11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // array elements.
11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store the number of elements in the index pointer.
11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(UpperCount, IndexPtr);
11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index != 0 fall to the loop body,
11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* zeroConstant =
11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Constant::getNullValue(SizeLTy);
11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            "isne");
11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One);
11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXDestructorCall(D, Dtor_Complete, Address);
11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the decrement of the loop counter.
11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One, "dec");
11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Counter, IndexPtr);
11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of
11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction.
11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant *
12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 const ArrayType *Array,
12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 llvm::Value *This) {
12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionArgList Args;
12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  ImplicitParamDecl *Dst =
12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ImplicitParamDecl::Create(getContext(), 0,
12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              SourceLocation(), 0,
12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              getContext().getPointerType(getContext().VoidTy));
12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Args.push_back(std::make_pair(Dst, Dst->getType()));
12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::SmallString<16> Name;
12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType R = getContext().VoidTy;
12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args);
12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Function *Fn =
12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           Name.str(),
12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           &CGM.getModule());
12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str());
12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionDecl *FD = FunctionDecl::Create(getContext(),
12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          getContext().getTranslationUnitDecl(),
12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          SourceLocation(), II, R, 0,
12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          FunctionDecl::Static,
12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          false, true);
12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  StartFunction(FD, R, Fn, Args, SourceLocation());
12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType BaseElementTy = getContext().getBaseElementType(Array);
12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *BasePtr = ConvertType(BaseElementTy);
12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FinishFunction();
12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                              0);
12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return m;
12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1238c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CXXCtorType Type,
12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        llvm::Value *This,
12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (D->isCopyConstructor()) {
12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    if (ClassDecl->hasTrivialCopyConstructor()) {
12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
12493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson             "EmitCXXConstructorCall - user declared copy constructor");
12503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      const Expr *E = (*ArgBeg);
12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      QualType Ty = E->getType();
12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      llvm::Value *Src = EmitLValue(E).getAddress();
12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      EmitAggregateCopy(This, Src, Ty);
12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      return;
12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    }
12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  } else if (D->isTrivial()) {
12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    // FIXME: Track down why we're trying to generate calls to the trivial
12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    // default constructor!
12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1262c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
12633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1265c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            CXXDtorType Type,
12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            llvm::Value *This) {
1271c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1274c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
12753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value *
1278bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
1279bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                           const CXXRecordDecl *ClassDecl,
12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const CXXRecordDecl *BaseClassDecl) {
12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy =
12823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Type::getInt8Ty(VMContext)->getPointerTo();
12833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VTablePtr = Builder.CreateBitCast(This,
12853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 Int8PtrTy->getPointerTo());
12863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
12873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  int64_t VBaseOffsetIndex =
12893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
12903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffsetPtr =
12923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr");
12933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *PtrDiffTy =
12943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ConvertType(getContext().getPointerDiffType());
12953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr,
12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                         PtrDiffTy->getPointerTo());
12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
13003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return VBaseOffset;
13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) {
13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl);
130921431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson  CGVtableInfo::AddrSubMap_t& AddressPoints =
131021431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson      *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl];
13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *ThisPtr = LoadCXXThis();
13123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for virtual bases
13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) {
13173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl);
13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, Offset);
13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases and current class
13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0);
13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive(
13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        const CXXRecordDecl *ClassDecl,
13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Constant *Vtable,
133221431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson        CGVtableInfo::AddrSubMap_t& AddressPoints,
13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Value *ThisPtr,
13343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        uint64_t Offset) {
13353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases
13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    if (Base.isVirtual())
13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      continue;
13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl);
13483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, NewOffset);
13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address point
13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) &&
13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson         "Missing address point for class");
13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableAddressPoint =
13573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address to store the address point
13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8);
13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *AddressPointPtrTy =
13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      VtableAddressPoint->getType()->getPointerTo();
13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy);
13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address point
13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(VtableAddressPoint, VtableField);
13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
1370c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1371c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() {
1372c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
1373c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson          isa<CXXDestructorDecl>(CurFuncDecl)) &&
1374c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson         "Must be in a C++ ctor or dtor to load the vtt parameter");
1375c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1376c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
1377c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson}
1378