CGCXX.cpp revision 5a0f49ebc83e7fe0da07b9964c44b0a7fae270cb
1e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
3e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//                     The LLVM Compiler Infrastructure
4e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
5e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This file is distributed under the University of Illinois Open Source
6e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// License. See LICENSE.TXT for details.
7e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
8e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
9e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
10e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This contains code dealing with C++ code generation.
11e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
12e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
13e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump// We might split this into multiple files if it gets too unwieldy
15e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
16e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenFunction.h"
17e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenModule.h"
18283a062a633d6e868aa2be319da812341fe73728Anders Carlsson#include "Mangle.h"
19e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/ASTContext.h"
20742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian#include "clang/AST/RecordLayout.h"
21e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h"
22774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson#include "clang/AST/DeclCXX.h"
2386e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h"
24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
27e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid
293b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders CarlssonCodeGenFunction::EmitCXXGlobalDtorRegistration(const CXXDestructorDecl *Dtor,
303b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                               llvm::Constant *DeclPtr) {
313b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // FIXME: This is ABI dependent and we use the Itanium ABI.
321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::Type *Int8PtrTy =
340032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
363b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  std::vector<const llvm::Type *> Params;
373b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
393b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // Get the destructor function type
401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::Type *DtorFnTy =
410032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
423b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy);
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
443b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.clear();
453b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(DtorFnTy);
463b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
473b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
493b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // Get the __cxa_atexit function type
503b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::FunctionType *AtExitFnTy =
523b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false);
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
543b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy,
553b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                                       "__cxa_atexit");
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
573b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
583b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                                     "__dso_handle");
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
603b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
623b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy),
633b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                           llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy),
643b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                           llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) };
653b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
663b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson}
673b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
693b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                               llvm::Constant *DeclPtr) {
703b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  assert(D.hasGlobalStorage() &&
713b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson         "VarDecl must have global storage!");
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
733b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  const Expr *Init = D.getInit();
743b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  QualType T = D.getType();
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
763b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  if (T->isReferenceType()) {
77622f9dc76bdc4f4d6920907f4fb64a3222aa6566Anders Carlsson    ErrorUnsupported(Init, "global variable that binds to a reference");
783b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  } else if (!hasAggregateLLVMType(T)) {
793b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    llvm::Value *V = EmitScalarExpr(Init);
803b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    EmitStoreOfScalar(V, DeclPtr, T.isVolatileQualified(), T);
813b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  } else if (T->isAnyComplexType()) {
823b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    EmitComplexExprIntoAddr(Init, DeclPtr, T.isVolatileQualified());
833b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  } else {
843b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    EmitAggExpr(Init, DeclPtr, T.isVolatileQualified());
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
863b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    if (const RecordType *RT = T->getAs<RecordType>()) {
873b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson      CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
883b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson      if (!RD->hasTrivialDestructor())
893b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson        EmitCXXGlobalDtorRegistration(RD->getDestructor(getContext()), DeclPtr);
903b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    }
913b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  }
923b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson}
933b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
9489ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlssonvoid
9589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders CarlssonCodeGenModule::EmitCXXGlobalInitFunc() {
9689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  if (CXXGlobalInits.empty())
9789ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    return;
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
990032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  const llvm::FunctionType *FTy = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
10089ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                          false);
1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10289ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  // Create our global initialization function.
10389ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  // FIXME: Should this be tweakable by targets?
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Function *Fn =
10589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
10689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                           "__cxx_global_initialization", &TheModule);
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
10910c40eee98c600d24437474463b056f323d0cfd2Benjamin Kramer                                                   &CXXGlobalInits[0],
11089ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                   CXXGlobalInits.size());
11189ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  AddGlobalCtor(Fn);
11289ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson}
11389ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
11489ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlssonvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
11589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                const VarDecl **Decls,
11689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                unsigned NumDecls) {
1170ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
11889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                SourceLocation());
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12089ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  for (unsigned i = 0; i != NumDecls; ++i) {
12189ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    const VarDecl *D = Decls[i];
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12389ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
12489ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    EmitCXXGlobalVarDeclInit(*D, DeclPtr);
12589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  }
12689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  FinishFunction();
12789ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson}
12889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpCodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
1313b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                               llvm::GlobalVariable *GV) {
1320096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar  // FIXME: This should use __cxa_guard_{acquire,release}?
1330096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar
134e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(!getContext().getLangOptions().ThreadsafeStatics &&
135e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "thread safe statics are currently not supported!");
136e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
137283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::SmallString<256> GuardVName;
138283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  llvm::raw_svector_ostream GuardVOut(GuardVName);
139283a062a633d6e868aa2be319da812341fe73728Anders Carlsson  mangleGuardVariable(&D, getContext(), GuardVOut);
1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
141e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::GlobalValue *GuardV =
1430032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    new llvm::GlobalVariable(CGM.getModule(), llvm::Type::getInt64Ty(VMContext), false,
1440096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                             GV->getLinkage(),
1450032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                             llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)),
1467765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                             GuardVName.str());
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
1490032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
151e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
153e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Compare it against 0.
1540032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext));
155e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar  llvm::BasicBlock *InitBlock = createBasicBlock("init");
1589615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar  llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
159e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
160e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // If the guard variable is 0, jump to the initializer code.
161e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
163e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(InitBlock);
164e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
1653b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  EmitCXXGlobalVarDeclInit(D, GV);
1663b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
1670032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1),
168e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                      Builder.CreateBitCast(GuardV, PtrTy));
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(EndBlock);
171e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
172e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
173b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
174b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          llvm::Value *Callee,
175b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          llvm::Value *This,
176b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          CallExpr::const_arg_iterator ArgBeg,
177b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                          CallExpr::const_arg_iterator ArgEnd) {
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(MD->isInstance() &&
179774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson         "Trying to emit a member call expr on a static method!");
180b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
1814fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor  // A call to a trivial destructor requires no code generation.
1824fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor  if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD))
1834fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor    if (Destructor->isTrivial())
1844fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor      return RValue::get(0);
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
186b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
188b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  CallArgList Args;
1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
190b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // Push the this ptr.
191b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  Args.push_back(std::make_pair(RValue::get(This),
192b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                MD->getThisType(getContext())));
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
194b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // And the rest of the call args
195b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
197b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
198b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
199b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                  Callee, Args, MD);
200b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson}
201b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
202b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
203b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
204b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
205b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
206e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2077116da1efe23f90eb22524ac9aa036153b74f482Mike Stump
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::Type *Ty =
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
210e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                                   FPT->isVariadic());
211b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *This;
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
213774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  if (ME->isArrow())
214b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = EmitScalarExpr(ME->getBase());
215774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  else {
216774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    LValue BaseLV = EmitLValue(ME->getBase());
217b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = BaseLV.getAddress();
218774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  }
219f0070dbae9535836ad41711081465dec2259786bMike Stump
220bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor  // C++ [class.virtual]p12:
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  //   Explicit qualification with the scope operator (5.1) suppresses the
222bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor  //   virtual call mechanism.
223f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::Value *Callee;
2240979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor  if (MD->isVirtual() && !ME->hasQualifier())
225f0070dbae9535836ad41711081465dec2259786bMike Stump    Callee = BuildVirtualCall(MD, This, Ty);
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  else if (const CXXDestructorDecl *Destructor
2274fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor             = dyn_cast<CXXDestructorDecl>(MD))
2284fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor    Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
2290979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor  else
230555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson    Callee = CGM.GetAddrOfFunction(MD, Ty);
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return EmitCXXMemberCall(MD, Callee, This,
233b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                           CE->arg_begin(), CE->arg_end());
234774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson}
2355f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2361eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue
2370f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
2380f294632f36459174199b77699e339715244b5abAnders Carlsson                                               const CXXMethodDecl *MD) {
2391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(MD->isInstance() &&
2400f294632f36459174199b77699e339715244b5abAnders Carlsson         "Trying to emit a member call expr on a static method!");
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
242ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian  if (MD->isCopyAssignment()) {
243ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
244ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    if (ClassDecl->hasTrivialCopyAssignment()) {
245ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
246ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian             "EmitCXXOperatorMemberCallExpr - user declared copy assignment");
247ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
248ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
249ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      QualType Ty = E->getType();
250ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
251ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      return RValue::get(This);
252ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    }
253ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian  }
2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2550f294632f36459174199b77699e339715244b5abAnders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::Type *Ty =
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
258ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                   FPT->isVariadic());
259555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2610f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2630f294632f36459174199b77699e339715244b5abAnders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
2640f294632f36459174199b77699e339715244b5abAnders Carlsson                           E->arg_begin() + 1, E->arg_end());
2650f294632f36459174199b77699e339715244b5abAnders Carlsson}
2660f294632f36459174199b77699e339715244b5abAnders Carlsson
2675f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
2695f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2705f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
2715f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2735f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
274f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ans: See how CodeGenFunction::LoadObjCSelf() uses
275f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // CodeGenFunction::BlockForwardSelf() for how to do this.
2765f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
2775f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
27895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
279288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
280288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// for-loop to call the default constructor on individual members of the
281288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. 'Array' is the array type, 'This' is llvm pointer of the start
282288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// of the array and 'D' is the default costructor Decl for elements of the
283288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. It is assumed that all relevant checks have been made by the
284288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// caller.
285288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanianvoid
286288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz JahanianCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
287288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            const ArrayType *Array,
288288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            llvm::Value *This) {
289288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
290288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  assert(CA && "Do we support VLA for construction ?");
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
292288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
2930de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
294288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                           "loop.index");
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value* zeroConstant =
2960de78998e7bda473b408437053e48661b510d453Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
297288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
299288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Start the loop with a block that tests the condition.
300288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
301288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
303288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(CondBlock);
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
305288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
307288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
308288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // otherwise, go to the block after the for-loop.
3094f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value * NumElementsPtr =
3114f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
312288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
314288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                              "isless");
315288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // If the condition is true, execute the body.
316288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ForBody);
3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
320288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
321288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
322995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
3234f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
3244f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0);
3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
326288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ContinueBlock);
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
328288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the increment of the loop counter.
329288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
330288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
331288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
332288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
334288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
335288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBranch(CondBlock);
3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
337288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the fall-through block.
338288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(AfterFor, true);
339288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian}
340288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
3411c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// EmitCXXAggrDestructorCall - calls the default destructor on array
3421c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// elements in reverse order of construction.
343b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
344f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz JahanianCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
345f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           const ArrayType *Array,
346f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           llvm::Value *This) {
3471c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
3481c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  assert(CA && "Do we support VLA for destruction ?");
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
3501c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            1);
3510de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
3521c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Create a temporary for the loop index and initialize it with count of
3531c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // array elements.
3541c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
3551c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                           "loop.index");
3561c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Index = ElementCount;
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value* UpperCount =
3581c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
3591c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(UpperCount, IndexPtr, false);
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3611c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Start the loop with a block that tests the condition.
3621c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
3631c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3651c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(CondBlock);
3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3671c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3691c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Generate: if (loop-index != 0 fall to the loop body,
3701c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // otherwise, go to the block after the for-loop.
3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value* zeroConstant =
3721c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
3731c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
3741c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
3751c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            "isne");
3761c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // If the condition is true, execute the body.
3771c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3791c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ForBody);
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3811c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
3821c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
3831c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
3841c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One);
3851c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
3861c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitCXXDestructorCall(D, Dtor_Complete, Address);
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3881c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ContinueBlock);
3891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3901c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the decrement of the loop counter.
3911c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
3921c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One, "dec");
3931c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(Counter, IndexPtr, false);
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3951c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
3961c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBranch(CondBlock);
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3981c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the fall-through block.
3991c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(AfterFor, true);
400f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian}
401f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian
402f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanianvoid
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                        CXXCtorType Type,
405b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
406b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
407b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
408343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  if (D->isCopyConstructor(getContext())) {
409343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
410343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    if (ClassDecl->hasTrivialCopyConstructor()) {
411343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
412343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian             "EmitCXXConstructorCall - user declared copy constructor");
413343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      const Expr *E = (*ArgBeg);
414343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      QualType Ty = E->getType();
415343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      llvm::Value *Src = EmitLValue(E).getAddress();
416343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
417343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      return;
418343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    }
419343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  }
4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
421b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
422b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
423b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
424b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
425b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
4277267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
4287267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
4297267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4317267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
4327267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
4337267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid
4351eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
43631ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
437b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const CXXRecordDecl *RD =
4406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
441b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
442b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
4436904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Code gen optimization to eliminate copy constructor and return
4456904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
44692f5822df6a0d7571df44b5d279ed4f017fbb0e6Anders Carlsson  if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
4476904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
4481cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
4491cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
4506904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
451b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
453b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
454b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
455b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
456a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
457ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
458ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
45903e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
460ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
462ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
463ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
464ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
466ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
467ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
468ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
469ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *AllocSize =
4711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::ConstantInt::get(ConvertType(SizeTy),
472ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
473ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
474ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
476ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
477ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
478ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
479ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
480ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
481ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
482ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
483ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
484ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
486ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump           getTypePtr() ==
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
489ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
492ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
494ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Either we've emitted all the call args, or we have a call to a
497ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
499ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
501ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
503ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
504ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
505ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
506ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
507ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
508ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
509ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue RV =
511ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
512555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson             CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD);
513ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
514d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
515d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
516d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
517d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
518d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
519d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
520ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
521f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
522f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
523f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
524f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
525f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
526f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
527d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
528f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
529f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
530f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *IsNull =
5331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Builder.CreateICmpEQ(NewPtr,
534c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
535f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
537f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
538f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
539d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
541f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5436d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
544215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      assert(E->getNumConstructorArgs() == 1 &&
5466d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
5476d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
5486d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (!hasAggregateLLVMType(AllocType))
5516d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
5523923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
5533923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
554627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
555627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
5566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
557d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Call the constructor.
559d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
5621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                           E->constructor_arg_begin(),
563d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
564ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
565d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
566f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
567f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
568f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
569f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
570f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
572f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
573f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
574f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
575c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
577f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
578f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
580d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
581a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
582a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
58360e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
58460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (E->isArrayForm()) {
58560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    ErrorUnsupported(E, "delete[] expression");
58660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    return;
58760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  };
58860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
5891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  QualType DeleteTy =
59060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Null check the pointer.
59560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
59660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
59760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *IsNull =
59960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
60060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                         "isnull");
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
60360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteNotNull);
6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call the destructor if necessary.
60660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
60760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
60860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      if (!RD->hasTrivialDestructor()) {
60960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
61060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        if (Dtor->isVirtual()) {
61160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          ErrorUnsupported(E, "delete expression with virtual destructor");
61260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          return;
61360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        }
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
61660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      }
61760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    }
61860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  }
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call delete.
62160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  FunctionDecl *DeleteFD = E->getOperatorDelete();
6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const FunctionProtoType *DeleteFTy =
62360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    DeleteFD->getType()->getAsFunctionProtoType();
6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  CallArgList DeleteArgs;
62660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
62760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType ArgTy = DeleteFTy->getArgType(0);
62860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
62960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Emit the call to delete.
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
63360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                                          DeleteArgs),
634555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson           CGM.GetAddrOfFunction(DeleteFD),
63560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           DeleteArgs, DeleteFD);
6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteEnd);
63860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson}
63960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
64095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
6412a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
6422a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
64395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
644363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
64627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
6471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
6491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6500ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
65327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
65427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
65527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
656363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
6571eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
658363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
659363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
660363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
662363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
663b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
664b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
665363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
66627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
66827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
66927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
67027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
67127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
6721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
67427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
67527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
67627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
67727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
67827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
67927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
68027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
68127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
68327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
68427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
6851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6860ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
68927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
69027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
69127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
69227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
6931eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
69427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
69527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
69627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
6971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
699b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
700b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
70127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
70227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
70427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
70527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
70627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
70727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
7081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
71027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
71127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
712e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
71332f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
714738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
7150032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
716cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
717738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
718738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
719cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
720738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
721738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
722738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
723738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
724e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
725738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
726738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
727738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
728738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
7294ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti descriptor");
730738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
731738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
7324ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti ts");
733738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
734738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
735738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
736738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
737738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
738738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
73932f3701853a8237704065c77abc17369dd02c39bMike Stump  Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C,
7407765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                  Out.str());
741cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
742cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
743738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
744738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
745eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stumpclass VtableBuilder {
746f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
747f0070dbae9535836ad41711081465dec2259786bMike Stump  /// Index_t - Vtable index type.
748f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef uint64_t Index_t;
749f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate:
7507c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  std::vector<llvm::Constant *> &methods;
75115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  std::vector<llvm::Constant *> submethods;
7527c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::Type *Ptr8Ty;
753b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Class - The most derived class that this vtable is being built for.
75432f3701853a8237704065c77abc17369dd02c39bMike Stump  const CXXRecordDecl *Class;
755b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// BLayout - Layout for the most derived class that this vtable is being
756b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// built for.
757b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  const ASTRecordLayout &BLayout;
758ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
7597fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
76032f3701853a8237704065c77abc17369dd02c39bMike Stump  llvm::Constant *rtti;
7617c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::LLVMContext &VMContext;
76265defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  CodeGenModule &CGM;  // Per-module state.
763b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Index - Maps a method decl into a vtable index.  Useful for virtual
764b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// dispatch codegen.
765f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
76615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
76715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
7686e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  typedef std::pair<Index_t, Index_t>  CallOffset;
7696e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t;
77077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  Thunks_t Thunks;
7716e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  typedef llvm::DenseMap<const CXXMethodDecl *,
7726e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                         std::pair<CallOffset, CallOffset> > CovariantThunks_t;
7736e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  CovariantThunks_t CovariantThunks;
77415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  std::vector<Index_t> VCalls;
775552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump  typedef CXXRecordDecl::method_iterator method_iter;
776ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // FIXME: Linkage should follow vtable
777ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const bool Extern;
77877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  const uint32_t LLVMPointerWidth;
77977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  Index_t extra;
7807c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic:
781eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder(std::vector<llvm::Constant *> &meth,
782eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                const CXXRecordDecl *c,
783eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                CodeGenModule &cgm)
784b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
785b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
78677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      CGM(cgm), Extern(true),
78777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
7887c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
7897c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  }
79032f3701853a8237704065c77abc17369dd02c39bMike Stump
791f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
792b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
79315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::Constant *wrap(Index_t i) {
7947c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    llvm::Constant *m;
79515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i);
79615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
79715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  }
7987c435fa7f7666b22abbe8494c537ebc25209223dMike Stump
79915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::Constant *wrap(llvm::Constant *m) {
80015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    return llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
80180a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump  }
8024c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump
8037fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
804b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump                            const CXXRecordDecl *RD, uint64_t Offset) {
8057fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
8067fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump           e = RD->bases_end(); i != e; ++i) {
8071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const CXXRecordDecl *Base =
8087fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
8097fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      if (i->isVirtual() && !SeenVBase.count(Base)) {
8107fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        SeenVBase.insert(Base);
811b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
81215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        llvm::Constant *m = wrap(BaseOffset);
81315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        m = wrap((0?700:0) + BaseOffset);
8147fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        offsets.push_back(m);
8157fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      }
816b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, Base, Offset);
8177fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    }
8187fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  }
8197fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump
820b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void StartNewTable() {
821b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    SeenVBase.clear();
822b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
82365defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump
82435191b61db617aefba43b8add88a2ec88af67592Mike Stump  bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
825dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                      bool MorallyVirtual, Index_t Offset) {
826b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    typedef CXXMethodDecl::method_iterator meth_iter;
827b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
828b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // FIXME: Don't like the nested loops.  For very large inheritance
829b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // heirarchies we could have a table on the side with the final overridder
830b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // and just replace each instance of an overridden method once.  Would be
831b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // nice to measure the cost/benefit on real code.
832b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
833b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (meth_iter mi = MD->begin_overridden_methods(),
834b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump           e = MD->end_overridden_methods();
835b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         mi != e; ++mi) {
836b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      const CXXMethodDecl *OMD = *mi;
837b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      llvm::Constant *om;
838555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson      om = CGM.GetAddrOfFunction(OMD, Ptr8Ty);
839b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty);
840b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
841dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      for (Index_t i = 0, e = submethods.size();
842f0070dbae9535836ad41711081465dec2259786bMike Stump           i != e; ++i) {
843b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        // FIXME: begin_overridden_methods might be too lax, covariance */
84477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (submethods[i] != om)
84577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          continue;
8466e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        QualType nc_oret = OMD->getType()->getAsFunctionType()->getResultType();
8476e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        CanQualType oret = CGM.getContext().getCanonicalType(nc_oret);
8486e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        QualType nc_ret = MD->getType()->getAsFunctionType()->getResultType();
8496e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        CanQualType ret = CGM.getContext().getCanonicalType(nc_ret);
8506e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        CallOffset ReturnOffset = std::make_pair(0, 0);
8516e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        if (oret != ret) {
8526e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          // FIXME: calculate offsets for covariance
8536e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          ReturnOffset = std::make_pair(42,42);
8546e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump        }
855dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        Index[MD] = i;
85677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        submethods[i] = m;
85777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
85877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        Thunks.erase(OMD);
85977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (MorallyVirtual) {
86077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          Index_t &idx = VCall[OMD];
86177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          if (idx == 0) {
862dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump            VCallOffset[MD] = Offset/8;
86377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump            idx = VCalls.size()+1;
86477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump            VCalls.push_back(0);
865dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump          } else {
866dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump            VCallOffset[MD] = VCallOffset[OMD];
867dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump            VCalls[idx-1] = -VCallOffset[OMD] + Offset/8;
86815a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump          }
86977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          VCall[MD] = idx;
8706e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          CallOffset ThisOffset;
8716e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          // FIXME: calculate non-virtual offset
8726e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          ThisOffset = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8));
8736e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          if (ReturnOffset.first || ReturnOffset.second)
8746e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump            CovariantThunks[MD] = std::make_pair(ThisOffset, ReturnOffset);
8756e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump          else
8766e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump            Thunks[MD] = ThisOffset;
87735191b61db617aefba43b8add88a2ec88af67592Mike Stump          return true;
878b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        }
87977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#if 0
88077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        // FIXME: finish off
88177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        int64_t O = VCallOffset[OMD] - Offset/8;
88277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (O) {
88377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          Thunks[MD] = std::make_pair(O, 0);
88477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        }
88577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#endif
88677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        return true;
88765defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      }
888bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump    }
889b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
89035191b61db617aefba43b8add88a2ec88af67592Mike Stump    return false;
89135191b61db617aefba43b8add88a2ec88af67592Mike Stump  }
89235191b61db617aefba43b8add88a2ec88af67592Mike Stump
89398cc71003d385561224e3711cd34c5b03f27ccdcMike Stump  void InstallThunks() {
89477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
89577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump         i != e; ++i) {
89677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      const CXXMethodDecl *MD = i->first;
89777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t idx = Index[MD];
89877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t nv_O = i->second.first;
89977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t v_O = i->second.second;
90098cc71003d385561224e3711cd34c5b03f27ccdcMike Stump      submethods[idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
90177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    }
90277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    Thunks.clear();
9036e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    for (CovariantThunks_t::iterator i = CovariantThunks.begin(),
9046e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump           e = CovariantThunks.end();
9056e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump         i != e; ++i) {
9066e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      const CXXMethodDecl *MD = i->first;
9076e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      Index_t idx = Index[MD];
9086e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      Index_t nv_t = i->second.first.first;
9096e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      Index_t v_t = i->second.first.second;
9106e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      Index_t nv_r = i->second.second.first;
9116e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      Index_t v_r = i->second.second.second;
9126e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump      submethods[idx] = CGM.BuildCovariantThunk(MD, Extern, nv_t, v_t, nv_r,
9136e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                v_r);
9146e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    }
9156e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    CovariantThunks.clear();
91677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  }
91777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
918dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump  void OverrideMethods(std::vector<std::pair<const CXXRecordDecl *,
919dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                       int64_t> > *Path, bool MorallyVirtual) {
920dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      for (std::vector<std::pair<const CXXRecordDecl *,
921dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump             int64_t> >::reverse_iterator i =Path->rbegin(),
92298cc71003d385561224e3711cd34c5b03f27ccdcMike Stump           e = Path->rend(); i != e; ++i) {
923dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      const CXXRecordDecl *RD = i->first;
924dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      int64_t Offset = i->second;
92598cc71003d385561224e3711cd34c5b03f27ccdcMike Stump      for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
92698cc71003d385561224e3711cd34c5b03f27ccdcMike Stump           ++mi)
92798cc71003d385561224e3711cd34c5b03f27ccdcMike Stump        if (mi->isVirtual()) {
92898cc71003d385561224e3711cd34c5b03f27ccdcMike Stump          const CXXMethodDecl *MD = *mi;
929c7cba15f5fd86b96c03c57a1d307dde468f7399bAnders Carlsson          llvm::Constant *m = wrap(CGM.GetAddrOfFunction(MD));
930dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump          OverrideMethod(MD, m, MorallyVirtual, Offset);
93198cc71003d385561224e3711cd34c5b03f27ccdcMike Stump        }
93298cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    }
933f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump  }
934f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump
9356d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual, Index_t Offset) {
936c7cba15f5fd86b96c03c57a1d307dde468f7399bAnders Carlsson    llvm::Constant *m = 0;
9373fec4c605e0dd074422bca21626c036f52dab31dAnders Carlsson    if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD))
938c7cba15f5fd86b96c03c57a1d307dde468f7399bAnders Carlsson      m = wrap(CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete));
9393fec4c605e0dd074422bca21626c036f52dab31dAnders Carlsson    else
940c7cba15f5fd86b96c03c57a1d307dde468f7399bAnders Carlsson      m = wrap(CGM.GetAddrOfFunction(MD));
9413fec4c605e0dd074422bca21626c036f52dab31dAnders Carlsson
94277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    // If we can find a previously allocated slot for this, reuse it.
943dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump    if (OverrideMethod(MD, m, MorallyVirtual, Offset))
94435191b61db617aefba43b8add88a2ec88af67592Mike Stump      return;
9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
946b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // else allocate a new slot.
94715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    Index[MD] = submethods.size();
948dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump    submethods.push_back(m);
94915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    if (MorallyVirtual) {
95015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      VCallOffset[MD] = Offset/8;
95115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      Index_t &idx = VCall[MD];
95215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      // Allocate the first one, after that, we reuse the previous one.
95315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      if (idx == 0) {
95415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        idx = VCalls.size()+1;
95515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        VCalls.push_back(0);
95615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      }
95715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    }
958b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
959b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
9606d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
9616d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump                  Index_t Offset) {
962b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
963b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         ++mi)
964b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      if (mi->isVirtual())
9656d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        AddMethod(*mi, MorallyVirtual, Offset);
966bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump  }
967bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump
96877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
96977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       const CXXRecordDecl *PrimaryBase,
97077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       bool PrimaryBaseWasVirtual, bool MorallyVirtual,
97177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       int64_t Offset) {
97277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
97377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump           e = RD->bases_end(); i != e; ++i) {
97477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      if (i->isVirtual())
97577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        continue;
9761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const CXXRecordDecl *Base =
97777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
97877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
97977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
98077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        StartNewTable();
981dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        std::vector<std::pair<const CXXRecordDecl *,
982dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump          int64_t> > S;
983dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        S.push_back(std::make_pair(RD, Offset));
98498cc71003d385561224e3711cd34c5b03f27ccdcMike Stump        GenerateVtableForBase(Base, MorallyVirtual, o, false, &S);
98577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      }
98677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    }
98777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  }
98877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
9896d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant *> &offsets,
9906d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              const ASTRecordLayout &Layout,
9916d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              const CXXRecordDecl *PrimaryBase,
9926d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              bool PrimaryBaseWasVirtual, bool MorallyVirtual,
9936d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              int64_t Offset, bool ForVirtualBase) {
9946d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    StartNewTable();
9956d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    extra = 0;
9966d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // FIXME: Cleanup.
9976d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    if (!ForVirtualBase) {
9986d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      // then virtual base offsets...
9996d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
10006d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump             e = offsets.rend(); i != e; ++i)
10016d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        methods.push_back(*i);
10026d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    }
10036d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10046d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // The vcalls come first...
1005dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump    for (std::vector<Index_t>::reverse_iterator i=VCalls.rbegin(),
1006dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump           e=VCalls.rend();
1007dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump         i != e; ++i)
10086d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      methods.push_back(wrap((0?600:0) + *i));
10096d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    VCalls.clear();
10106d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10116d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    if (ForVirtualBase) {
10126d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      // then virtual base offsets...
10136d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
10146d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump             e = offsets.rend(); i != e; ++i)
10156d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        methods.push_back(*i);
10166d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    }
10176d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10186d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.push_back(wrap(-(Offset/8)));
10196d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.push_back(rtti);
10206d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    Index_t AddressPoint = methods.size();
10216d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
102298cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    InstallThunks();
10236d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.insert(methods.end(), submethods.begin(), submethods.end());
10246d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    submethods.clear();
10256d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10266d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // and then the non-virtual bases.
10276d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
10286d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump                    MorallyVirtual, Offset);
10296d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    return AddressPoint;
10306d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  }
10316d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
1032078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump  void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset) {
10339bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    if (!RD->isDynamicClass())
10349bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump      return;
10359bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10369bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
10371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
10389bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
10399bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10409bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    // vtables are composed from the chain of primaries.
10419bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    if (PrimaryBase) {
10429bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump      if (PrimaryBaseWasVirtual)
10439bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump        IndirectPrimary.insert(PrimaryBase);
1044078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump      Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset);
10459bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    }
10469bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10479bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    // And add the virtuals for the class to the primary vtable.
10489bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    AddMethods(RD, MorallyVirtual, Offset);
10499bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump  }
10509bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
1051e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump  int64_t GenerateVtableForBase(const CXXRecordDecl *RD,
1052a18df0ec71c5c95fb6809d4a80050f7b218f38b5Mike Stump                                bool MorallyVirtual = false, int64_t Offset = 0,
1053a18df0ec71c5c95fb6809d4a80050f7b218f38b5Mike Stump                                bool ForVirtualBase = false,
1054dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                                std::vector<std::pair<const CXXRecordDecl *,
1055dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                                int64_t> > *Path = 0) {
1056bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump    if (!RD->isDynamicClass())
1057263b3522add846130ff5f0a85568234e612a81caMike Stump      return 0;
1058109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1059109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
10601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1061109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1062109b13db3391face0b393c730f0326ca51d25b52Mike Stump
106315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    std::vector<llvm::Constant *> offsets;
1064b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    extra = 0;
1065b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    GenerateVBaseOffsets(offsets, RD, Offset);
1066b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    if (ForVirtualBase)
1067b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump      extra = offsets.size();
106802cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
1069109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // vtables are composed from the chain of primaries.
1070109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (PrimaryBase) {
1071109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (PrimaryBaseWasVirtual)
1072109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(PrimaryBase);
1073078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump      Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset);
1074109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1075276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
107615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    // And add the virtuals for the class to the primary vtable.
10776d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    AddMethods(RD, MorallyVirtual, Offset);
107815a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump
107998cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    if (Path)
1080dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      OverrideMethods(Path, MorallyVirtual);
108198cc71003d385561224e3711cd34c5b03f27ccdcMike Stump
10826d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual,
10836d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump               MorallyVirtual, Offset, ForVirtualBase);
1084276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
1085276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
108698cc71003d385561224e3711cd34c5b03f27ccdcMike Stump  void GenerateVtableForVBases(const CXXRecordDecl *RD,
1087dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                               int64_t Offset = 0,
1088dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                               std::vector<std::pair<const CXXRecordDecl *,
1089dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump                               int64_t> > *Path = 0) {
109098cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    bool alloc = false;
109198cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    if (Path == 0) {
109298cc71003d385561224e3711cd34c5b03f27ccdcMike Stump      alloc = true;
1093dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      Path = new std::vector<std::pair<const CXXRecordDecl *,
1094dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        int64_t> >;
109598cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    }
109698cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    // FIXME: We also need to override using all paths to a virtual base,
109798cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    // right now, we just process the first path
1098dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump    Path->push_back(std::make_pair(RD, Offset));
1099109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1100109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
11011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const CXXRecordDecl *Base =
1102109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1103109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !IndirectPrimary.count(Base)) {
1104109b13db3391face0b393c730f0326ca51d25b52Mike Stump        // Mark it so we don't output it twice.
1105109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(Base);
1106b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1107b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
110898cc71003d385561224e3711cd34c5b03f27ccdcMike Stump        GenerateVtableForBase(Base, true, BaseOffset, true, Path);
1109109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1110dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      int64_t BaseOffset = Offset;
1111dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump      if (i->isVirtual())
1112dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        BaseOffset = BLayout.getVBaseClassOffset(Base);
1113109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base->getNumVBases())
1114dec025b15c63e0353768e402ad1fd566d97d2be7Mike Stump        GenerateVtableForVBases(Base, BaseOffset, Path);
1115109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
111698cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    Path->pop_back();
111798cc71003d385561224e3711cd34c5b03f27ccdcMike Stump    if (alloc)
111898cc71003d385561224e3711cd34c5b03f27ccdcMike Stump      delete Path;
1119e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
1120109b13db3391face0b393c730f0326ca51d25b52Mike Stump};
11218a12b564923a72224730a467007e61b5701e4aa7Mike Stump
1122f0070dbae9535836ad41711081465dec2259786bMike Stumpclass VtableInfo {
1123f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
1124f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef VtableBuilder::Index_t Index_t;
1125f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate:
1126f0070dbae9535836ad41711081465dec2259786bMike Stump  CodeGenModule &CGM;  // Per-module state.
1127f0070dbae9535836ad41711081465dec2259786bMike Stump  /// Index_t - Vtable index type.
1128f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef llvm::DenseMap<const CXXMethodDecl *, Index_t> ElTy;
1129f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy;
1130f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: Move to Context.
1131f0070dbae9535836ad41711081465dec2259786bMike Stump  static MapTy IndexFor;
1132f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
1133f0070dbae9535836ad41711081465dec2259786bMike Stump  VtableInfo(CodeGenModule &cgm) : CGM(cgm) { }
1134f0070dbae9535836ad41711081465dec2259786bMike Stump  void register_index(const CXXRecordDecl *RD, const ElTy &e) {
1135f0070dbae9535836ad41711081465dec2259786bMike Stump    assert(IndexFor.find(RD) == IndexFor.end() && "Don't compute vtbl twice");
1136f0070dbae9535836ad41711081465dec2259786bMike Stump    // We own a copy of this, it will go away shortly.
1137f0070dbae9535836ad41711081465dec2259786bMike Stump    new ElTy (e);
1138f0070dbae9535836ad41711081465dec2259786bMike Stump    IndexFor[RD] = new ElTy (e);
1139f0070dbae9535836ad41711081465dec2259786bMike Stump  }
1140f0070dbae9535836ad41711081465dec2259786bMike Stump  Index_t lookup(const CXXMethodDecl *MD) {
1141f0070dbae9535836ad41711081465dec2259786bMike Stump    const CXXRecordDecl *RD = MD->getParent();
1142f0070dbae9535836ad41711081465dec2259786bMike Stump    MapTy::iterator I = IndexFor.find(RD);
1143f0070dbae9535836ad41711081465dec2259786bMike Stump    if (I == IndexFor.end()) {
1144f0070dbae9535836ad41711081465dec2259786bMike Stump      std::vector<llvm::Constant *> methods;
1145f0070dbae9535836ad41711081465dec2259786bMike Stump      VtableBuilder b(methods, RD, CGM);
1146a18df0ec71c5c95fb6809d4a80050f7b218f38b5Mike Stump      b.GenerateVtableForBase(RD);
1147bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump      b.GenerateVtableForVBases(RD);
1148f0070dbae9535836ad41711081465dec2259786bMike Stump      register_index(RD, b.getIndex());
1149f0070dbae9535836ad41711081465dec2259786bMike Stump      I = IndexFor.find(RD);
1150f0070dbae9535836ad41711081465dec2259786bMike Stump    }
1151f0070dbae9535836ad41711081465dec2259786bMike Stump    assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index");
1152f0070dbae9535836ad41711081465dec2259786bMike Stump    return (*I->second)[MD];
1153f0070dbae9535836ad41711081465dec2259786bMike Stump  }
1154f0070dbae9535836ad41711081465dec2259786bMike Stump};
1155f0070dbae9535836ad41711081465dec2259786bMike Stump
1156f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: Move to Context.
1157f0070dbae9535836ad41711081465dec2259786bMike StumpVtableInfo::MapTy VtableInfo::IndexFor;
1158f0070dbae9535836ad41711081465dec2259786bMike Stump
1159f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
1160f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
1161f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
1162f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
1163e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
1164f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
116582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
116682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
116782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
1168276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
116998cc71003d385561224e3711cd34c5b03f27ccdcMike Stump  int64_t AddressPoint;
11706f376336138ea719e3c4757ae046a5768043b276Mike Stump
1171eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder b(methods, RD, CGM);
1172109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1173276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // First comes the vtables for all the non-virtual bases...
117498cc71003d385561224e3711cd34c5b03f27ccdcMike Stump  AddressPoint = b.GenerateVtableForBase(RD);
117570101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
1176276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // then the vtables for all the virtual bases.
1177bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump  b.GenerateVtableForVBases(RD);
11786f376336138ea719e3c4757ae046a5768043b276Mike Stump
117982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
118082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
118182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
118282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
11837765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                                 linktype, C, Out.str());
1184f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
1185f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
1186276b9f1d814f4f6551cc3000590759a34185d6daMike Stump                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
118798cc71003d385561224e3711cd34c5b03f27ccdcMike Stump                                              AddressPoint*LLVMPointerWidth/8));
1188f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
1189f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
1190f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
1191f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: move to Context
1192f0070dbae9535836ad41711081465dec2259786bMike Stumpstatic VtableInfo *vtableinfo;
1193f0070dbae9535836ad41711081465dec2259786bMike Stump
1194ed032eb5c18b99528cbd76415337b6056a72b911Mike Stumpllvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
1195ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                               const CXXMethodDecl *MD,
119677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                               bool Extern, int64_t nv,
119777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                               int64_t v) {
1198ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  QualType R = MD->getType()->getAsFunctionType()->getResultType();
1199ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
1200ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FunctionArgList Args;
1201ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  ImplicitParamDecl *ThisDecl =
1202ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
1203ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                              MD->getThisType(getContext()));
1204ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType()));
1205ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  for (FunctionDecl::param_const_iterator i = MD->param_begin(),
1206ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump         e = MD->param_end();
1207ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump       i != e; ++i) {
1208ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    ParmVarDecl *D = *i;
1209ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    Args.push_back(std::make_pair(D, D->getType()));
1210ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  }
1211ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  IdentifierInfo *II
1212ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    = &CGM.getContext().Idents.get("__thunk_named_foo_");
1213ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FunctionDecl *FD = FunctionDecl::Create(getContext(),
1214ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          getContext().getTranslationUnitDecl(),
1215ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          SourceLocation(), II, R, 0,
1216ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          Extern
1217ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                            ? FunctionDecl::Extern
1218ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                            : FunctionDecl::Static,
1219ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          false, true);
1220ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  StartFunction(FD, R, Fn, Args, SourceLocation());
1221ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // FIXME: generate body
1222ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FinishFunction();
1223ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  return Fn;
1224ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump}
1225ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
12266e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stumpllvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
12276e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        const CXXMethodDecl *MD,
12286e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        bool Extern,
12296e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        int64_t nv_t,
12306e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        int64_t v_t,
12316e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        int64_t nv_r,
12326e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                        int64_t v_r) {
12336e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  QualType R = MD->getType()->getAsFunctionType()->getResultType();
12346e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump
12356e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  FunctionArgList Args;
12366e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  ImplicitParamDecl *ThisDecl =
12376e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
12386e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                              MD->getThisType(getContext()));
12396e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType()));
12406e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  for (FunctionDecl::param_const_iterator i = MD->param_begin(),
12416e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump         e = MD->param_end();
12426e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump       i != e; ++i) {
12436e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    ParmVarDecl *D = *i;
12446e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    Args.push_back(std::make_pair(D, D->getType()));
12456e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  }
12466e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  IdentifierInfo *II
12476e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    = &CGM.getContext().Idents.get("__thunk_named_foo_");
12486e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  FunctionDecl *FD = FunctionDecl::Create(getContext(),
12496e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                          getContext().getTranslationUnitDecl(),
12506e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                          SourceLocation(), II, R, 0,
12516e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                          Extern
12526e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                            ? FunctionDecl::Extern
12536e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                            : FunctionDecl::Static,
12546e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                          false, true);
12556e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  StartFunction(FD, R, Fn, Args, SourceLocation());
12566e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  // FIXME: generate body
12576e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  FinishFunction();
12586e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  return Fn;
12596e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump}
12606e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump
126177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stumpllvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
126277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                          int64_t nv, int64_t v) {
1263ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::SmallString<256> OutName;
1264ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::raw_svector_ostream Out(OutName);
126577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  mangleThunk(MD, nv, v, getContext(), Out);
1266ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
1267ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
1268ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  if (!Extern)
1269ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    linktype = llvm::GlobalValue::InternalLinkage;
1270ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
1271ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1272ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const llvm::FunctionType *FTy =
1273ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
1274ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                               FPT->isVariadic());
1275ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
1276ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(),
1277ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                              &getModule());
127877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v);
1279ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // Fn = Builder.CreateBitCast(Fn, Ptr8Ty);
1280ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
1281ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  return m;
1282ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump}
1283ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
12846e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stumpllvm::Constant *CodeGenModule::BuildCovariantThunk(const CXXMethodDecl *MD,
12856e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                   bool Extern, int64_t nv_t,
12866e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                   int64_t v_t, int64_t nv_r,
12876e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                                   int64_t v_r) {
12886e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::SmallString<256> OutName;
12896e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::raw_svector_ostream Out(OutName);
12906e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  mangleCovariantThunk(MD, nv_t, v_t, nv_r, v_r, getContext(), Out);
12916e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
12926e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
12936e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  if (!Extern)
12946e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    linktype = llvm::GlobalValue::InternalLinkage;
12956e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
12966e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
12976e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  const llvm::FunctionType *FTy =
12986e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
12996e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                               FPT->isVariadic());
13006e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump
13016e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(),
13026e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                              &getModule());
13036e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, nv_t, v_t, nv_r,
13046e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump                                               v_r);
13056e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  // Fn = Builder.CreateBitCast(Fn, Ptr8Ty);
13066e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
13076e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump  return m;
13086e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump}
13096e319f6adc2a06c31cf99265854eef1321bcecf2Mike Stump
1310f0070dbae9535836ad41711081465dec2259786bMike Stumpllvm::Value *
1311f0070dbae9535836ad41711081465dec2259786bMike StumpCodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
1312f0070dbae9535836ad41711081465dec2259786bMike Stump                                  const llvm::Type *Ty) {
1313f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: If we know the dynamic type, we don't have to do a virtual dispatch.
13141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1315f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: move to Context
1316f0070dbae9535836ad41711081465dec2259786bMike Stump  if (vtableinfo == 0)
1317f0070dbae9535836ad41711081465dec2259786bMike Stump    vtableinfo = new VtableInfo(CGM);
1318f0070dbae9535836ad41711081465dec2259786bMike Stump
1319f0070dbae9535836ad41711081465dec2259786bMike Stump  VtableInfo::Index_t Idx = vtableinfo->lookup(MD);
1320f0070dbae9535836ad41711081465dec2259786bMike Stump
1321f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1322f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1323f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1324f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::Value *vtbl = Builder.CreateBitCast(This, Ty);
1325f0070dbae9535836ad41711081465dec2259786bMike Stump  vtbl = Builder.CreateLoad(vtbl);
1326f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::Value *vfn = Builder.CreateConstInBoundsGEP1_64(vtbl,
1327f0070dbae9535836ad41711081465dec2259786bMike Stump                                                        Idx, "vfn");
1328f0070dbae9535836ad41711081465dec2259786bMike Stump  vfn = Builder.CreateLoad(vfn);
1329f0070dbae9535836ad41711081465dec2259786bMike Stump  return vfn;
1330f0070dbae9535836ad41711081465dec2259786bMike Stump}
1331f0070dbae9535836ad41711081465dec2259786bMike Stump
1332eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
1333eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
1334eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// copy or via a copy constructor call.
13354f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian//  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
13361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
1337eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            llvm::Value *Src,
1338eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            const ArrayType *Array,
13391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                            const CXXRecordDecl *BaseClassDecl,
1340eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            QualType Ty) {
1341eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1342eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  assert(CA && "VLA cannot be copied over");
1343eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
13441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1345eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1346eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1347eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                           "loop.index");
13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value* zeroConstant =
1349eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1350eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    Builder.CreateStore(zeroConstant, IndexPtr, false);
1351eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Start the loop with a block that tests the condition.
1352eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1353eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
13541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1355eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(CondBlock);
13561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1357eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1358eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1359eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // otherwise, go to the block after the for-loop.
1360eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
13611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value * NumElementsPtr =
1362eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1363eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
13641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1365eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                              "isless");
1366eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // If the condition is true, execute the body.
1367eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
13681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1369eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ForBody);
1370eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1371eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
1372eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1373eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1374eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1375eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  if (BitwiseCopy)
1376eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
13771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  else if (CXXConstructorDecl *BaseCopyCtor =
1378eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian           BaseClassDecl->getCopyConstructor(getContext(), 0)) {
13791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1380eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                                      Ctor_Complete);
1381eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgList CallArgs;
1382eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the this (Dest) ptr.
1383eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1384eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
13851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1386eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the Src ptr.
1387eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1388eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getParamDecl(0)->getType()));
13891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType ResultType =
1390eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1391eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1392eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1393eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  }
1394eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ContinueBlock);
13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1396eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the increment of the loop counter.
1397eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1398eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1399eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1400eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
14011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1402eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1403eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBranch(CondBlock);
14041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1405eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the fall-through block.
1406eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(AfterFor, true);
1407eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian}
1408eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1409c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
14101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// array of objects from SrcValue to DestValue. Assignment can be either a
1411c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// bitwise assignment or via a copy assignment operator function call.
1412c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
14131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
1414c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            llvm::Value *Src,
1415c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            const ArrayType *Array,
14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                            const CXXRecordDecl *BaseClassDecl,
1417c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            QualType Ty) {
1418c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1419c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  assert(CA && "VLA cannot be asssigned");
1420c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1422c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1423c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1424c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                           "loop.index");
14251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value* zeroConstant =
1426c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1427c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
1428c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Start the loop with a block that tests the condition.
1429c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1430c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
14311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1432c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(CondBlock);
14331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1434c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1435c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1436c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // otherwise, go to the block after the for-loop.
1437c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value * NumElementsPtr =
1439c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1440c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
14411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1442c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                              "isless");
1443c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // If the condition is true, execute the body.
1444c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
14451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1446c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ForBody);
1447c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1448c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Inside the loop body, emit the assignment operator call on array element.
1449c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1450c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1451c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1452c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const CXXMethodDecl *MD = 0;
1453c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  if (BitwiseAssign)
1454c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1455c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  else {
1456c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    bool hasCopyAssign = BaseClassDecl->hasConstCopyAssignment(getContext(),
1457c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                                               MD);
1458c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    assert(hasCopyAssign && "EmitClassAggrCopyAssignment - No user assign");
1459c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    (void)hasCopyAssign;
1460c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1461c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const llvm::Type *LTy =
1462c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1463c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                   FPT->isVariadic());
1464555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson    llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
14651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1466c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgList CallArgs;
1467c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the this (Dest) ptr.
1468c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1469c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getThisType(getContext())));
14701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1471c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the Src ptr.
1472c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1473c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getParamDecl(0)->getType()));
1474ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
1475c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1476c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian             Callee, CallArgs, MD);
1477c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  }
1478c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ContinueBlock);
14791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1480c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the increment of the loop counter.
1481c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1482c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1483c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1484c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
14851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1486c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1487c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBranch(CondBlock);
14881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1489c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the fall-through block.
1490c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(AfterFor, true);
1491c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian}
1492c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1493ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
1494ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
1495eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// or via a copy constructor call.
1496ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
1497942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
14981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        const CXXRecordDecl *ClassDecl,
1499942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
1500942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
15015a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson    Dest = GetAddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl,
15025a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                    /*NullCheckValue=*/false);
15035a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson    Src = GetAddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl,
15045a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                   /*NullCheckValue=*/false);
1505942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1506942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
1507942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1508ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
1509942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
15101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (CXXConstructorDecl *BaseCopyCtor =
151280e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
15131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1514ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
1515ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
1516ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
1517ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1518ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1520ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
1521ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1522370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian                       BaseCopyCtor->getParamDecl(0)->getType()));
15231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    QualType ResultType =
1524ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1525ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1526ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1527ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
1528ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
152906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
15300270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class
15311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// object from SrcValue to DestValue. Assignment can be either a bitwise
15320270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call.
1533c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
15340270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment(
15350270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        llvm::Value *Dest, llvm::Value *Src,
15361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                        const CXXRecordDecl *ClassDecl,
15371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                        const CXXRecordDecl *BaseClassDecl,
15380270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        QualType Ty) {
15390270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (ClassDecl) {
15405a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson    Dest = GetAddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl,
15415a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                    /*NullCheckValue=*/false);
15425a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson    Src = GetAddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl,
15435a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                   /*NullCheckValue=*/false);
15440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
15450270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyAssignment()) {
15460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
15470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    return;
15480270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
15491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXMethodDecl *MD = 0;
15511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(),
1552e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                                                 MD);
1553e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign");
1554e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  (void)ConstCopyAssignOp;
1555e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian
1556e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
15571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const llvm::Type *LTy =
15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1559e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                   FPT->isVariadic());
1560555b4bb2749aea2ec8e2adc351a71ec1cb9bdc33Anders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, LTy);
15611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1562e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgList CallArgs;
1563e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the this (Dest) ptr.
1564e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Dest),
1565e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getThisType(getContext())));
15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1567e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the Src ptr.
1568e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Src),
1569e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getParamDecl(0)->getType()));
15701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  QualType ResultType =
1571e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
1572e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1573e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian           Callee, CallArgs, MD);
15740270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian}
15750270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
157606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor
15771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid
15780ff8bafde95f6fa51ccea70738c1b99db870bddcAnders CarlssonCodeGenFunction::SynthesizeDefaultConstructor(GlobalDecl GD,
157906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionDecl *FD,
158006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              llvm::Function *Fn,
158106f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionArgList &Args) {
15820ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(GD.getDecl());
15830ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson
15840ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  StartFunction(GD, FD->getResultType(), Fn, Args, SourceLocation());
15850ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  EmitCtorPrologue(Ctor);
158606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  FinishFunction();
158706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian}
158806f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
15898c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
159097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
15911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The implicitly-defined copy constructor for class X performs a memberwise
15921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// copy of its subobjects. The order of copying is the same as the order
159397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
159497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
15951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///  if the subobject is of class type, the copy constructor for the class is
159697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
15971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///  if the subobject is an array, each element is copied, in the manner
159897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
15991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///  if the subobject is of scalar type, the built-in assignment operator is
160097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
16011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Virtual base class subobjects shall be copied only once by the
16021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// implicitly-defined copy constructor
160397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
16040ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlssonvoid CodeGenFunction::SynthesizeCXXCopyConstructor(GlobalDecl GD,
16058c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
16068c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
1607ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
16080ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(GD.getDecl());
16090ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  const CXXRecordDecl *ClassDecl = Ctor->getParent();
161097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
16118c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
16120ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  StartFunction(GD, Ctor->getResultType(), Fn, Args, SourceLocation());
16131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16141e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
16151e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
16161e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
16171e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
16181e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
16191e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
16201e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
16211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
162297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
162397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
162497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
162597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
162697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
16271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
162897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
162997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1630942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
1631942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
163297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
16331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16341e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
16351e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
16361e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
16371e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
16381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const ConstantArrayType *Array =
1639eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1640eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    if (Array)
1641eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16431e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
16441e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
16451e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
16461e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
16471e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1648eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      if (Array) {
1649eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1650eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
16511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        llvm::Value *DestBaseAddrPtr =
1652eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
16531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        llvm::Value *SrcBaseAddrPtr =
1654eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1655eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1656eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                    FieldClassDecl, FieldType);
1657eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      }
16581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      else
16591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
1660eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
16611e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
16621e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
1663f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    // Do a built-in assignment of scalar data members.
1664f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1665f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1666f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
1667f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
16681e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
16698c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
16701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
167197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
16722198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
16731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Before the implicitly-declared copy assignment operator for a class is
16741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// implicitly defined, all implicitly- declared copy assignment operators for
16751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// its direct base classes and its nonstatic data members shall have been
16762198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12]
16771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// The implicitly-defined copy assignment operator for class X performs
16781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// memberwise assignment of its subob- jects. The direct base classes of X are
16791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// assigned first, in the order of their declaration in
16801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// the base-specifier-list, and then the immediate nonstatic data members of X
16811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// are assigned, in the order in which they were declared in the class
16822198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type:
16831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   if the subobject is of class type, the copy assignment operator for the
16841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   class is used (as if by explicit qualification; that is, ignoring any
16852198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   possible virtual overriding functions in more derived classes);
16860270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
16871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   if the subobject is an array, each element is assigned, in the manner
16882198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   appropriate to the element type;
16890270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
16901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   if the subobject is of scalar type, the built-in assignment operator is
16912198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   used.
16922198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
16932198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionDecl *FD,
16942198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  llvm::Function *Fn,
16952198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionArgList &Args) {
16960270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
16980270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
16990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
17002198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
17011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17020270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
17030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *ThisArg = i->first;
17040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
17050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
17060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
17070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
17080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
17091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
17110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
17120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
17130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (Base->isVirtual())
17140270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
17151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17160270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
17170270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
17180270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
17190270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                            Base->getType());
17200270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
17211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17220270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
17230270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
17240270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Field != FieldEnd; ++Field) {
17250270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
17261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const ConstantArrayType *Array =
1727c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1728c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    if (Array)
1729c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
17301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17310270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
17320270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      CXXRecordDecl *FieldClassDecl
17330270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(FieldClassType->getDecl());
17340270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
17350270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1736c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      if (Array) {
1737c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1738c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1739c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *DestBaseAddrPtr =
1740c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1741c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *SrcBaseAddrPtr =
1742c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1743c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1744c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                    FieldClassDecl, FieldType);
1745c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      }
1746c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      else
17471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
1748c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
17490270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
17500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    }
17510270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // Do a built-in assignment of scalar data members.
17520270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
17530270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
17540270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
17550270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
1756183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  }
17571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1758183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  // return *this;
1759183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  Builder.CreateStore(LoadOfThis, ReturnValue);
17601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17612198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  FinishFunction();
17621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
176397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
1764e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
1765e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
1766174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXCtorType.
1767e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
1768742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
1769eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
1770f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
17711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1772742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1773e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
1774e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
1775e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
1776e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
1777f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
17786d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
17791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      CXXRecordDecl *BaseClassDecl =
17806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
17815a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson      llvm::Value *V = GetAddressCXXOfBaseClass(LoadOfThis, ClassDecl,
17825a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                BaseClassDecl,
17835a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                /*NullCheckValue=*/false);
1784742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
1785742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
17861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                             Member->const_arg_begin(),
1787742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
1788b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1789e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
1790e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
1791e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
17921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const ConstantArrayType *Array =
1793eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
179464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian      if (Array)
179564a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
17961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1797f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1798e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      LValue LHS;
1799e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      if (FieldType->isReferenceType()) {
1800e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        // FIXME: This is really ugly; should be refactored somehow
1801e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
1802e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        llvm::Value *V = Builder.CreateStructGEP(LoadOfThis, idx, "tmp");
1803e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        LHS = LValue::MakeAddr(V, FieldType.getCVRQualifiers(),
1804e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman                               QualType::GCNone, FieldType.getAddressSpace());
1805e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      } else {
1806e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
1807e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      }
18086217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
1809e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        if (!Field->isAnonymousStructOrUnion()) {
18101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          assert(Member->getConstructor() &&
181150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
181264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          if (Array) {
181364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            const llvm::Type *BasePtr = ConvertType(FieldType);
181464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            BasePtr = llvm::PointerType::getUnqual(BasePtr);
18151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            llvm::Value *BaseAddrPtr =
181664a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
18171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            EmitCXXAggrConstructorCall(Member->getConstructor(),
181864a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                       Array, BaseAddrPtr);
181964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          }
182064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          else
182164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            EmitCXXConstructorCall(Member->getConstructor(),
182264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Ctor_Complete, LHS.getAddress(),
18231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                   Member->const_arg_begin(),
182464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Member->const_arg_end());
1825e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          continue;
1826e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
1827e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        else {
1828e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          // Initializing an anonymous union data member.
1829e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldDecl *anonMember = Member->getAnonUnionMember();
18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          LHS = EmitLValueForField(LHS.getAddress(), anonMember,
1831c186b8fe4a308b53569fe839a3224de70d92ab0eAnders Carlsson                                   /*IsUnion=*/true, 0);
1832e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldType = anonMember->getType();
1833e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
183450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
18351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1836e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
183750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
1838e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      RValue RHS;
1839e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      if (FieldType->isReferenceType())
1840e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        RHS = EmitReferenceBindingToExpr(RhsExpr, FieldType,
1841e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman                                        /*IsInitializer=*/true);
1842e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      else
1843e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        RHS = RValue::get(EmitScalarExpr(RhsExpr, true));
1844e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      EmitStoreThroughLValue(RHS, LHS, FieldType);
1845e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
1846e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
1847f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
18480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
18491d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    // Nontrivial default constructor with no initializer list. It may still
18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // have bases classes and/or contain non-static data members which require
18510880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // construction.
18521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    for (CXXRecordDecl::base_class_const_iterator Base =
18530880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          ClassDecl->bases_begin();
18540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          Base != ClassDecl->bases_end(); ++Base) {
18550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      // FIXME. copy assignment of virtual base NYI
18560880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (Base->isVirtual())
18570880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18590880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *BaseClassDecl
18600880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
18610880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (BaseClassDecl->hasTrivialConstructor())
18620880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (CXXConstructorDecl *BaseCX =
18640880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            BaseClassDecl->getDefaultConstructor(getContext())) {
18650880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
18665a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson        llvm::Value *V = GetAddressCXXOfBaseClass(LoadOfThis, ClassDecl,
18675a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                  BaseClassDecl,
18685a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                  /*NullCheckValue=*/false);
18690880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
18700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      }
18710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
18721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18731d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
18741d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         FieldEnd = ClassDecl->field_end();
18751d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         Field != FieldEnd; ++Field) {
18761d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((*Field)->getType());
18771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const ConstantArrayType *Array =
1878288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1879f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1880f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
18811d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
18821d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian        continue;
18831d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      const RecordType *ClassRec = FieldType->getAs<RecordType>();
18841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      CXXRecordDecl *MemberClassDecl =
18850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
18860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor())
18870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (CXXConstructorDecl *MamberCX =
18890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            MemberClassDecl->getDefaultConstructor(getContext())) {
18900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
18910880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1892288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        if (Array) {
1893288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          const llvm::Type *BasePtr = ConvertType(FieldType);
1894288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          BasePtr = llvm::PointerType::getUnqual(BasePtr);
18951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          llvm::Value *BaseAddrPtr =
1896288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1897288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr);
1898288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        }
1899288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        else
19001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(),
1901288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                 0, 0);
19021d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      }
19031d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    }
19040880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
19051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1906f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
1907b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
1908f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
1909f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1910f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
1911f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
19120032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1913f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
1914f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
1915f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
1916f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
1917f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
1918e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
1919426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1920426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
19211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// destructor. This is to call destructors on members and base classes
1922426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
1923174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXDtorType.
1924426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
1925426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
1926de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson  assert(!ClassDecl->getNumVBases() &&
1927de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson         "FIXME: Destruction of virtual bases not supported");
1928426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
19291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1930426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
1931426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
1932426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
1933426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
1934426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
1935426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
19361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const ConstantArrayType *Array =
1937f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1938f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1939f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
1940426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
1941426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1942426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
1943426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1944426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
1945426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
1946f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1947f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1948f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
19491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        llvm::Value *BaseAddrPtr =
1950f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
19511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1952f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1953f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1954f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1955f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1956f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
1957b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1958426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
1959426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
1960426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1961426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
1962426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
19635a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson      llvm::Value *V = GetAddressCXXOfBaseClass(LoadCXXThis(),
19645a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                ClassDecl, BaseClassDecl,
19655a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                                /*NullCheckValue=*/false);
1966426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
1967426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
1968426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
1969426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
19700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial())
19710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
19720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // Case of destructor synthesis with fields and base classes
19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // which have non-trivial destructors. They must be destructed in
19740880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // reverse order of their construction.
19750880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<FieldDecl *, 16> DestructedFields;
19761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19770880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
19780880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
19790880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Field != FieldEnd; ++Field) {
19800880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1981f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian    if (getContext().getAsConstantArrayType(FieldType))
1982f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
19830880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (const RecordType *RT = FieldType->getAs<RecordType>()) {
19840880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
19850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
19860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
19870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      DestructedFields.push_back(*Field);
19880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
19890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
19900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!DestructedFields.empty())
19910880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (int i = DestructedFields.size() -1; i >= 0; --i) {
19920880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      FieldDecl *Field = DestructedFields[i];
19930880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      QualType FieldType = Field->getType();
19941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      const ConstantArrayType *Array =
1995f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1996f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        if (Array)
1997f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          FieldType = getContext().getBaseElementType(FieldType);
19980880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
19990880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
20000880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
20010880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
2002f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
2003f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
2004f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        llvm::Value *BaseAddrPtr =
2006f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
20071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
2008f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
2009f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
2010f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
2011f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
2012f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
20130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
20141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
20160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
20170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
20180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
20190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (Base->isVirtual())
20200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
20211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
20230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
20240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (BaseClassDecl->hasTrivialDestructor())
20250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
20260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    DestructedBases.push_back(BaseClassDecl);
20270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
20280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DestructedBases.empty())
20290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
20300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (int i = DestructedBases.size() -1; i >= 0; --i) {
20310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl = DestructedBases[i];
20325a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson    llvm::Value *V = GetAddressCXXOfBaseClass(LoadCXXThis(),
20335a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                              ClassDecl,BaseClassDecl,
20345a0f49ebc83e7fe0da07b9964c44b0a7fae270cbAnders Carlsson                                              /*NullCheckValue=*/false);
20350880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
20360880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                          Dtor_Complete, V);
20370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
2038426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
20390880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
20400ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlssonvoid CodeGenFunction::SynthesizeDefaultDestructor(GlobalDecl GD,
20410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionDecl *FD,
20420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  llvm::Function *Fn,
20430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionArgList &Args) {
20441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20450ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(GD.getDecl());
20460ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson
20470ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  const CXXRecordDecl *ClassDecl = Dtor->getParent();
20480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredDestructor() &&
20490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian         "SynthesizeDefaultDestructor - destructor has user declaration");
20500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  (void) ClassDecl;
20511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20520ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  StartFunction(GD, Dtor->getResultType(), Fn, Args, SourceLocation());
20530ff8bafde95f6fa51ccea70738c1b99db870bddcAnders Carlsson  EmitDtorEpilogue(Dtor);
20540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  FinishFunction();
20551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
2056