CGCXX.cpp revision e45c90f53e3fcb59a48e88862aa5cf5f5538556c
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
14e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// 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
280096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbarvoid
293b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders CarlssonCodeGenFunction::EmitCXXGlobalDtorRegistration(const CXXDestructorDecl *Dtor,
303b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                               llvm::Constant *DeclPtr) {
313b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // FIXME: This is ABI dependent and we use the Itanium ABI.
323b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
333b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  const llvm::Type *Int8PtrTy =
340032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
353b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
363b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  std::vector<const llvm::Type *> Params;
373b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
383b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
393b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // Get the destructor function type
403b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  const llvm::Type *DtorFnTy =
410032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false);
423b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy);
433b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
443b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.clear();
453b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(DtorFnTy);
463b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
473b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  Params.push_back(Int8PtrTy);
483b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
493b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // Get the __cxa_atexit function type
503b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d );
513b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  const llvm::FunctionType *AtExitFnTy =
523b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false);
533b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
543b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy,
553b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                                       "__cxa_atexit");
563b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
573b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy,
583b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                                     "__dso_handle");
593b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
603b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  llvm::Constant *DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
613b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
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
683b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
693b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson                                               llvm::Constant *DeclPtr) {
703b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  assert(D.hasGlobalStorage() &&
713b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson         "VarDecl must have global storage!");
723b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
733b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  const Expr *Init = D.getInit();
743b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson  QualType T = D.getType();
753b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
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());
853b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson
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;
9889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
990032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  const llvm::FunctionType *FTy = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
10089ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                          false);
10189ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
10289ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  // Create our global initialization function.
10389ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  // FIXME: Should this be tweakable by targets?
10489ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  llvm::Function *Fn =
10589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
10689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                           "__cxx_global_initialization", &TheModule);
10789ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
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) {
11789ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  StartFunction(0, getContext().VoidTy, Fn, FunctionArgList(),
11889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                SourceLocation());
11989ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
12089ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  for (unsigned i = 0; i != NumDecls; ++i) {
12189ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    const VarDecl *D = Decls[i];
12289ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
12389ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
12489ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson    EmitCXXGlobalVarDeclInit(*D, DeclPtr);
12589ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  }
12689ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  FinishFunction();
12789ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson}
12889ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson
1293b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlssonvoid
1303b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders CarlssonCodeGenFunction::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);
140283a062a633d6e868aa2be319da812341fe73728Anders Carlsson
141e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
142e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  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());
147e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
148e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
1490032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
150e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
151e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
152e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
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");
156e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
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);
162e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
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));
169e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
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) {
178774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  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);
1854fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor
186b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
187b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
188b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  CallArgList Args;
189b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
190b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // Push the this ptr.
191b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  Args.push_back(std::make_pair(RValue::get(This),
192b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                MD->getThisType(getContext())));
193b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
194b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // And the rest of the call args
195b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
196774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
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
208774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const llvm::Type *Ty =
209e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
210e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                                   FPT->isVariadic());
211b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *This;
212774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
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:
221bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor  //   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);
2264fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor  else if (const CXXDestructorDecl *Destructor
2274fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor             = dyn_cast<CXXDestructorDecl>(MD))
2284fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor    Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
2290979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor  else
230f0070dbae9535836ad41711081465dec2259786bMike Stump    Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
231774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
232b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
233b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                           CE->arg_begin(), CE->arg_end());
234774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson}
2355f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2360f294632f36459174199b77699e339715244b5abAnders CarlssonRValue
2370f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
2380f294632f36459174199b77699e339715244b5abAnders Carlsson                                               const CXXMethodDecl *MD) {
2390f294632f36459174199b77699e339715244b5abAnders Carlsson  assert(MD->isInstance() &&
2400f294632f36459174199b77699e339715244b5abAnders Carlsson         "Trying to emit a member call expr on a static method!");
2410f294632f36459174199b77699e339715244b5abAnders Carlsson
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  }
2540f294632f36459174199b77699e339715244b5abAnders Carlsson
2550f294632f36459174199b77699e339715244b5abAnders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2560f294632f36459174199b77699e339715244b5abAnders Carlsson  const llvm::Type *Ty =
257ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
258ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                   FPT->isVariadic());
2590f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
2600f294632f36459174199b77699e339715244b5abAnders Carlsson
2610f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
2620f294632f36459174199b77699e339715244b5abAnders Carlsson
2630f294632f36459174199b77699e339715244b5abAnders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
2640f294632f36459174199b77699e339715244b5abAnders Carlsson                           E->arg_begin() + 1, E->arg_end());
2650f294632f36459174199b77699e339715244b5abAnders Carlsson}
2660f294632f36459174199b77699e339715244b5abAnders Carlsson
26764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz JahanianRValue
26864e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz JahanianCodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) {
26964e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian  assert((E->getCastKind() == CastExpr::CK_UserDefinedConversion) &&
27064e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian         "EmitCXXFunctionalCastExpr - called with wrong cast");
27164e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian
27264e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian  CXXMethodDecl *MD = E->getTypeConversionMethod();
2734fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  assert(MD && "EmitCXXFunctionalCastExpr - null conversion method");
2744fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not"
2754fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian         " method decl");
27664e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
27764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian
2784fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  const llvm::Type *Ty =
2794fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
2804fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian                                   FPT->isVariadic());
2814fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
2824fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
2834fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0);
2844fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  if (RV.isAggregate())
2854fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian    RV = RValue::get(RV.getAggregateAddr());
2864fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian  return RV;
28764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian}
28864e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian
2895f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
2905f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
2915f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2925f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
2935f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2945f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2955f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
296f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ans: See how CodeGenFunction::LoadObjCSelf() uses
297f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // CodeGenFunction::BlockForwardSelf() for how to do this.
2985f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
2995f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
30095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
301c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool
302c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths,
303c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *ClassDecl,
304c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *BaseClassDecl) {
305c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
306c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      e = ClassDecl->bases_end(); i != e; ++i) {
307c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
308c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
309c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
310104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
311c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (Base == BaseClassDecl) {
312c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(BaseClassDecl);
313c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
314c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
315c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
316c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  // BaseClassDecl not an immediate base of ClassDecl.
317c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
318c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian       e = ClassDecl->bases_end(); i != e; ++i) {
319c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
320c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
321c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
322c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
323c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
324c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(Base);
325c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
326c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
327c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
328c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  return false;
329c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian}
330c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
3319e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
3326d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *ClassDecl,
3336d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *BaseClassDecl) {
3349e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  if (ClassDecl == BaseClassDecl)
3359e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    return BaseValue;
3369e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
3370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
338c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
339c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
340c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  assert(NestedBasePaths.size() > 0 &&
341c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "AddressCXXOfBaseClass - inheritence path failed");
342c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  NestedBasePaths.push_back(ClassDecl);
343c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  uint64_t Offset = 0;
344c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
3459e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // Accessing a member of the base class. Must add delata to
3469e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // the load of 'this'.
347c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
348c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
349c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
350c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const ASTRecordLayout &Layout =
351c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      getContext().getASTRecordLayout(DerivedClass);
352c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
353c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
3545a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian  llvm::Value *OffsetVal =
3555a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian    llvm::ConstantInt::get(
3565a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian                  CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
3579e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
3589e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
3599e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  QualType BTy =
3609e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    getContext().getCanonicalType(
3616d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
3629e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  const llvm::Type *BasePtr = ConvertType(BTy);
36396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
3649e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
3659e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  return BaseValue;
3669e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian}
3679e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
368288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
369288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// for-loop to call the default constructor on individual members of the
370288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. 'Array' is the array type, 'This' is llvm pointer of the start
371288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// of the array and 'D' is the default costructor Decl for elements of the
372288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. It is assumed that all relevant checks have been made by the
373288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// caller.
374288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanianvoid
375288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz JahanianCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
376288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            const ArrayType *Array,
377288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            llvm::Value *This) {
378288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
379288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  assert(CA && "Do we support VLA for construction ?");
380288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
381288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
3820de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
383288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                           "loop.index");
384288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value* zeroConstant =
3850de78998e7bda473b408437053e48661b510d453Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
386288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
387288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
388288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Start the loop with a block that tests the condition.
389288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
390288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
391288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
392288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(CondBlock);
393288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
394288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
395288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
396288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
397288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // otherwise, go to the block after the for-loop.
3984f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
399288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value * NumElementsPtr =
4004f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
401288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
402288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
403288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                              "isless");
404288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // If the condition is true, execute the body.
405288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
406288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
407288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ForBody);
408288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
409288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
410288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
411995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4124f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
4134f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian  EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0);
4146147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian
415288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ContinueBlock);
416288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
417288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the increment of the loop counter.
418288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
419288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
420288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
421288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
422288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
423288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
424288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBranch(CondBlock);
425288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
426288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the fall-through block.
427288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(AfterFor, true);
428288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian}
429288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
4301c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// EmitCXXAggrDestructorCall - calls the default destructor on array
4311c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// elements in reverse order of construction.
432b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
433f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz JahanianCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
434f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           const ArrayType *Array,
435f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           llvm::Value *This) {
4361c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
4371c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  assert(CA && "Do we support VLA for destruction ?");
4381c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
4391c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            1);
4400de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
4411c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Create a temporary for the loop index and initialize it with count of
4421c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // array elements.
4431c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
4441c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                           "loop.index");
4451c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Index = ElementCount;
4461c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* UpperCount =
4471c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
4481c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(UpperCount, IndexPtr, false);
4491c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4501c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Start the loop with a block that tests the condition.
4511c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
4521c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
4531c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4541c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(CondBlock);
4551c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4561c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
4571c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4581c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Generate: if (loop-index != 0 fall to the loop body,
4591c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // otherwise, go to the block after the for-loop.
4601c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* zeroConstant =
4611c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
4621c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
4631c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
4641c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            "isne");
4651c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // If the condition is true, execute the body.
4661c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
4671c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4681c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ForBody);
4691c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4701c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
4711c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
4721c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4731c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One);
4741c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
4751c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitCXXDestructorCall(D, Dtor_Complete, Address);
4761c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4771c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ContinueBlock);
4781c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4791c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the decrement of the loop counter.
4801c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4811c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One, "dec");
4821c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(Counter, IndexPtr, false);
4831c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4841c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
4851c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBranch(CondBlock);
4861c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4871c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the fall-through block.
4881c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(AfterFor, true);
489f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian}
490f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian
491f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanianvoid
492b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
493b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
494b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
495b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
496b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
497343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  if (D->isCopyConstructor(getContext())) {
498343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
499343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    if (ClassDecl->hasTrivialCopyConstructor()) {
500343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
501343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian             "EmitCXXConstructorCall - user declared copy constructor");
502343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      const Expr *E = (*ArgBeg);
503343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      QualType Ty = E->getType();
504343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      llvm::Value *Src = EmitLValue(E).getAddress();
505343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
506343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      return;
507343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    }
508343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  }
509343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian
510b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
511b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
512b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
513b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
514b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
5157267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
5167267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
5177267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
5187267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
5197267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
5207267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
5217267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
5227267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
523b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
52431ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
52531ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
526b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
527b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
528b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
5296217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
530b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
531b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
5326904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
5336904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // Code gen optimization to eliminate copy constructor and return
5346904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
53592f5822df6a0d7571df44b5d279ed4f017fbb0e6Anders Carlsson  if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
5366904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
5371cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
5381cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
5396904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
540b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
541b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
542b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
543b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
544b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
545a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
546ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
547ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
54803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
549ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
550ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
551ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
552ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
553ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
554ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
555ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
556ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
557ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
558ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
559ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
5604a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
561ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
562ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
563ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
564ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
565ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
566ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
567ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
568ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
569ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
570ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
571ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
572ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
573ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
574ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
575ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
576ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
577ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
578ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
579ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
580ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
581ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
582ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
583ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
584ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
585ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
586ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
587ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
588ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
589ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
590ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
591ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
592ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
593ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
594ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
595ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
596ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
597ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
598ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
599ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
600ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
601ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
602ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
603ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
604d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
605d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
606d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
607d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
608d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
609d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
610ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
611f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
612f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
613f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
614f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
615f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
616f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
617d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
618f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
619f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
620f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
621f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
622f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
623f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
624c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
625f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
626f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
627f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
628f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
629d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
630d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
631f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
632d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
6336d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
634215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
6356d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
6366d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
6376d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6386d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
6396d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6403923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
6416d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
6423923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
6433923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
644627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
645627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
6466d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
647d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
648d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
649d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
6506d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
651d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
652d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
653d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
654ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
655d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
656f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
657f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
658f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
659f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
660f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
661f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
662f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
663f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
664f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
665c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
666f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
667f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
668f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
669f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
670d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
671a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
672a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
67360e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
67460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (E->isArrayForm()) {
67560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    ErrorUnsupported(E, "delete[] expression");
67660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    return;
67760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  };
67860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType DeleteTy =
68060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
68160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
68360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Null check the pointer.
68560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
68660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
68760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *IsNull =
68960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
69060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                         "isnull");
69160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
69360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteNotNull);
69460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call the destructor if necessary.
69660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
69760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
69860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      if (!RD->hasTrivialDestructor()) {
69960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
70060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        if (Dtor->isVirtual()) {
70160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          ErrorUnsupported(E, "delete expression with virtual destructor");
70260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          return;
70360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        }
70460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
70660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      }
70760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    }
70860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  }
70960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call delete.
71160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  FunctionDecl *DeleteFD = E->getOperatorDelete();
71260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  const FunctionProtoType *DeleteFTy =
71360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    DeleteFD->getType()->getAsFunctionProtoType();
71460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  CallArgList DeleteArgs;
71660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType ArgTy = DeleteFTy->getArgType(0);
71860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
71960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
72060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
72160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Emit the call to delete.
72260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
72360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                                          DeleteArgs),
72460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)),
72560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           DeleteArgs, DeleteFD);
72660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
72760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteEnd);
72860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson}
72960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
73095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
7312a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
7322a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
73395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
734363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
73527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
73627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
73727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
73827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
73927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
74027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
74127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
74227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
74327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
74427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
74527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
746363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
747363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
748363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
749363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
750363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
751363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
752363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
753b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
754b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
755363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
75627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
75727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
75827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
75927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
76027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
76127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
76227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
76327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
76427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
76527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
76627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
76727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
76827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
76927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
77027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
77127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
77327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
77427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
77527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
77727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
77927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
78027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
78127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
78327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
78427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
78527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
78627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
78727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
789b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
790b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
79127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
79227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
79427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
79527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
79627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
79727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
79827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
80027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
80127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
802e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
80332f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
804738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
8050032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
806cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
807738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
808738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
809cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
810738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
811738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
812738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
813738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
814e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
815738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
816738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
817738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
818738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
8194ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti descriptor");
820738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
821738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
8224ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti ts");
823738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
824738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
825738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
826738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
827738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
828738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
82932f3701853a8237704065c77abc17369dd02c39bMike Stump  Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C,
8307765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                  Out.str());
831cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
832cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
833738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
834738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
835eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stumpclass VtableBuilder {
836f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
837f0070dbae9535836ad41711081465dec2259786bMike Stump  /// Index_t - Vtable index type.
838f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef uint64_t Index_t;
839f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate:
8407c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  std::vector<llvm::Constant *> &methods;
84115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  std::vector<llvm::Constant *> submethods;
8427c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::Type *Ptr8Ty;
843b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Class - The most derived class that this vtable is being built for.
84432f3701853a8237704065c77abc17369dd02c39bMike Stump  const CXXRecordDecl *Class;
845b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// BLayout - Layout for the most derived class that this vtable is being
846b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// built for.
847b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  const ASTRecordLayout &BLayout;
848ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
8497fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
85032f3701853a8237704065c77abc17369dd02c39bMike Stump  llvm::Constant *rtti;
8517c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::LLVMContext &VMContext;
85265defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  CodeGenModule &CGM;  // Per-module state.
853b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Index - Maps a method decl into a vtable index.  Useful for virtual
854b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// dispatch codegen.
855f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
85615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
85715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
85877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  typedef llvm::DenseMap<const CXXMethodDecl *,
85977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                         std::pair<Index_t, Index_t> > Thunks_t;
86077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  Thunks_t Thunks;
86115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  std::vector<Index_t> VCalls;
862552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump  typedef CXXRecordDecl::method_iterator method_iter;
863ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // FIXME: Linkage should follow vtable
864ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const bool Extern;
86577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  const uint32_t LLVMPointerWidth;
86677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  Index_t extra;
8677c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic:
868eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder(std::vector<llvm::Constant *> &meth,
869eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                const CXXRecordDecl *c,
870eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                CodeGenModule &cgm)
871b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
872b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
87377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      CGM(cgm), Extern(true),
87477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
8757c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
8767c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  }
87732f3701853a8237704065c77abc17369dd02c39bMike Stump
878f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
879b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
88015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::Constant *wrap(Index_t i) {
8817c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    llvm::Constant *m;
88215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i);
88315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
88415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  }
8857c435fa7f7666b22abbe8494c537ebc25209223dMike Stump
88615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump  llvm::Constant *wrap(llvm::Constant *m) {
88715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    return llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
88880a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump  }
8894c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump
8907fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
891b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump                            const CXXRecordDecl *RD, uint64_t Offset) {
8927fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
8937fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump           e = RD->bases_end(); i != e; ++i) {
8947fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      const CXXRecordDecl *Base =
8957fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
8967fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      if (i->isVirtual() && !SeenVBase.count(Base)) {
8977fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        SeenVBase.insert(Base);
898b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
89915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        llvm::Constant *m = wrap(BaseOffset);
90015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        m = wrap((0?700:0) + BaseOffset);
9017fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        offsets.push_back(m);
9027fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      }
903b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, Base, Offset);
9047fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    }
9057fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  }
9067fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump
907b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void StartNewTable() {
908b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    SeenVBase.clear();
909b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
91065defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump
91135191b61db617aefba43b8add88a2ec88af67592Mike Stump  bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
912ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                      bool MorallyVirtual, Index_t Offset,
913ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                      std::vector<llvm::Constant *> &submethods,
914ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                      Index_t AddressPoint) {
915b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    typedef CXXMethodDecl::method_iterator meth_iter;
916b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
917b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // FIXME: Don't like the nested loops.  For very large inheritance
918b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // heirarchies we could have a table on the side with the final overridder
919b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // and just replace each instance of an overridden method once.  Would be
920b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // nice to measure the cost/benefit on real code.
921b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
922b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (meth_iter mi = MD->begin_overridden_methods(),
923b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump           e = MD->end_overridden_methods();
924b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         mi != e; ++mi) {
925b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      const CXXMethodDecl *OMD = *mi;
926b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      llvm::Constant *om;
927b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = CGM.GetAddrOfFunction(GlobalDecl(OMD), Ptr8Ty);
928b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty);
929b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
930ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump      for (Index_t i = AddressPoint, e = submethods.size();
931f0070dbae9535836ad41711081465dec2259786bMike Stump           i != e; ++i) {
932b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        // FIXME: begin_overridden_methods might be too lax, covariance */
93377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (submethods[i] != om)
93477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          continue;
93577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        submethods[i] = m;
93677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        Index[MD] = i - AddressPoint;
93777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
93877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        Thunks.erase(OMD);
93977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (MorallyVirtual) {
94077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          VCallOffset[MD] = Offset/8;
94177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          Index_t &idx = VCall[OMD];
94277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          if (idx == 0) {
94377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump            idx = VCalls.size()+1;
94477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump            VCalls.push_back(0);
94515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump          }
94677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          VCalls[idx] = Offset/8 - VCallOffset[OMD];
94777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          VCall[MD] = idx;
94877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          // FIXME: 0?
94977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          Thunks[MD] = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8));
95035191b61db617aefba43b8add88a2ec88af67592Mike Stump          return true;
951b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        }
95277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#if 0
95377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        // FIXME: finish off
95477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        int64_t O = VCallOffset[OMD] - Offset/8;
95577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        if (O) {
95677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump          Thunks[MD] = std::make_pair(O, 0);
95777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        }
95877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#endif
95977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        return true;
96065defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      }
961bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump    }
962b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
96335191b61db617aefba43b8add88a2ec88af67592Mike Stump    return false;
96435191b61db617aefba43b8add88a2ec88af67592Mike Stump  }
96535191b61db617aefba43b8add88a2ec88af67592Mike Stump
96677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  void InstallThunks(Index_t AddressPoint) {
96777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
96877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump         i != e; ++i) {
96977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      const CXXMethodDecl *MD = i->first;
97077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t idx = Index[MD];
97177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t nv_O = i->second.first;
97277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      Index_t v_O = i->second.second;
97377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      methods[AddressPoint + idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
97477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    }
97577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    Thunks.clear();
97677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  }
97777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
978f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump  void OverrideMethods(const CXXRecordDecl *RD, Index_t AddressPoint,
979f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump                       bool MorallyVirtual, Index_t Offset) {
980f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
981f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump         ++mi)
982f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump      if (mi->isVirtual()) {
983f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump        const CXXMethodDecl *MD = *mi;
984f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump        llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
985ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump        OverrideMethod(MD, m, MorallyVirtual, Offset, methods, AddressPoint);
986f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump      }
987f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump  }
988f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump
9896d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual, Index_t Offset) {
990f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump    llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
99177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    // If we can find a previously allocated slot for this, reuse it.
992ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0))
99335191b61db617aefba43b8add88a2ec88af67592Mike Stump      return;
99435191b61db617aefba43b8add88a2ec88af67592Mike Stump
995b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // else allocate a new slot.
99615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    Index[MD] = submethods.size();
99715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    if (MorallyVirtual) {
99815a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      VCallOffset[MD] = Offset/8;
99915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      Index_t &idx = VCall[MD];
100015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      // Allocate the first one, after that, we reuse the previous one.
100115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      if (idx == 0) {
100215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        idx = VCalls.size()+1;
100315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump        VCalls.push_back(0);
100415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump      }
100515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    }
100615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    submethods.push_back(m);
1007b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
1008b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
10096d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
10106d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump                  Index_t Offset) {
1011b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
1012b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         ++mi)
1013b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      if (mi->isVirtual())
10146d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        AddMethod(*mi, MorallyVirtual, Offset);
1015bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump  }
1016bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump
101777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
101877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       const CXXRecordDecl *PrimaryBase,
101977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       bool PrimaryBaseWasVirtual, bool MorallyVirtual,
102077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                       int64_t Offset) {
102177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
102277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump           e = RD->bases_end(); i != e; ++i) {
102377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      if (i->isVirtual())
102477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        continue;
102577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      const CXXRecordDecl *Base =
102677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
102777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
102877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
102977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        StartNewTable();
103077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        Index_t AP;
1031e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump        AP = GenerateVtableForBase(Base, MorallyVirtual, o, false);
103277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        OverrideMethods(RD, AP, MorallyVirtual, o);
103377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        InstallThunks(AP);
103477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump      }
103577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump    }
103677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  }
103777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump
10386d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant *> &offsets,
10396d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              const ASTRecordLayout &Layout,
10406d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              const CXXRecordDecl *PrimaryBase,
10416d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              bool PrimaryBaseWasVirtual, bool MorallyVirtual,
10426d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump              int64_t Offset, bool ForVirtualBase) {
10436d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    StartNewTable();
10446d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    extra = 0;
10456d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // FIXME: Cleanup.
10466d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    if (!ForVirtualBase) {
10476d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      // then virtual base offsets...
10486d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
10496d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump             e = offsets.rend(); i != e; ++i)
10506d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        methods.push_back(*i);
10516d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    }
10526d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10536d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // The vcalls come first...
10546d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    for (std::vector<Index_t>::iterator i=VCalls.begin(), e=VCalls.end();
10556d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump         i < e; ++i)
10566d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      methods.push_back(wrap((0?600:0) + *i));
10576d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    VCalls.clear();
10586d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10596d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    if (ForVirtualBase) {
10606d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      // then virtual base offsets...
10616d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
10626d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump             e = offsets.rend(); i != e; ++i)
10636d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump        methods.push_back(*i);
10646d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    }
10656d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10666d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.push_back(wrap(-(Offset/8)));
10676d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.push_back(rtti);
10686d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    Index_t AddressPoint = methods.size();
10696d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10706d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    methods.insert(methods.end(), submethods.begin(), submethods.end());
10716d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    submethods.clear();
10726d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    InstallThunks(AddressPoint);
10736d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
10746d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    // and then the non-virtual bases.
10756d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
10766d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump                    MorallyVirtual, Offset);
10776d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    return AddressPoint;
10786d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump  }
10796d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump
1080078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump  void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset) {
10819bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    if (!RD->isDynamicClass())
10829bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump      return;
10839bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10849bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
10859bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
10869bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
10879bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10889bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    // vtables are composed from the chain of primaries.
10899bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    if (PrimaryBase) {
10909bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump      if (PrimaryBaseWasVirtual)
10919bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump        IndirectPrimary.insert(PrimaryBase);
1092078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump      Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset);
10939bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    }
10949bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
10959bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    // And add the virtuals for the class to the primary vtable.
10969bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump    AddMethods(RD, MorallyVirtual, Offset);
10979bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump  }
10989bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump
1099e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump  int64_t GenerateVtableForBase(const CXXRecordDecl *RD,
1100b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump                                bool MorallyVirtual, int64_t Offset,
1101b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump                                bool ForVirtualBase) {
1102bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump    if (!RD->isDynamicClass())
1103263b3522add846130ff5f0a85568234e612a81caMike Stump      return 0;
1104109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1105109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
1106109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
1107109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
1108109b13db3391face0b393c730f0326ca51d25b52Mike Stump
110915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    std::vector<llvm::Constant *> offsets;
1110b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    extra = 0;
1111b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    GenerateVBaseOffsets(offsets, RD, Offset);
1112b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump    if (ForVirtualBase)
1113b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump      extra = offsets.size();
111402cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
1115109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // vtables are composed from the chain of primaries.
1116109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (PrimaryBase) {
1117109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (PrimaryBaseWasVirtual)
1118109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(PrimaryBase);
1119078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump      Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset);
1120109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1121276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
112215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump    // And add the virtuals for the class to the primary vtable.
11236d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    AddMethods(RD, MorallyVirtual, Offset);
112415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump
11256d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump    return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual,
11266d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump               MorallyVirtual, Offset, ForVirtualBase);
1127276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
1128276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1129bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump  void GenerateVtableForVBases(const CXXRecordDecl *RD) {
1130109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1131109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
1132109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
1133109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1134109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !IndirectPrimary.count(Base)) {
1135109b13db3391face0b393c730f0326ca51d25b52Mike Stump        // Mark it so we don't output it twice.
1136109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(Base);
1137b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1138b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
1139ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump        Index_t AP;
1140e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump        AP = GenerateVtableForBase(Base, true, BaseOffset, true);
1141ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump        OverrideMethods(RD, AP, true, BaseOffset);
114277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump        InstallThunks(AP);
1143109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1144109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base->getNumVBases())
1145bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump        GenerateVtableForVBases(Base);
1146109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1147e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
1148109b13db3391face0b393c730f0326ca51d25b52Mike Stump};
11498a12b564923a72224730a467007e61b5701e4aa7Mike Stump
1150f0070dbae9535836ad41711081465dec2259786bMike Stumpclass VtableInfo {
1151f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
1152f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef VtableBuilder::Index_t Index_t;
1153f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate:
1154f0070dbae9535836ad41711081465dec2259786bMike Stump  CodeGenModule &CGM;  // Per-module state.
1155f0070dbae9535836ad41711081465dec2259786bMike Stump  /// Index_t - Vtable index type.
1156f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef llvm::DenseMap<const CXXMethodDecl *, Index_t> ElTy;
1157f0070dbae9535836ad41711081465dec2259786bMike Stump  typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy;
1158f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: Move to Context.
1159f0070dbae9535836ad41711081465dec2259786bMike Stump  static MapTy IndexFor;
1160f0070dbae9535836ad41711081465dec2259786bMike Stumppublic:
1161f0070dbae9535836ad41711081465dec2259786bMike Stump  VtableInfo(CodeGenModule &cgm) : CGM(cgm) { }
1162f0070dbae9535836ad41711081465dec2259786bMike Stump  void register_index(const CXXRecordDecl *RD, const ElTy &e) {
1163f0070dbae9535836ad41711081465dec2259786bMike Stump    assert(IndexFor.find(RD) == IndexFor.end() && "Don't compute vtbl twice");
1164f0070dbae9535836ad41711081465dec2259786bMike Stump    // We own a copy of this, it will go away shortly.
1165f0070dbae9535836ad41711081465dec2259786bMike Stump    new ElTy (e);
1166f0070dbae9535836ad41711081465dec2259786bMike Stump    IndexFor[RD] = new ElTy (e);
1167f0070dbae9535836ad41711081465dec2259786bMike Stump  }
1168f0070dbae9535836ad41711081465dec2259786bMike Stump  Index_t lookup(const CXXMethodDecl *MD) {
1169f0070dbae9535836ad41711081465dec2259786bMike Stump    const CXXRecordDecl *RD = MD->getParent();
1170f0070dbae9535836ad41711081465dec2259786bMike Stump    MapTy::iterator I = IndexFor.find(RD);
1171f0070dbae9535836ad41711081465dec2259786bMike Stump    if (I == IndexFor.end()) {
1172f0070dbae9535836ad41711081465dec2259786bMike Stump      std::vector<llvm::Constant *> methods;
1173f0070dbae9535836ad41711081465dec2259786bMike Stump      VtableBuilder b(methods, RD, CGM);
1174e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump      b.GenerateVtableForBase(RD, false, 0, false);
1175bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump      b.GenerateVtableForVBases(RD);
1176f0070dbae9535836ad41711081465dec2259786bMike Stump      register_index(RD, b.getIndex());
1177f0070dbae9535836ad41711081465dec2259786bMike Stump      I = IndexFor.find(RD);
1178f0070dbae9535836ad41711081465dec2259786bMike Stump    }
1179f0070dbae9535836ad41711081465dec2259786bMike Stump    assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index");
1180f0070dbae9535836ad41711081465dec2259786bMike Stump    return (*I->second)[MD];
1181f0070dbae9535836ad41711081465dec2259786bMike Stump  }
1182f0070dbae9535836ad41711081465dec2259786bMike Stump};
1183f0070dbae9535836ad41711081465dec2259786bMike Stump
1184f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: Move to Context.
1185f0070dbae9535836ad41711081465dec2259786bMike StumpVtableInfo::MapTy VtableInfo::IndexFor;
1186f0070dbae9535836ad41711081465dec2259786bMike Stump
1187f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
1188f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
1189f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
1190f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
1191e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
1192f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
119382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
119482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
119582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
1196276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
1197263b3522add846130ff5f0a85568234e612a81caMike Stump  int64_t Offset;
11986f376336138ea719e3c4757ae046a5768043b276Mike Stump
1199eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder b(methods, RD, CGM);
1200109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1201276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // First comes the vtables for all the non-virtual bases...
1202e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump  Offset = b.GenerateVtableForBase(RD, false, 0, false);
120370101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
1204276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // then the vtables for all the virtual bases.
1205bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump  b.GenerateVtableForVBases(RD);
12066f376336138ea719e3c4757ae046a5768043b276Mike Stump
120782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
120882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
120982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
121082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
12117765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                                 linktype, C, Out.str());
1212f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
1213f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
1214276b9f1d814f4f6551cc3000590759a34185d6daMike Stump                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
1215263b3522add846130ff5f0a85568234e612a81caMike Stump                                              Offset*LLVMPointerWidth/8));
1216f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
1217f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
1218f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
1219f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: move to Context
1220f0070dbae9535836ad41711081465dec2259786bMike Stumpstatic VtableInfo *vtableinfo;
1221f0070dbae9535836ad41711081465dec2259786bMike Stump
1222ed032eb5c18b99528cbd76415337b6056a72b911Mike Stumpllvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
1223ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                               const CXXMethodDecl *MD,
122477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                               bool Extern, int64_t nv,
122577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                               int64_t v) {
1226ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  QualType R = MD->getType()->getAsFunctionType()->getResultType();
1227ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
1228ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FunctionArgList Args;
1229ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  ImplicitParamDecl *ThisDecl =
1230ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
1231ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                              MD->getThisType(getContext()));
1232ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType()));
1233ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  for (FunctionDecl::param_const_iterator i = MD->param_begin(),
1234ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump         e = MD->param_end();
1235ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump       i != e; ++i) {
1236ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    ParmVarDecl *D = *i;
1237ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    Args.push_back(std::make_pair(D, D->getType()));
1238ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  }
1239ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  IdentifierInfo *II
1240ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    = &CGM.getContext().Idents.get("__thunk_named_foo_");
1241ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FunctionDecl *FD = FunctionDecl::Create(getContext(),
1242ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          getContext().getTranslationUnitDecl(),
1243ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          SourceLocation(), II, R, 0,
1244ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          Extern
1245ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                            ? FunctionDecl::Extern
1246ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                            : FunctionDecl::Static,
1247ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                          false, true);
1248ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  StartFunction(FD, R, Fn, Args, SourceLocation());
1249ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // FIXME: generate body
1250ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  FinishFunction();
1251ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  return Fn;
1252ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump}
1253ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
125477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stumpllvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
125577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump                                          int64_t nv, int64_t v) {
1256ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::SmallString<256> OutName;
1257ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::raw_svector_ostream Out(OutName);
125877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  mangleThunk(MD, nv, v, getContext(), Out);
1259ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
1260ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
1261ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  if (!Extern)
1262ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    linktype = llvm::GlobalValue::InternalLinkage;
1263ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
1264ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1265ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  const llvm::FunctionType *FTy =
1266ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    getTypes().GetFunctionType(getTypes().getFunctionInfo(MD),
1267ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                               FPT->isVariadic());
1268ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
1269ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(),
1270ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump                                              &getModule());
127177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump  CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v);
1272ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  // Fn = Builder.CreateBitCast(Fn, Ptr8Ty);
1273ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
1274ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump  return m;
1275ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump}
1276ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump
1277f0070dbae9535836ad41711081465dec2259786bMike Stumpllvm::Value *
1278f0070dbae9535836ad41711081465dec2259786bMike StumpCodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This,
1279f0070dbae9535836ad41711081465dec2259786bMike Stump                                  const llvm::Type *Ty) {
1280f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: If we know the dynamic type, we don't have to do a virtual dispatch.
1281f0070dbae9535836ad41711081465dec2259786bMike Stump
1282f0070dbae9535836ad41711081465dec2259786bMike Stump  // FIXME: move to Context
1283f0070dbae9535836ad41711081465dec2259786bMike Stump  if (vtableinfo == 0)
1284f0070dbae9535836ad41711081465dec2259786bMike Stump    vtableinfo = new VtableInfo(CGM);
1285f0070dbae9535836ad41711081465dec2259786bMike Stump
1286f0070dbae9535836ad41711081465dec2259786bMike Stump  VtableInfo::Index_t Idx = vtableinfo->lookup(MD);
1287f0070dbae9535836ad41711081465dec2259786bMike Stump
1288f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1289f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1290f0070dbae9535836ad41711081465dec2259786bMike Stump  Ty = llvm::PointerType::get(Ty, 0);
1291f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::Value *vtbl = Builder.CreateBitCast(This, Ty);
1292f0070dbae9535836ad41711081465dec2259786bMike Stump  vtbl = Builder.CreateLoad(vtbl);
1293f0070dbae9535836ad41711081465dec2259786bMike Stump  llvm::Value *vfn = Builder.CreateConstInBoundsGEP1_64(vtbl,
1294f0070dbae9535836ad41711081465dec2259786bMike Stump                                                        Idx, "vfn");
1295f0070dbae9535836ad41711081465dec2259786bMike Stump  vfn = Builder.CreateLoad(vfn);
1296f0070dbae9535836ad41711081465dec2259786bMike Stump  return vfn;
1297f0070dbae9535836ad41711081465dec2259786bMike Stump}
1298f0070dbae9535836ad41711081465dec2259786bMike Stump
1299eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
1300eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
1301eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// copy or via a copy constructor call.
13024f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian//  FIXME. Consolidate this with EmitCXXAggrConstructorCall.
1303eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanianvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
1304eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            llvm::Value *Src,
1305eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            const ArrayType *Array,
1306eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            const CXXRecordDecl *BaseClassDecl,
1307eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            QualType Ty) {
1308eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1309eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  assert(CA && "VLA cannot be copied over");
1310eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
1311eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1312eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1313eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1314eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                           "loop.index");
1315eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value* zeroConstant =
1316eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1317eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    Builder.CreateStore(zeroConstant, IndexPtr, false);
1318eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Start the loop with a block that tests the condition.
1319eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1320eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
1321eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1322eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(CondBlock);
1323eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1324eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1325eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1326eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // otherwise, go to the block after the for-loop.
1327eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
1328eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value * NumElementsPtr =
1329eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1330eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
1331eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1332eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                              "isless");
1333eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // If the condition is true, execute the body.
1334eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
1335eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1336eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ForBody);
1337eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1338eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
1339eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1340eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1341eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1342eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  if (BitwiseCopy)
1343eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1344eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  else if (CXXConstructorDecl *BaseCopyCtor =
1345eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian           BaseClassDecl->getCopyConstructor(getContext(), 0)) {
1346eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1347eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                                      Ctor_Complete);
1348eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgList CallArgs;
1349eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the this (Dest) ptr.
1350eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1351eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
1352eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1353eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the Src ptr.
1354eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1355eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getParamDecl(0)->getType()));
1356eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    QualType ResultType =
1357eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1358eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1359eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1360eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  }
1361eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ContinueBlock);
1362eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1363eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the increment of the loop counter.
1364eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1365eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1366eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1367eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
1368eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1369eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1370eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBranch(CondBlock);
1371eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1372eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the fall-through block.
1373eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(AfterFor, true);
1374eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian}
1375eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1376c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
1377c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// array of objects from SrcValue to DestValue. Assignment can be either a
1378c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// bitwise assignment or via a copy assignment operator function call.
1379c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
1380c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanianvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
1381c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            llvm::Value *Src,
1382c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            const ArrayType *Array,
1383c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            const CXXRecordDecl *BaseClassDecl,
1384c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            QualType Ty) {
1385c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1386c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  assert(CA && "VLA cannot be asssigned");
1387c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
1388c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1389c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1390c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1391c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                           "loop.index");
1392c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value* zeroConstant =
1393c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1394c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
1395c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Start the loop with a block that tests the condition.
1396c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1397c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
1398c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1399c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(CondBlock);
1400c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1401c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1402c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1403c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // otherwise, go to the block after the for-loop.
1404c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
1405c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value * NumElementsPtr =
1406c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1407c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
1408c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1409c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                              "isless");
1410c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // If the condition is true, execute the body.
1411c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
1412c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1413c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ForBody);
1414c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1415c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Inside the loop body, emit the assignment operator call on array element.
1416c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1417c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1418c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1419c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const CXXMethodDecl *MD = 0;
1420c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  if (BitwiseAssign)
1421c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1422c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  else {
1423c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    bool hasCopyAssign = BaseClassDecl->hasConstCopyAssignment(getContext(),
1424c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                                               MD);
1425c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    assert(hasCopyAssign && "EmitClassAggrCopyAssignment - No user assign");
1426c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    (void)hasCopyAssign;
1427c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1428c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const llvm::Type *LTy =
1429c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1430c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                   FPT->isVariadic());
1431c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
1432c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1433c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgList CallArgs;
1434c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the this (Dest) ptr.
1435c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1436c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getThisType(getContext())));
1437c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1438c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the Src ptr.
1439c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1440c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getParamDecl(0)->getType()));
1441ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump    QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
1442c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1443c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian             Callee, CallArgs, MD);
1444c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  }
1445c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ContinueBlock);
1446c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1447c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the increment of the loop counter.
1448c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1449c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1450c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1451c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
1452c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1453c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1454c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBranch(CondBlock);
1455c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1456c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the fall-through block.
1457c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(AfterFor, true);
1458c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian}
1459c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1460ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
1461ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
1462eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// or via a copy constructor call.
1463ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
1464942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
1465ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                        const CXXRecordDecl *ClassDecl,
1466942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
1467942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
1468942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
1469942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
1470942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1471942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
1472942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1473ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
1474942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1475942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
1476ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  if (CXXConstructorDecl *BaseCopyCtor =
147780e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
1478ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1479ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
1480ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
1481ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
1482ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1483ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
1484ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
1485ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
1486ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1487370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian                       BaseCopyCtor->getParamDecl(0)->getType()));
1488ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    QualType ResultType =
1489ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1490ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1491ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1492ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
1493ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
149406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
14950270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class
14960270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// object from SrcValue to DestValue. Assignment can be either a bitwise
14970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call.
1498c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
14990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment(
15000270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        llvm::Value *Dest, llvm::Value *Src,
15010270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *ClassDecl,
15020270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *BaseClassDecl,
15030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        QualType Ty) {
15040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (ClassDecl) {
15050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
15060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
15070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
15080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyAssignment()) {
15090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
15100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    return;
15110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
15120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
15130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXMethodDecl *MD = 0;
1514e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(),
1515e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                                                 MD);
1516e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign");
1517e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  (void)ConstCopyAssignOp;
1518e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian
1519e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1520e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const llvm::Type *LTy =
1521e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1522e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                   FPT->isVariadic());
1523e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
15240270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1525e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgList CallArgs;
1526e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the this (Dest) ptr.
1527e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Dest),
1528e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getThisType(getContext())));
15290270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1530e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the Src ptr.
1531e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Src),
1532e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getParamDecl(0)->getType()));
1533e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  QualType ResultType =
1534e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
1535e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1536e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian           Callee, CallArgs, MD);
15370270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian}
15380270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
153906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor
154006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanianvoid
154106f598aa45b651f9f3be0b916d43876eae747af0Fariborz JahanianCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *CD,
154206f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionDecl *FD,
154306f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              llvm::Function *Fn,
154406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionArgList &Args) {
154506f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
154606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  EmitCtorPrologue(CD);
154706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  FinishFunction();
154806f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian}
154906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
15508c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
155197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
155297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise
155397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order
155497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
155597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
155697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of class type, the copy constructor for the class is
155797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
155897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is an array, each element is copied, in the manner
155997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
156097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of scalar type, the built-in assignment operator is
156197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
156297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the
156397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor
156497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
15658c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
15668c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
15678c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
1568ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
156997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
157097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
15718c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
15728c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
157397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
15741e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
15751e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
15761e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
15771e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
15781e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
15791e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
15801e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
15811e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
158297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
158397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
158497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
158597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
158697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
1587ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
158897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
158997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1590942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
1591942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
159297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
159397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
15941e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
15951e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
15961e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
15971e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1598eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    const ConstantArrayType *Array =
1599eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1600eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    if (Array)
1601eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
1602eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
16031e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
16041e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
16051e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
16061e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
16071e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1608eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      if (Array) {
1609eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1610eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1611eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        llvm::Value *DestBaseAddrPtr =
1612eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1613eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        llvm::Value *SrcBaseAddrPtr =
1614eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1615eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1616eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                    FieldClassDecl, FieldType);
1617eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      }
1618eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      else
1619eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
1620eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
16211e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
16221e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
1623f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    // Do a built-in assignment of scalar data members.
1624f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1625f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1626f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
1627f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
16281e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
16298c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
163097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian}
163197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
16322198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
16332198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// Before the implicitly-declared copy assignment operator for a class is
16342198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined, all implicitly- declared copy assignment operators for
16352198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// its direct base classes and its nonstatic data members shall have been
16362198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12]
16372198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// The implicitly-defined copy assignment operator for class X performs
16382198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// memberwise assignment of its subob- jects. The direct base classes of X are
16392198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// assigned first, in the order of their declaration in
16402198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// the base-specifier-list, and then the immediate nonstatic data members of X
16412198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// are assigned, in the order in which they were declared in the class
16422198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type:
16430270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of class type, the copy assignment operator for the
16440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   class is used (as if by explicit qualification; that is, ignoring any
16452198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   possible virtual overriding functions in more derived classes);
16460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
16470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is an array, each element is assigned, in the manner
16482198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   appropriate to the element type;
16490270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
16500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of scalar type, the built-in assignment operator is
16512198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   used.
16522198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
16532198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionDecl *FD,
16542198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  llvm::Function *Fn,
16552198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionArgList &Args) {
16560270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16570270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
16580270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
16590270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
16602198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
16612198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian
16620270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
16630270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *ThisArg = i->first;
16640270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
16650270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
16660270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
16670270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
16680270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
16690270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16700270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
16710270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
16720270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
16730270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (Base->isVirtual())
16740270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
16750270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16760270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
16770270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
16780270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
16790270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                            Base->getType());
16800270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
16810270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16820270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
16830270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
16840270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Field != FieldEnd; ++Field) {
16850270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1686c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const ConstantArrayType *Array =
1687c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1688c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    if (Array)
1689c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
16900270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
16910270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
16920270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      CXXRecordDecl *FieldClassDecl
16930270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(FieldClassType->getDecl());
16940270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
16950270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1696c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      if (Array) {
1697c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1698c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1699c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *DestBaseAddrPtr =
1700c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1701c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *SrcBaseAddrPtr =
1702c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1703c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1704c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                    FieldClassDecl, FieldType);
1705c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      }
1706c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      else
1707c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
1708c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
17090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
17100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    }
17110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // Do a built-in assignment of scalar data members.
17120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
17130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
17140270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
17150270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
1716183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  }
1717183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian
1718183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  // return *this;
1719183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  Builder.CreateStore(LoadOfThis, ReturnValue);
17200270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
17212198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  FinishFunction();
17222198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian}
172397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
1724e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
1725e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
1726174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXCtorType.
1727e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
1728742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
1729eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
1730f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
17316d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
1732742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1733e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
1734e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
1735e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
1736e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
1737f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
17386d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
17396d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
17406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
17416d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
17426d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
1743742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
1744742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
1745742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
1746742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
1747b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1748e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
1749e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
1750e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
175164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian      const ConstantArrayType *Array =
1752eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
175364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian      if (Array)
175464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
17558c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian
1756f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1757e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      LValue LHS;
1758e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      if (FieldType->isReferenceType()) {
1759e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        // FIXME: This is really ugly; should be refactored somehow
1760e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
1761e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        llvm::Value *V = Builder.CreateStructGEP(LoadOfThis, idx, "tmp");
1762e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        LHS = LValue::MakeAddr(V, FieldType.getCVRQualifiers(),
1763e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman                               QualType::GCNone, FieldType.getAddressSpace());
1764e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      } else {
1765e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
1766e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      }
17676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
1768e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        if (!Field->isAnonymousStructOrUnion()) {
176950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
177050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
177164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          if (Array) {
177264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            const llvm::Type *BasePtr = ConvertType(FieldType);
177364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            BasePtr = llvm::PointerType::getUnqual(BasePtr);
177464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            llvm::Value *BaseAddrPtr =
177564a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
177664a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            EmitCXXAggrConstructorCall(Member->getConstructor(),
177764a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                       Array, BaseAddrPtr);
177864a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          }
177964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          else
178064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            EmitCXXConstructorCall(Member->getConstructor(),
178164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Ctor_Complete, LHS.getAddress(),
178264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Member->const_arg_begin(),
178364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Member->const_arg_end());
1784e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          continue;
1785e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
1786e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        else {
1787e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          // Initializing an anonymous union data member.
1788e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldDecl *anonMember = Member->getAnonUnionMember();
1789c186b8fe4a308b53569fe839a3224de70d92ab0eAnders Carlsson          LHS = EmitLValueForField(LHS.getAddress(), anonMember,
1790c186b8fe4a308b53569fe839a3224de70d92ab0eAnders Carlsson                                   /*IsUnion=*/true, 0);
1791e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldType = anonMember->getType();
1792e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
179350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
1794e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
1795e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
179650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
1797e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      RValue RHS;
1798e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      if (FieldType->isReferenceType())
1799e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        RHS = EmitReferenceBindingToExpr(RhsExpr, FieldType,
1800e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman                                        /*IsInitializer=*/true);
1801e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      else
1802e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman        RHS = RValue::get(EmitScalarExpr(RhsExpr, true));
1803e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman      EmitStoreThroughLValue(RHS, LHS, FieldType);
1804e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
1805e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
1806f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
18070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
18081d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    // Nontrivial default constructor with no initializer list. It may still
18090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // have bases classes and/or contain non-static data members which require
18100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // construction.
18110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (CXXRecordDecl::base_class_const_iterator Base =
18120880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          ClassDecl->bases_begin();
18130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          Base != ClassDecl->bases_end(); ++Base) {
18140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      // FIXME. copy assignment of virtual base NYI
18150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (Base->isVirtual())
18160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
18180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *BaseClassDecl
18190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
18200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (BaseClassDecl->hasTrivialConstructor())
18210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *BaseCX =
18230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            BaseClassDecl->getDefaultConstructor(getContext())) {
18240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
18250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
18260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                               BaseClassDecl);
18270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
18280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      }
18290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
18300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
18311d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
18321d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         FieldEnd = ClassDecl->field_end();
18331d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         Field != FieldEnd; ++Field) {
18341d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1835288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian      const ConstantArrayType *Array =
1836288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1837f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1838f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
18391d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
18401d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian        continue;
18411d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      const RecordType *ClassRec = FieldType->getAs<RecordType>();
18420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *MemberClassDecl =
18430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
18440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor())
18450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
18460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *MamberCX =
18470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            MemberClassDecl->getDefaultConstructor(getContext())) {
18480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
18490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1850288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        if (Array) {
1851288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          const llvm::Type *BasePtr = ConvertType(FieldType);
1852288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          BasePtr = llvm::PointerType::getUnqual(BasePtr);
1853288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          llvm::Value *BaseAddrPtr =
1854288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1855288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr);
1856288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        }
1857288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        else
1858288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(),
1859288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                 0, 0);
18601d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      }
18611d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    }
18620880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
18630880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
1864f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
1865b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
1866f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
1867f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1868f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
1869f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
18700032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1871f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
1872f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
1873f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
1874f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
1875f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
1876e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
1877426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1878426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
1879426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
1880426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
1881174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXDtorType.
1882426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
1883426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
1884de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson  assert(!ClassDecl->getNumVBases() &&
1885de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson         "FIXME: Destruction of virtual bases not supported");
1886426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
1887426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1888426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
1889426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
1890426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
1891426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
1892426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
1893426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
1894f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1895f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1896f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1897f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
1898426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
1899426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1900426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
1901426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1902426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
1903426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
1904f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1905f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1906f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1907f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1908f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1909f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1910f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1911f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1912f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1913f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1914f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
1915b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1916426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
1917426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
1918426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1919426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
1920426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1921426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
1922426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
1923426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
1924426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
1925426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
1926426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
19270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial())
19280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
19290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // Case of destructor synthesis with fields and base classes
19300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // which have non-trivial destructors. They must be destructed in
19310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // reverse order of their construction.
19320880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<FieldDecl *, 16> DestructedFields;
19330880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
19340880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
19350880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
19360880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Field != FieldEnd; ++Field) {
19370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1938f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian    if (getContext().getAsConstantArrayType(FieldType))
1939f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
19400880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (const RecordType *RT = FieldType->getAs<RecordType>()) {
19410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
19420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
19430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
19440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      DestructedFields.push_back(*Field);
19450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
19460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
19470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!DestructedFields.empty())
19480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (int i = DestructedFields.size() -1; i >= 0; --i) {
19490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      FieldDecl *Field = DestructedFields[i];
19500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      QualType FieldType = Field->getType();
1951f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1952f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1953f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        if (Array)
1954f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          FieldType = getContext().getBaseElementType(FieldType);
19550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
19560880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
19570880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
19580880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
1959f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1960f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1961f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1962f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1963f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1964f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1965f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1966f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1967f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1968f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1969f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
19700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
19710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
19720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
19730880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
19740880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
19750880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
19760880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (Base->isVirtual())
19770880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
19780880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
19790880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
19800880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
19810880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (BaseClassDecl->hasTrivialDestructor())
19820880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
19830880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    DestructedBases.push_back(BaseClassDecl);
19840880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
19850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DestructedBases.empty())
19860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
19870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (int i = DestructedBases.size() -1; i >= 0; --i) {
19880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl = DestructedBases[i];
19890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
19900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                           ClassDecl,BaseClassDecl);
19910880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
19920880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                          Dtor_Complete, V);
19930880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
1994426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
19950880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
19960880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanianvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *CD,
19970880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionDecl *FD,
19980880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  llvm::Function *Fn,
19990880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionArgList &Args) {
20000880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
20010880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
20020880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredDestructor() &&
20030880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian         "SynthesizeDefaultDestructor - destructor has user declaration");
20040880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  (void) ClassDecl;
20050880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
20060880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
20070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  EmitDtorEpilogue(CD);
20080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  FinishFunction();
20090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian}
2010