CGClass.cpp revision bff225ecf77fb891596ecb1b27196310d268365e
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
22bff225ecf77fb891596ecb1b27196310d268365eJohn McCallComputeNonVirtualBaseClassOffset(ASTContext &Context,
23bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                 const CXXBasePath &Path,
242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson                                 unsigned Start) {
252f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson  uint64_t Offset = 0;
265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
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
60bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  uint64_t Offset = ComputeNonVirtualBaseClassOffset(getContext(),
61bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                     Paths.front(), 0);
6284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson  if (!Offset)
6384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson    return 0;
6484080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
652b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson  const llvm::Type *PtrDiffTy =
662b3583573ba6b26b605aacaad9a50492fb3d6fe6Anders Carlsson    Types.ConvertType(getContext().getPointerDiffType());
6784080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
6884080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson  return llvm::ConstantInt::get(PtrDiffTy, Offset);
6984080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson}
7084080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
719fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// FIXME: This probably belongs in CGVtable, but it relies on
729fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// the static function ComputeNonVirtualBaseClassOffset, so we should make that
739fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson// a CodeGenModule member function as well.
749fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonThunkAdjustment
759fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders CarlssonCodeGenModule::ComputeThunkAdjustment(const CXXRecordDecl *ClassDecl,
769fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                                      const CXXRecordDecl *BaseClassDecl) {
779fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
789fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
799fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (!const_cast<CXXRecordDecl *>(ClassDecl)->
809fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClassDecl), Paths)) {
819fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    assert(false && "Class must be derived from the passed in base class!");
829fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    return ThunkAdjustment();
839fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
849fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
859fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  unsigned Start = 0;
869fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t VirtualOffset = 0;
879fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
889fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXBasePath &Path = Paths.front();
899fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  const CXXRecordDecl *VBase = 0;
909fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
919fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    const CXXBasePathElement& Element = Path[i];
929fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    if (Element.Base->isVirtual()) {
939fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      Start = i+1;
949fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      QualType VBaseType = Element.Base->getType();
959fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
969fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    }
979fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  }
989fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  if (VBase)
999fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson    VirtualOffset =
1009fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson      getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
1019fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
1029fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  uint64_t Offset =
103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start);
1049fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson  return ThunkAdjustment(Offset, VirtualOffset);
1059fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson}
1069fcfc421d3bf124beed5b185b8d6d795edcbf83aAnders Carlsson
107bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// Gets the address of a virtual base class within a complete object.
108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// This should only be used for (1) non-virtual bases or (2) virtual bases
109bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// when the type is known to be complete (e.g. in complete destructors).
110bff225ecf77fb891596ecb1b27196310d268365eJohn McCall///
111bff225ecf77fb891596ecb1b27196310d268365eJohn McCall/// The object pointed to by 'This' is assumed to be non-null.
112bff225ecf77fb891596ecb1b27196310d268365eJohn McCallllvm::Value *
113bff225ecf77fb891596ecb1b27196310d268365eJohn McCallCodeGenFunction::GetAddressOfBaseOfCompleteClass(llvm::Value *This,
114bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                 bool isBaseVirtual,
115bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                 const CXXRecordDecl *Derived,
116bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                 const CXXRecordDecl *Base) {
117bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // 'this' must be a pointer (in some address space) to Derived.
118bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  assert(This->getType()->isPointerTy() &&
119bff225ecf77fb891596ecb1b27196310d268365eJohn McCall         cast<llvm::PointerType>(This->getType())->getElementType()
120bff225ecf77fb891596ecb1b27196310d268365eJohn McCall           == ConvertType(Derived));
121bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
122bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // Compute the offset of the virtual base.
123bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  uint64_t Offset;
124bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived);
125bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  if (isBaseVirtual)
126bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    Offset = Layout.getVBaseClassOffset(Base);
127bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  else
128bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    Offset = Layout.getBaseClassOffset(Base);
129bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
130bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // Shift and cast down to the base type.
131bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // TODO: for complete types, this should be possible with a GEP.
132bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  llvm::Value *V = This;
133bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  if (Offset) {
134bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
135bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    V = Builder.CreateBitCast(V, Int8PtrTy);
136bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    V = Builder.CreateConstInBoundsGEP1_64(V, Offset / 8);
137bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  }
138bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo());
139bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
140bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  return V;
141bff225ecf77fb891596ecb1b27196310d268365eJohn McCall}
142bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
1435d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonllvm::Value *
144a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
145bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                       const CXXRecordDecl *Class,
146bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                       const CXXRecordDecl *BaseClass,
147a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                       bool NullCheckValue) {
148dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  QualType BTy =
149dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    getContext().getCanonicalType(
150bff225ecf77fb891596ecb1b27196310d268365eJohn McCall      getContext().getTypeDeclType(BaseClass));
151dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  const llvm::Type *BasePtrTy = llvm::PointerType::getUnqual(ConvertType(BTy));
1525d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
153bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (Class == BaseClass) {
154dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson    // Just cast back.
155a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, BasePtrTy);
156dfd0330267742862342976eb7f2d5ef305790df4Anders Carlsson  }
157905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
158905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  CXXBasePaths Paths(/*FindAmbiguities=*/false,
159905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson                     /*RecordPaths=*/true, /*DetectVirtual=*/false);
160905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (!const_cast<CXXRecordDecl *>(Class)->
161905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson        isDerivedFrom(const_cast<CXXRecordDecl *>(BaseClass), Paths)) {
162905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    assert(false && "Class must be derived from the passed in base class!");
163905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    return 0;
164905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
165905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
166905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  unsigned Start = 0;
167905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *VirtualOffset = 0;
168905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
169905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const CXXBasePath &Path = Paths.front();
170905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const CXXRecordDecl *VBase = 0;
171905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  for (unsigned i = 0, e = Path.size(); i != e; ++i) {
172905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    const CXXBasePathElement& Element = Path[i];
173905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    if (Element.Base->isVirtual()) {
174905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      Start = i+1;
175905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      QualType VBaseType = Element.Base->getType();
176905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      VBase = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
177905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    }
178905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
179905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
180905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  uint64_t Offset =
181bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    ComputeNonVirtualBaseClassOffset(getContext(), Paths.front(), Start);
1824a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
183905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (!Offset && !VBase) {
184905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    // Just cast back.
185905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    return Builder.CreateBitCast(Value, BasePtrTy);
186905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  }
187905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
18832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNull = 0;
18932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastNotNull = 0;
19032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  llvm::BasicBlock *CastEnd = 0;
19132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
19232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
19332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNull = createBasicBlock("cast.null");
19432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
19532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    CastEnd = createBasicBlock("cast.end");
19632baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
19732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    llvm::Value *IsNull =
198a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      Builder.CreateICmpEQ(Value,
199a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                           llvm::Constant::getNullValue(Value->getType()));
20032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
20132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNotNull);
20232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  }
20332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
204905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (VBase)
205905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    VirtualOffset = GetVirtualBaseClassOffset(Value, Class, VBase);
2064a5dc242545222aef6313cc4297708f524e10c6fEli Friedman
207905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
208905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *NonVirtualOffset = 0;
209905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (Offset)
210905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, Offset);
2115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
212905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  llvm::Value *BaseOffset;
213905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  if (VBase) {
214905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    if (NonVirtualOffset)
215905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      BaseOffset = Builder.CreateAdd(VirtualOffset, NonVirtualOffset);
216905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    else
217905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson      BaseOffset = VirtualOffset;
218905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  } else
219905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson    BaseOffset = NonVirtualOffset;
220905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson
221905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  // Apply the base offset.
222905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
223905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  Value = Builder.CreateBitCast(Value, Int8PtrTy);
224905a100f3d03039f6f3e3aecf2996a05cef4a267Anders Carlsson  Value = Builder.CreateGEP(Value, BaseOffset, "add.ptr");
2255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
2265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson  // Cast back.
227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  Value = Builder.CreateBitCast(Value, BasePtrTy);
22832baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
22932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  if (NullCheckValue) {
23032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
23132baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastNull);
23232baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    Builder.CreateBr(CastEnd);
23332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    EmitBlock(CastEnd);
23432baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
235a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
236a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->reserveOperandSpace(2);
237a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(Value, CastNotNull);
238a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
239a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                     CastNull);
240a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = PHI;
241a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
242a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
243a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  return Value;
244a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson}
245a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
246a3697c9c155bda93fd2802f37084b620f4738822Anders Carlssonllvm::Value *
247a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonCodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
248bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                          const CXXRecordDecl *Class,
249bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                          const CXXRecordDecl *DerivedClass,
250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                          bool NullCheckValue) {
251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  QualType DerivedTy =
252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    getContext().getCanonicalType(
253bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson    getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass)));
254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
255a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
256bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson  if (Class == DerivedClass) {
257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    // Just cast back.
258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    return Builder.CreateBitCast(Value, DerivedPtrTy);
259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
260a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
261a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  llvm::Value *NonVirtualOffset =
262a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class);
263a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  if (!NonVirtualOffset) {
265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    // No offset, we can just cast back.
266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    return Builder.CreateBitCast(Value, DerivedPtrTy);
267a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  }
268a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNull = 0;
270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastNotNull = 0;
271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  llvm::BasicBlock *CastEnd = 0;
272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (NullCheckValue) {
274a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNull = createBasicBlock("cast.null");
275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastNotNull = createBasicBlock("cast.notnull");
276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    CastEnd = createBasicBlock("cast.end");
277a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
278a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::Value *IsNull =
279a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateICmpEQ(Value,
280a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                         llvm::Constant::getNullValue(Value->getType()));
281a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
282a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastNotNull);
283a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
284a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
285a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  // Apply the offset.
286a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
287a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateSub(Value, NonVirtualOffset);
288a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
289a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
290a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  // Just cast.
291a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  Value = Builder.CreateBitCast(Value, DerivedPtrTy);
292a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
293a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (NullCheckValue) {
294a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateBr(CastEnd);
295a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastNull);
296a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Builder.CreateBr(CastEnd);
297a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    EmitBlock(CastEnd);
298a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
299a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
30032baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson    PHI->reserveOperandSpace(2);
301a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(Value, CastNotNull);
302a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
30332baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson                     CastNull);
304a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    Value = PHI;
30532baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  }
3065d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
307a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  return Value;
3085d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson}
309607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
310607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
311607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
312607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy or via a copy constructor call.
313607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson//  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
314607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
315607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            llvm::Value *Src,
316607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const ArrayType *Array,
317607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const CXXRecordDecl *BaseClassDecl,
318607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            QualType Ty) {
319607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
320607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(CA && "VLA cannot be copied over");
321607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
322607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
323607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Create a temporary for the loop index and initialize it with 0.
324607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
325607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           "loop.index");
326607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value* zeroConstant =
327607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
328607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(zeroConstant, IndexPtr);
329607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Start the loop with a block that tests the condition.
330607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
331607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
332607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
333607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(CondBlock);
334607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
335607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
336607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
337607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // otherwise, go to the block after the for-loop.
338607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
339607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value * NumElementsPtr =
340607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
341607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
342607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
343607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              "isless");
344607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the condition is true, execute the body.
345607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
346607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
347607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ForBody);
348607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
349607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Inside the loop body, emit the constructor call on the array element.
350607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
351607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
352607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
353607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BitwiseCopy)
354607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
355607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  else if (CXXConstructorDecl *BaseCopyCtor =
356607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           BaseClassDecl->getCopyConstructor(getContext(), 0)) {
357607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
358607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                      Ctor_Complete);
359607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
360607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
361607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
362607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      BaseCopyCtor->getThisType(getContext())));
363607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
364607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
365607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Src),
366607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                     BaseCopyCtor->getParamDecl(0)->getType()));
36704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    const FunctionProtoType *FPT
36804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      = BaseCopyCtor->getType()->getAs<FunctionProtoType>();
36904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
370607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
371607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
372607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ContinueBlock);
373607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
374607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the increment of the loop counter.
375607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
376607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
377607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
378607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
379607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
380607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Finally, branch back up to the condition for the next iteration.
381607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBranch(CondBlock);
382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the fall-through block.
384607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(AfterFor, true);
385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// array of objects from SrcValue to DestValue. Assignment can be either a
389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// bitwise assignment or via a copy assignment operator function call.
390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            llvm::Value *Src,
393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const ArrayType *Array,
394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            const CXXRecordDecl *BaseClassDecl,
395607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                            QualType Ty) {
396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(CA && "VLA cannot be asssigned");
398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Create a temporary for the loop index and initialize it with 0.
401607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
402607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           "loop.index");
403607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value* zeroConstant =
404607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
405607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(zeroConstant, IndexPtr);
406607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Start the loop with a block that tests the condition.
407607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
408607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
409607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
410607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(CondBlock);
411607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
412607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
413607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
414607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // otherwise, go to the block after the for-loop.
415607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
416607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value * NumElementsPtr =
417607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
418607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
419607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
420607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              "isless");
421607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If the condition is true, execute the body.
422607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
423607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
424607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ForBody);
425607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Inside the loop body, emit the assignment operator call on array element.
427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
428607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
429607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
430607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXMethodDecl *MD = 0;
431607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BitwiseAssign)
432607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
433607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  else {
4348a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
4358a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    assert(MD && "EmitClassAggrCopyAssignment - No user assign");
436607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
437607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const llvm::Type *LTy =
438607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
439607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                   FPT->isVariadic());
440607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
441607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
442607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
443607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
444607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
445607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      MD->getThisType(getContext())));
446607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
447607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
4488a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    QualType SrcTy = MD->getParamDecl(0)->getType();
4498a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
4508a850baa41ea9015b949183667ad96a981f10b09Eli Friedman                                                 RValue::getAggregate(Src);
4518a850baa41ea9015b949183667ad96a981f10b09Eli Friedman    CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
45204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
453607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, MD);
454607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
455607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(ContinueBlock);
456607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
457607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the increment of the loop counter.
458607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
459607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
460607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
461607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
462607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
463607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Finally, branch back up to the condition for the next iteration.
464607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBranch(CondBlock);
465607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
466607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Emit the fall-through block.
467607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitBlock(AfterFor, true);
468607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
469607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
470c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// GetVTTParameter - Return the VTT parameter that should be passed to a
471c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson/// base constructor/destructor with virtual bases.
472c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonstatic llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) {
473c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (!CGVtableInfo::needsVTTParameter(GD)) {
474c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // This constructor/destructor does not need a VTT parameter.
475c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return 0;
476c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  }
477c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
478c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent();
479c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
480c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
481c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT;
482c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
483c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  uint64_t SubVTTIndex =
484c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base);
485c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
486c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
487c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) {
488c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // A VTT parameter was passed to the constructor, use it.
489c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.LoadCXXVTT();
490c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
491c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  } else {
492c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // We're the complete constructor, so get the VTT by name.
493c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.CGM.getVtableInfo().getVTT(RD);
494c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
495c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  }
496c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
497c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  return VTT;
498c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson}
499c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
500c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
501607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassMemberwiseCopy - This routine generates code to copy a class
502607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Copying can be either a bitwise copy
503607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// or via a copy constructor call.
504607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassMemberwiseCopy(
505607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        llvm::Value *Dest, llvm::Value *Src,
506607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        const CXXRecordDecl *ClassDecl,
507607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
508c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  CXXCtorType CtorType = Ctor_Complete;
509c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
510607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (ClassDecl) {
511607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
512607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 /*NullCheckValue=*/false);
513607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
514607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                /*NullCheckValue=*/false);
515c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
516c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // We want to call the base constructor.
517c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    CtorType = Ctor_Base;
518607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
519607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BaseClassDecl->hasTrivialCopyConstructor()) {
520607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
521607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
522607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
523607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
524607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (CXXConstructorDecl *BaseCopyCtor =
525607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
526c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType);
527607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgList CallArgs;
528607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the this (Dest) ptr.
529607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Dest),
530607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                      BaseCopyCtor->getThisType(getContext())));
531607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
532c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    // Push the VTT parameter, if necessary.
533c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    if (llvm::Value *VTT =
534c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson          GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) {
535c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      QualType T = getContext().getPointerType(getContext().VoidPtrTy);
536c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      CallArgs.push_back(std::make_pair(RValue::get(VTT), T));
537c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    }
538c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
539607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Push the Src ptr.
540607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CallArgs.push_back(std::make_pair(RValue::get(Src),
541607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                       BaseCopyCtor->getParamDecl(0)->getType()));
54204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    const FunctionProtoType *FPT =
54304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall      BaseCopyCtor->getType()->getAs<FunctionProtoType>();
54404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson             Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
547607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
548607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitClassCopyAssignment - This routine generates code to copy assign a class
550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// object from SrcValue to DestValue. Assignment can be either a bitwise
551607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assignment of via an assignment operator call.
552607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
553607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitClassCopyAssignment(
554607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        llvm::Value *Dest, llvm::Value *Src,
555607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        const CXXRecordDecl *ClassDecl,
556607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        const CXXRecordDecl *BaseClassDecl,
557607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                        QualType Ty) {
558607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (ClassDecl) {
559607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
560607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                 /*NullCheckValue=*/false);
561607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
562607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                /*NullCheckValue=*/false);
563607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
564607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (BaseClassDecl->hasTrivialCopyAssignment()) {
565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitAggregateCopy(Dest, Src, Ty);
566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
567607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
568607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
569607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXMethodDecl *MD = 0;
5708a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  BaseClassDecl->hasConstCopyAssignment(getContext(), MD);
5718a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  assert(MD && "EmitClassCopyAssignment - missing copy assign");
572607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
573607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
574607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const llvm::Type *LTy =
575607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
576607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                   FPT->isVariadic());
577607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
578607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
579607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CallArgList CallArgs;
580607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Push the this (Dest) ptr.
581607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CallArgs.push_back(std::make_pair(RValue::get(Dest),
582607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    MD->getThisType(getContext())));
583607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
584607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Push the Src ptr.
5858a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  QualType SrcTy = MD->getParamDecl(0)->getType();
5868a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
5878a850baa41ea9015b949183667ad96a981f10b09Eli Friedman                                               RValue::getAggregate(Src);
5888a850baa41ea9015b949183667ad96a981f10b09Eli Friedman  CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
58904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
590607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           Callee, ReturnValueSlot(), CallArgs, MD);
591607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
592607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
593607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeDefaultConstructor - synthesize a default constructor
594607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid
595607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor,
596607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              CXXCtorType Type,
597607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              llvm::Function *Fn,
598607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              const FunctionArgList &Args) {
599607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
600607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args,
601607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
602607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitCtorPrologue(Ctor, Type);
603607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
604607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
605607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
606607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a
607607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy constructor, in accordance with section 12.8 (p7 and p8) of C++03
608607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy constructor for class X performs a memberwise
609607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// copy of its subobjects. The order of copying is the same as the order of
610607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// initialization of bases and members in a user-defined constructor
611607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Each subobject is copied in the manner appropriate to its type:
612607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is of class type, the copy constructor for the class is
613607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  used;
614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is an array, each element is copied, in the manner
615607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  appropriate to the element type;
616607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  if the subobject is of scalar type, the built-in assignment operator is
617607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///  used.
618607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Virtual base class subobjects shall be copied only once by the
619607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly-defined copy constructor
620607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
621607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid
622607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders CarlssonCodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
623607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              CXXCtorType Type,
624607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              llvm::Function *Fn,
625607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                              const FunctionArgList &Args) {
626607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = Ctor->getParent();
627607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
628607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      "SynthesizeCXXCopyConstructor - copy constructor has definition already");
629607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
630607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args,
631607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
632607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
633607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FunctionArgList::const_iterator i = Args.begin();
634607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *ThisArg = i->first;
635607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
636607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
637607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *SrcArg = (i+1)->first;
638607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
639607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
640607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
641607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Base != ClassDecl->bases_end(); ++Base) {
643607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // FIXME. copy constrution of virtual base NYI
644607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base->isVirtual())
645607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
646607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
647607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
648607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Base->getType());
651607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
652607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
653607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
654607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->field_end(); I != E; ++I) {
655607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = *I;
656607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
657607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType(Field->getType());
658607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
659607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
660607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
661607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
662607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
663607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
664607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CXXRecordDecl *FieldClassDecl
665607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        = cast<CXXRecordDecl>(FieldClassType->getDecl());
666e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue LHS = EmitLValueForField(LoadOfThis, Field, 0);
667e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue RHS = EmitLValueForField(LoadOfSrc, Field, 0);
668607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      if (Array) {
669607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        const llvm::Type *BasePtr = ConvertType(FieldType);
670607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        BasePtr = llvm::PointerType::getUnqual(BasePtr);
671607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *DestBaseAddrPtr =
672607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
673607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *SrcBaseAddrPtr =
674607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
675607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
676607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    FieldClassDecl, FieldType);
677607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      }
678607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      else
679607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
680607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
681607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
682607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
683607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
684607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Do a built-in assignment of scalar data members.
6859cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson    LValue LHS = EmitLValueForFieldInitialization(LoadOfThis, Field, 0);
6869cfe0ec4decfd19a0387bb737f28eb0ea2c3a476Anders Carlsson    LValue RHS = EmitLValueForFieldInitialization(LoadOfSrc, Field, 0);
687607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
688607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!hasAggregateLLVMType(Field->getType())) {
689607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
690607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
691607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else if (Field->getType()->isAnyComplexType()) {
692607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
693607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                               RHS.isVolatileQualified());
694607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
695607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else {
696607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
697607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
698607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
699607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
700607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  InitializeVtablePtrs(ClassDecl);
701607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
702607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
703607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
704607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
705607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// Before the implicitly-declared copy assignment operator for a class is
706607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined, all implicitly- declared copy assignment operators for
707607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// its direct base classes and its nonstatic data members shall have been
708607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// implicitly defined. [12.8-p12]
709607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// The implicitly-defined copy assignment operator for class X performs
710607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// memberwise assignment of its subob- jects. The direct base classes of X are
711607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// assigned first, in the order of their declaration in
712607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// the base-specifier-list, and then the immediate nonstatic data members of X
713607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// are assigned, in the order in which they were declared in the class
714607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// definition.Each subobject is assigned in the manner appropriate to its type:
715607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is of class type, the copy assignment operator for the
716607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   class is used (as if by explicit qualification; that is, ignoring any
717607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   possible virtual overriding functions in more derived classes);
718607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///
719607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is an array, each element is assigned, in the manner
720607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   appropriate to the element type;
721607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///
722607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   if the subobject is of scalar type, the built-in assignment operator is
723607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson///   used.
724607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
725607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  llvm::Function *Fn,
726607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  const FunctionArgList &Args) {
727607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
728607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
729607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
730607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
731607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation());
732607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
733607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FunctionArgList::const_iterator i = Args.begin();
734607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *ThisArg = i->first;
735607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
736607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
737607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const VarDecl *SrcArg = (i+1)->first;
738607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
739607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
740607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
741607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
742607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Base != ClassDecl->bases_end(); ++Base) {
743607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // FIXME. copy assignment of virtual base NYI
744607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base->isVirtual())
745607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
746607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
747607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
748607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
749607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
750607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Base->getType());
751607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
752607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
753607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
754607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       FieldEnd = ClassDecl->field_end();
755607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       Field != FieldEnd; ++Field) {
756607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
757607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
758607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
759607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
760607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
761607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
762607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
763607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      CXXRecordDecl *FieldClassDecl
764607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(FieldClassType->getDecl());
765e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
766e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
767607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      if (Array) {
768607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        const llvm::Type *BasePtr = ConvertType(FieldType);
769607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        BasePtr = llvm::PointerType::getUnqual(BasePtr);
770607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *DestBaseAddrPtr =
771607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
772607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        llvm::Value *SrcBaseAddrPtr =
773607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
774607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
775607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    FieldClassDecl, FieldType);
776607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      }
777607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      else
778607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
779607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
780607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
781607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
782607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Do a built-in assignment of scalar data members.
783e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LValue LHS = EmitLValueForField(LoadOfThis, *Field, 0);
784e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, 0);
785607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!hasAggregateLLVMType(Field->getType())) {
786607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      RValue RVRHS = EmitLoadOfLValue(RHS, Field->getType());
787607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitStoreThroughLValue(RVRHS, LHS, Field->getType());
788607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else if (Field->getType()->isAnyComplexType()) {
789607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      ComplexPairTy Pair = LoadComplexFromAddr(RHS.getAddress(),
790607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                               RHS.isVolatileQualified());
791607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      StoreComplexToAddr(Pair, LHS.getAddress(), LHS.isVolatileQualified());
792607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else {
793607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitAggregateCopy(LHS.getAddress(), RHS.getAddress(), Field->getType());
794607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
795607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
796607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
797607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // return *this;
798607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Builder.CreateStore(LoadOfThis, ReturnValue);
799607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
800607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
801607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
802607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
803607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitBaseInitializer(CodeGenFunction &CGF,
804607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                const CXXRecordDecl *ClassDecl,
805607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                CXXBaseOrMemberInitializer *BaseInit,
806607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                CXXCtorType CtorType) {
807607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(BaseInit->isBaseInitializer() &&
808607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Must have base initializer!");
809607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
810607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisPtr = CGF.LoadCXXThis();
811607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
812607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const Type *BaseType = BaseInit->getBaseClass();
813607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  CXXRecordDecl *BaseClassDecl =
814607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
815607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
816607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: This method of determining whether a base is virtual is ridiculous;
817607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // it should be part of BaseInit.
818607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  bool isBaseVirtual = false;
819607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(),
820607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->vbases_end(); I != E; ++I)
821607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (I->getType()->getAs<RecordType>()->getDecl() == BaseClassDecl) {
822607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      isBaseVirtual = true;
823607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      break;
824607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    }
825607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
826607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // The base constructor doesn't construct virtual bases.
827607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (CtorType == Ctor_Base && isBaseVirtual)
828607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
829607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
830bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // We can pretend to be a complete class because it only matters for
831bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  // virtual bases, and we only do virtual bases for complete ctors.
832bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  llvm::Value *V = ThisPtr;
833bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  V = CGF.GetAddressOfBaseOfCompleteClass(V, isBaseVirtual,
834bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                          ClassDecl, BaseClassDecl);
835bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
8369db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
837594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson
838594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson  if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) {
839594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson    // FIXME: Is this OK for C++0x delegating constructors?
840594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson    CodeGenFunction::EHCleanupBlock Cleanup(CGF);
841594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson
842594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson    CXXDestructorDecl *DD = BaseClassDecl->getDestructor(CGF.getContext());
843594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson    CGF.EmitCXXDestructorCall(DD, Dtor_Base, V);
844594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson  }
845607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
846607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
847607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonstatic void EmitMemberInitializer(CodeGenFunction &CGF,
848607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  const CXXRecordDecl *ClassDecl,
849607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                  CXXBaseOrMemberInitializer *MemberInit) {
850607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(MemberInit->isMemberInitializer() &&
851607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Must have member initializer!");
852607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
853607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // non-static data member initializers.
854607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FieldDecl *Field = MemberInit->getMember();
855607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
856607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
857607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::Value *ThisPtr = CGF.LoadCXXThis();
85806a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson  LValue LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
85906a2970e9480c6d02b367b2f970baff29b9f9721Anders Carlsson
860607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we are initializing an anonymous union field, drill down to the field.
861607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (MemberInit->getAnonUnionMember()) {
862607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Field = MemberInit->getAnonUnionMember();
863e6d2a534851a649485cb087e9dfcaf8a65886858Anders Carlsson    LHS = CGF.EmitLValueForField(LHS.getAddress(), Field, 0);
864607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = Field->getType();
865607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
866607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
8679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  // FIXME: If there's no initializer and the CXXBaseOrMemberInitializer
8689db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  // was implicitly generated, we shouldn't be zeroing memory.
869607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  RValue RHS;
870607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (FieldType->isReferenceType()) {
871a64a869312066ff6119d1d7ae03f88ce499e3f82Anders Carlsson    RHS = CGF.EmitReferenceBindingToExpr(MemberInit->getInit(),
8729db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                                         /*IsInitializer=*/true);
873607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
8743bb9412788e04755cb509ec576f41afbed4efdd3Eli Friedman  } else if (FieldType->isArrayType() && !MemberInit->getInit()) {
875607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
8769db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
8779db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
878607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
8799db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
8809db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
881607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                LHS.isVolatileQualified());
882607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  } else {
8839db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(),
8849db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                    LHS.isVolatileQualified(), false, true);
8859405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson
8869405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    if (!CGF.Exceptions)
8879405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      return;
8889405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson
8899405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
8909405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    if (!RT)
8919405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      return;
8929405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson
8939405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
8949405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    if (!RD->hasTrivialDestructor()) {
8959405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      // FIXME: Is this OK for C++0x delegating constructors?
8969405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      CodeGenFunction::EHCleanupBlock Cleanup(CGF);
8979405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson
8989405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      llvm::Value *ThisPtr = CGF.LoadCXXThis();
8999405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
9009405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson
9019405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      CXXDestructorDecl *DD = RD->getDestructor(CGF.getContext());
9029405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson      CGF.EmitCXXDestructorCall(DD, Dtor_Complete, LHS.getAddress());
9039405dcd83f090d86d5d06ab3a4e59cc39e7edd93Anders Carlsson    }
904607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
905607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
906607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
907607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitCtorPrologue - This routine generates necessary code to initialize
908607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// base classes and non-static data members belonging to this constructor.
909607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
910607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXCtorType CtorType) {
911607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = CD->getParent();
912a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson
913a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson  llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> MemberInitializers;
914607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
915607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // FIXME: Add vbase initialization
916607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
917607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
918607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = CD->init_end();
919607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       B != E; ++B) {
920607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXBaseOrMemberInitializer *Member = (*B);
921607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
922607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(LiveTemporaries.empty() &&
923607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "Should not have any live temporaries at initializer start!");
924607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
925607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Member->isBaseInitializer())
926607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
927607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    else
928a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson      MemberInitializers.push_back(Member);
929607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
930607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
931607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  InitializeVtablePtrs(ClassDecl);
932a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson
933a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson  for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) {
934a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson    assert(LiveTemporaries.empty() &&
935a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson           "Should not have any live temporaries at initializer start!");
936a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson
937a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson    EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I]);
938a78fa2c40fbbe505485e7d120dc68a292ee0c968Anders Carlsson  }
939607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
940607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
941607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// EmitDtorEpilogue - Emit all code that comes at the end of class's
942607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// destructor. This is to call destructors on members and base classes
943607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// in reverse order of their construction.
944607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson/// FIXME: This needs to take a CXXDtorType.
945607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD,
946607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                       CXXDtorType DtorType) {
947607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!DD->isTrivial() &&
948607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "Should not emit dtor epilogue for trivial dtor!");
949607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
950607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const CXXRecordDecl *ClassDecl = DD->getParent();
951607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
952607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Collect the fields.
953607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  llvm::SmallVector<const FieldDecl *, 16> FieldDecls;
954607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
955607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       E = ClassDecl->field_end(); I != E; ++I) {
956607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = *I;
957607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
958607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = getContext().getCanonicalType(Field->getType());
959607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldType = getContext().getBaseElementType(FieldType);
960607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
961607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
962607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (!RT)
963607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
964607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
965607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
966607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (FieldClassDecl->hasTrivialDestructor())
967607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        continue;
968607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
969607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    FieldDecls.push_back(Field);
970607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
971607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
972607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Now destroy the fields.
973607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (size_t i = FieldDecls.size(); i > 0; --i) {
974607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const FieldDecl *Field = FieldDecls[i - 1];
975607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
976607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    QualType FieldType = Field->getType();
977607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const ConstantArrayType *Array =
978607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      getContext().getAsConstantArrayType(FieldType);
979607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array)
980607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      FieldType = getContext().getBaseElementType(FieldType);
981607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
982607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const RecordType *RT = FieldType->getAs<RecordType>();
983607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
984607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
985607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *ThisPtr = LoadCXXThis();
986607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
987607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    LValue LHS = EmitLValueForField(ThisPtr, Field,
988607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    // FIXME: Qualifiers?
989607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                    /*CVRQualifiers=*/0);
990607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Array) {
991607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      const llvm::Type *BasePtr = ConvertType(FieldType);
992607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      BasePtr = llvm::PointerType::getUnqual(BasePtr);
993607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      llvm::Value *BaseAddrPtr =
994607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
995607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
996607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                Array, BaseAddrPtr);
997607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    } else
998607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
999607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                            Dtor_Complete, LHS.getAddress());
1000607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1001607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1002607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Destroy non-virtual bases.
1003607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
1004607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson        ClassDecl->bases_rbegin(), E = ClassDecl->bases_rend(); I != E; ++I) {
1005607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
1006607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1007607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore virtual bases.
1008607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (Base.isVirtual())
1009607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1010607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1011607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
1012607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
1013607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1014607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
1015607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
1016607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1017607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
1018607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1019607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
1020607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           ClassDecl, BaseClassDecl,
1021607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                           /*NullCheckValue=*/false);
1022607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
1023607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1024607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1025607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we're emitting a base destructor, we don't want to emit calls to the
1026607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // virtual bases.
1027607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Base)
1028607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    return;
1029607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1030607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Handle virtual bases.
1031607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  for (CXXRecordDecl::reverse_base_class_const_iterator I =
1032607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson       ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) {
1033607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXBaseSpecifier &Base = *I;
1034607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    CXXRecordDecl *BaseClassDecl
1035bff225ecf77fb891596ecb1b27196310d268365eJohn McCall      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
1036607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1037607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Ignore trivial destructors.
1038607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (BaseClassDecl->hasTrivialDestructor())
1039607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      continue;
1040607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext());
1041bff225ecf77fb891596ecb1b27196310d268365eJohn McCall    llvm::Value *V = GetAddressOfBaseOfCompleteClass(LoadCXXThis(),
1042bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                     true,
1043bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                     ClassDecl,
1044bff225ecf77fb891596ecb1b27196310d268365eJohn McCall                                                     BaseClassDecl);
1045607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitCXXDestructorCall(D, Dtor_Base, V);
1046607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1047607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1048607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // If we have a deleting destructor, emit a call to the delete operator.
1049607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  if (DtorType == Dtor_Deleting) {
1050607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(DD->getOperatorDelete() &&
1051607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "operator delete missing - EmitDtorEpilogue");
1052607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    EmitDeleteCall(DD->getOperatorDelete(), LoadCXXThis(),
1053607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                   getContext().getTagDeclType(ClassDecl));
1054607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
1055607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
1056607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1057607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
1058607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  CXXDtorType DtorType,
1059607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  llvm::Function *Fn,
1060607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                  const FunctionArgList &Args) {
1061607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  assert(!Dtor->getParent()->hasUserDeclaredDestructor() &&
1062607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson         "SynthesizeDefaultDestructor - destructor has user declaration");
1063607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
1064607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args,
1065607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                SourceLocation());
10661851a12605bc6f1ea70d11974a315340ebaab6ebAnders Carlsson  InitializeVtablePtrs(Dtor->getParent());
1067607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  EmitDtorEpilogue(Dtor, DtorType);
1068607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  FinishFunction();
1069607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson}
10703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
10723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// for-loop to call the default constructor on individual members of the
10733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array.
10743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// 'D' is the default constructor for elements of the array, 'ArrayTy' is the
10753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// array type and 'ArrayPtr' points to the beginning fo the array.
10763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// It is assumed that all relevant checks have been made by the caller.
10773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10783b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          const ConstantArrayType *ArrayTy,
10803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value * NumElements =
10863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::ConstantInt::get(SizeTy,
10873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           getContext().getConstantArrayElementCount(ArrayTy));
10883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrConstructorCall(D, NumElements, ArrayPtr, ArgBeg, ArgEnd);
10903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
10913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
10923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
10933b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
10943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *NumElements,
10953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          llvm::Value *ArrayPtr,
10963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
10973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
10983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
10993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with 0.
11013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeTy, "loop.index");
11023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
11033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Zero, IndexPtr);
11043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
11063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
11073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
11083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
11103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
11123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index < number-of-elements fall to the loop body,
11143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
11153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
11163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElements, "isless");
11173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
11183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
11193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
11213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
11233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
11243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(ArrayPtr, Counter,
11263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                   "arrayidx");
11273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // C++ [class.temporary]p4:
11293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // There are two contexts in which temporaries are destroyed at a different
11303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // point than the end of the full-expression. The first context is when a
11313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // default constructor is called to initialize an element of an array.
11323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the constructor has one or more default arguments, the destruction of
11333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // every temporary created in a default argument expression is sequenced
11343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // before the construction of the next array element, if any.
11353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Keep track of the current number of live temporaries.
11373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  unsigned OldNumLiveTemporaries = LiveTemporaries.size();
11383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
11403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Pop temporaries.
11423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  while (LiveTemporaries.size() > OldNumLiveTemporaries)
11433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    PopCXXTemporary();
11443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
11463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the increment of the loop counter.
11483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *NextVal = llvm::ConstantInt::get(SizeTy, 1);
11493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
11503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
11513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(NextVal, IndexPtr);
11523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
11543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
11553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
11573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
11583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11633b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const ArrayType *Array,
11653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
11673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(CA && "Do we support VLA for destruction ?");
11683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
11693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
11723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
11733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
11743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// EmitCXXAggrDestructorCall - calls the default destructor on array
11763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// elements in reverse order of construction.
11773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
11783b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
11793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *UpperCount,
11803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           llvm::Value *This) {
11813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
11823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
11833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Create a temporary for the loop index and initialize it with count of
11853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // array elements.
11863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
11873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store the number of elements in the index pointer.
11893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(UpperCount, IndexPtr);
11903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Start the loop with a block that tests the condition.
11923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
11933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
11943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(CondBlock);
11963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
11983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
11993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Generate: if (loop-index != 0 fall to the loop body,
12003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // otherwise, go to the block after the for-loop.
12013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value* zeroConstant =
12023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Constant::getNullValue(SizeLTy);
12033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
12043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
12053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            "isne");
12063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // If the condition is true, execute the body.
12073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
12083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12093b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ForBody);
12103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
12123b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Inside the loop body, emit the constructor call on the array element.
12133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
12143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One);
12153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
12163b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXDestructorCall(D, Dtor_Complete, Address);
12173b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(ContinueBlock);
12193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the decrement of the loop counter.
12213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateLoad(IndexPtr);
12223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Counter = Builder.CreateSub(Counter, One, "dec");
12233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(Counter, IndexPtr);
12243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Finally, branch back up to the condition for the next iteration.
12263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBranch(CondBlock);
12273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Emit the fall-through block.
12293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitBlock(AfterFor, true);
12303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
12333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// invoked, calls the default destructor on array elements in reverse order of
12343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson/// construction.
12353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Constant *
12363b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
12373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 const ArrayType *Array,
12383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 llvm::Value *This) {
12393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionArgList Args;
12403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  ImplicitParamDecl *Dst =
12413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ImplicitParamDecl::Create(getContext(), 0,
12423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              SourceLocation(), 0,
12433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                              getContext().getPointerType(getContext().VoidTy));
12443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Args.push_back(std::make_pair(Dst, Dst->getType()));
12453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
12463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::SmallString<16> Name;
12473b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
12483b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType R = getContext().VoidTy;
124904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  const CGFunctionInfo &FI
125004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    = CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
12513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
12523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Function *Fn =
12533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
12543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           Name.str(),
12553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                           &CGM.getModule());
12563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  IdentifierInfo *II = &CGM.getContext().Idents.get(Name.str());
12573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FunctionDecl *FD = FunctionDecl::Create(getContext(),
12583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          getContext().getTranslationUnitDecl(),
12593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          SourceLocation(), II, R, 0,
12603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          FunctionDecl::Static,
12613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                          false, true);
12623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  StartFunction(FD, R, Fn, Args, SourceLocation());
12633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  QualType BaseElementTy = getContext().getBaseElementType(Array);
12643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *BasePtr = ConvertType(BaseElementTy);
12653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
12663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr);
12673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
12683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  FinishFunction();
12693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
12703b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                              0);
12713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
12723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return m;
12733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
12743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1275c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
12763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid
12773b5ad2283c999f6edf7d42332a655447b7386b2eAnders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
12783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CXXCtorType Type,
12793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        llvm::Value *This,
12803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
12813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
12828b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall  if (D->isTrivial()) {
12838b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    if (ArgBeg == ArgEnd) {
12848b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall      // Trivial default constructor, no codegen required.
12858b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall      assert(D->isDefaultConstructor() &&
12868b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall             "trivial 0-arg ctor not a default ctor");
12873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      return;
12883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    }
12898b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall
12908b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    assert(ArgBeg + 1 == ArgEnd && "unexpected argcount for trivial ctor");
12918b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    assert(D->isCopyConstructor() && "trivial 1-arg ctor not a copy ctor");
12928b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall
12938b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    const Expr *E = (*ArgBeg);
12948b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    QualType Ty = E->getType();
12958b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    llvm::Value *Src = EmitLValue(E).getAddress();
12968b6bbeb2a3eb59df77ce69f4eeb28aa6a81015eaJohn McCall    EmitAggregateCopy(This, Src, Ty);
12973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
12983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
12993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1300c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
13013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
13023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1303c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
13043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
13073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            CXXDtorType Type,
13083b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                            llvm::Value *This) {
1309c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
13103b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
13113b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
1312c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
13133b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13143b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13153b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonllvm::Value *
1316bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders CarlssonCodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
1317bb7e17b52ffaa4097b4c4d7935746d23539ffe2aAnders Carlsson                                           const CXXRecordDecl *ClassDecl,
13183b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                           const CXXRecordDecl *BaseClassDecl) {
13193b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy =
13203b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    llvm::Type::getInt8Ty(VMContext)->getPointerTo();
13213b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13223b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VTablePtr = Builder.CreateBitCast(This,
13233b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                                 Int8PtrTy->getPointerTo());
13243b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VTablePtr = Builder.CreateLoad(VTablePtr, "vtable");
13253b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13263b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  int64_t VBaseOffsetIndex =
13273b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CGM.getVtableInfo().getVirtualBaseOffsetIndex(ClassDecl, BaseClassDecl);
13283b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13293b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffsetPtr =
13303b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetIndex, "vbase.offset.ptr");
13313b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *PtrDiffTy =
13323b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    ConvertType(getContext().getPointerDiffType());
13333b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13343b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr,
13353b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                         PtrDiffTy->getPointerTo());
13363b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13373b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset");
13383b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13393b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  return VBaseOffset;
13403b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13413b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13423b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) {
13433b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13443b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13453b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13463b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl);
134721431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson  CGVtableInfo::AddrSubMap_t& AddressPoints =
134821431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson      *(*CGM.getVtableInfo().AddressPoints[ClassDecl])[ClassDecl];
13493b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *ThisPtr = LoadCXXThis();
13503b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13513b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13523b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for virtual bases
13533b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13543b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) {
13553b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13563b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13573b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13583b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl);
13593b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13603b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, Offset);
13613b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13623b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13633b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases and current class
13643b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0);
13653b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
13663b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13673b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlssonvoid CodeGenFunction::InitializeVtablePtrsRecursive(
13683b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        const CXXRecordDecl *ClassDecl,
13693b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Constant *Vtable,
137021431c551d867962c66c92f0f96f652678f64c1cAnders Carlsson        CGVtableInfo::AddrSubMap_t& AddressPoints,
13713b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        llvm::Value *ThisPtr,
13723b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson        uint64_t Offset) {
13733b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  if (!ClassDecl->isDynamicClass())
13743b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    return;
13753b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13763b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address points for non-virtual bases
13773b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
13783b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I =
13793b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson       ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
13803b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    const CXXBaseSpecifier &Base = *I;
13813b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    if (Base.isVirtual())
13823b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      continue;
13833b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    CXXRecordDecl *BaseClassDecl
13843b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
13853b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl);
13863b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson    InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
13873b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson                                  ThisPtr, NewOffset);
13883b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  }
13893b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13903b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address point
13913b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) &&
13923b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson         "Missing address point for class");
13933b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
13943b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableAddressPoint =
13953b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
13963b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
13973b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Compute the address to store the address point
13983b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
13993b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
14003b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8);
14013b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  const llvm::Type *AddressPointPtrTy =
14023b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson      VtableAddressPoint->getType()->getPointerTo();
14033b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  VtableField = Builder.CreateBitCast(VtableField, AddressPointPtrTy);
14043b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson
14053b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  // Store address point
14063b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson  Builder.CreateStore(VtableAddressPoint, VtableField);
14073b5ad2283c999f6edf7d42332a655447b7386b2eAnders Carlsson}
1408c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1409c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlssonllvm::Value *CodeGenFunction::LoadCXXVTT() {
1410c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
1411c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson          isa<CXXDestructorDecl>(CurFuncDecl)) &&
1412c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson         "Must be in a C++ ctor or dtor to load the vtt parameter");
1413c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
1414c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
1415c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson}
1416