CGCXX.cpp revision c28bbc2d2271aab6c5d79ef2758604221cd92a4b
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
181b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
182b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
183b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  CallArgList Args;
184b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
185b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // Push the this ptr.
186b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  Args.push_back(std::make_pair(RValue::get(This),
187b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                                MD->getThisType(getContext())));
188b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
189b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  // And the rest of the call args
190b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
191774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
192b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  QualType ResultType = MD->getType()->getAsFunctionType()->getResultType();
193b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args),
194b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                  Callee, Args, MD);
195b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson}
196b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
197b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
198b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const MemberExpr *ME = cast<MemberExpr>(CE->getCallee());
199b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
200b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
201e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2027116da1efe23f90eb22524ac9aa036153b74f482Mike Stump
203f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  if (MD->isVirtual()) {
2047116da1efe23f90eb22524ac9aa036153b74f482Mike Stump    ErrorUnsupported(CE, "virtual dispatch");
2057116da1efe23f90eb22524ac9aa036153b74f482Mike Stump  }
2067116da1efe23f90eb22524ac9aa036153b74f482Mike Stump
207774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  const llvm::Type *Ty =
208e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
209e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson                                   FPT->isVariadic());
210b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
211774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
212b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *This;
213774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
214774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  if (ME->isArrow())
215b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = EmitScalarExpr(ME->getBase());
216774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  else {
217774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson    LValue BaseLV = EmitLValue(ME->getBase());
218b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson    This = BaseLV.getAddress();
219774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson  }
220774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson
221b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
222b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson                           CE->arg_begin(), CE->arg_end());
223774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson}
2245f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2250f294632f36459174199b77699e339715244b5abAnders CarlssonRValue
2260f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
2270f294632f36459174199b77699e339715244b5abAnders Carlsson                                               const CXXMethodDecl *MD) {
2280f294632f36459174199b77699e339715244b5abAnders Carlsson  assert(MD->isInstance() &&
2290f294632f36459174199b77699e339715244b5abAnders Carlsson         "Trying to emit a member call expr on a static method!");
2300f294632f36459174199b77699e339715244b5abAnders Carlsson
231ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian  if (MD->isCopyAssignment()) {
232ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext());
233ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    if (ClassDecl->hasTrivialCopyAssignment()) {
234ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
235ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian             "EmitCXXOperatorMemberCallExpr - user declared copy assignment");
236ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
237ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress();
238ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      QualType Ty = E->getType();
239ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
240ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian      return RValue::get(This);
241ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian    }
242ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian  }
2430f294632f36459174199b77699e339715244b5abAnders Carlsson
2440f294632f36459174199b77699e339715244b5abAnders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2450f294632f36459174199b77699e339715244b5abAnders Carlsson  const llvm::Type *Ty =
2460f294632f36459174199b77699e339715244b5abAnders Carlsson  CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
2470f294632f36459174199b77699e339715244b5abAnders Carlsson                                 FPT->isVariadic());
2480f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
2490f294632f36459174199b77699e339715244b5abAnders Carlsson
2500f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
2510f294632f36459174199b77699e339715244b5abAnders Carlsson
2520f294632f36459174199b77699e339715244b5abAnders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
2530f294632f36459174199b77699e339715244b5abAnders Carlsson                           E->arg_begin() + 1, E->arg_end());
2540f294632f36459174199b77699e339715244b5abAnders Carlsson}
2550f294632f36459174199b77699e339715244b5abAnders Carlsson
2565f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
2575f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
2585f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2595f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
2605f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2615f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2625f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
263f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ans: See how CodeGenFunction::LoadObjCSelf() uses
264f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // CodeGenFunction::BlockForwardSelf() for how to do this.
2655f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
2665f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
26795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
268c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool
269c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths,
270c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *ClassDecl,
271c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *BaseClassDecl) {
272c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
273c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      e = ClassDecl->bases_end(); i != e; ++i) {
274c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
275c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
276c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
277104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
278c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (Base == BaseClassDecl) {
279c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(BaseClassDecl);
280c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
281c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
282c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
283c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  // BaseClassDecl not an immediate base of ClassDecl.
284c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
285c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian       e = ClassDecl->bases_end(); i != e; ++i) {
286c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
287c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
288c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
289c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
290c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
291c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(Base);
292c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
293c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
294c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
295c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  return false;
296c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian}
297c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
2989e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
2996d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *ClassDecl,
3006d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *BaseClassDecl) {
3019e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  if (ClassDecl == BaseClassDecl)
3029e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    return BaseValue;
3039e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
3040032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
305c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
306c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
307c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  assert(NestedBasePaths.size() > 0 &&
308c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "AddressCXXOfBaseClass - inheritence path failed");
309c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  NestedBasePaths.push_back(ClassDecl);
310c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  uint64_t Offset = 0;
311c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
3129e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // Accessing a member of the base class. Must add delata to
3139e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // the load of 'this'.
314c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
315c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
316c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
317c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const ASTRecordLayout &Layout =
318c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      getContext().getASTRecordLayout(DerivedClass);
319c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
320c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
3215a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian  llvm::Value *OffsetVal =
3225a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian    llvm::ConstantInt::get(
3235a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian                  CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
3249e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
3259e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
3269e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  QualType BTy =
3279e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    getContext().getCanonicalType(
3286d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
3299e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  const llvm::Type *BasePtr = ConvertType(BTy);
33096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
3319e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
3329e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  return BaseValue;
3339e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian}
3349e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
335288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
336288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// for-loop to call the default constructor on individual members of the
337288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. 'Array' is the array type, 'This' is llvm pointer of the start
338288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// of the array and 'D' is the default costructor Decl for elements of the
339288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. It is assumed that all relevant checks have been made by the
340288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// caller.
341288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanianvoid
342288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz JahanianCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
343288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            const ArrayType *Array,
344288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                            llvm::Value *This) {
345288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
346288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  assert(CA && "Do we support VLA for construction ?");
347288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
348288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
3490de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
350288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                           "loop.index");
351288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value* zeroConstant =
3520de78998e7bda473b408437053e48661b510d453Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
353288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
354288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
355288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Start the loop with a block that tests the condition.
356288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
357288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
358288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
359288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(CondBlock);
360288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
361288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
362288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
363288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
364288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // otherwise, go to the block after the for-loop.
365288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  uint64_t NumElements = CA->getSize().getZExtValue();
366288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value * NumElementsPtr =
3670de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
368288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
369288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
370288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                              "isless");
371288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // If the condition is true, execute the body.
372288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
373288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
374288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ForBody);
375288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
376288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
377288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
378995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
379288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  if (const ConstantArrayType *CAT =
380288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian      dyn_cast<ConstantArrayType>(Array->getElementType())) {
3810de78998e7bda473b408437053e48661b510d453Fariborz Jahanian    uint64_t delta = getContext().getConstantArrayElementCount(CAT);
382995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian    // Address = This + delta*Counter for current loop iteration.
3836147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *DeltaPtr =
3840de78998e7bda473b408437053e48661b510d453Fariborz Jahanian      llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), delta);
3856147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    DeltaPtr = Builder.CreateMul(Counter, DeltaPtr, "mul");
3866147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *Address =
3876147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian      Builder.CreateInBoundsGEP(This, DeltaPtr, "arrayidx");
388288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian    EmitCXXAggrConstructorCall(D, CAT, Address);
389288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  }
3906147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian  else {
3916147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
392288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian    EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0);
3936147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian  }
3946147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian
395288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ContinueBlock);
396288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
397288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the increment of the loop counter.
398288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
399288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
400288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
401288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
402288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
403288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
404288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBranch(CondBlock);
405288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
406288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the fall-through block.
407288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(AfterFor, true);
408288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian}
409288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
4101c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// EmitCXXAggrDestructorCall - calls the default destructor on array
4111c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// elements in reverse order of construction.
412b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
413f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz JahanianCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
414f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           const ArrayType *Array,
415f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           llvm::Value *This) {
4161c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
4171c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  assert(CA && "Do we support VLA for destruction ?");
4181c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
4191c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            1);
4200de78998e7bda473b408437053e48661b510d453Fariborz Jahanian  uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
4211c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Create a temporary for the loop index and initialize it with count of
4221c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // array elements.
4231c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
4241c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                           "loop.index");
4251c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Index = ElementCount;
4261c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* UpperCount =
4271c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
4281c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(UpperCount, IndexPtr, false);
4291c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4301c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Start the loop with a block that tests the condition.
4311c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
4321c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
4331c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4341c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(CondBlock);
4351c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4361c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
4371c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4381c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Generate: if (loop-index != 0 fall to the loop body,
4391c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // otherwise, go to the block after the for-loop.
4401c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* zeroConstant =
4411c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
4421c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
4431c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
4441c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            "isne");
4451c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // If the condition is true, execute the body.
4461c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
4471c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4481c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ForBody);
4491c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4501c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
4511c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
4521c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4531c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One);
4541c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
4551c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitCXXDestructorCall(D, Dtor_Complete, Address);
4561c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4571c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ContinueBlock);
4581c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4591c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the decrement of the loop counter.
4601c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4611c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One, "dec");
4621c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(Counter, IndexPtr, false);
4631c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4641c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
4651c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBranch(CondBlock);
4661c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4671c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the fall-through block.
4681c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(AfterFor, true);
469f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian}
470f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian
471f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanianvoid
472b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
473b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
474b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
475b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
476b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
477343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  if (D->isCopyConstructor(getContext())) {
478343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
479343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    if (ClassDecl->hasTrivialCopyConstructor()) {
480343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
481343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian             "EmitCXXConstructorCall - user declared copy constructor");
482343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      const Expr *E = (*ArgBeg);
483343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      QualType Ty = E->getType();
484343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      llvm::Value *Src = EmitLValue(E).getAddress();
485343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
486343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      return;
487343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    }
488343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  }
489343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian
490b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
491b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
492b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
493b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
494b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
4957267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
4967267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
4977267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
4987267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
4997267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
5007267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
5017267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
5027267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
503b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
50431ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
50531ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
506b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
507b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
508b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
5096217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
510b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
511b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
5126904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
5136904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // Code gen optimization to eliminate copy constructor and return
5146904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
5151cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian  if (E->isElidable()) {
5166904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
5171cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
5181cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
5196904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
520b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
521b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
522b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
523b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
524b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
525a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
526ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
527ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
52803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
529ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
530ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
531ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
532ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
533ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
534ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
535ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
536ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
537ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
538ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
539ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
5404a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
541ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
542ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
543ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
544ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
545ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
546ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
547ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
548ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
549ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
550ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
551ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
552ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
553ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
554ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
555ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
556ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
557ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
558ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
559ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
560ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
561ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
562ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
563ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
564ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
565ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
566ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
567ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
568ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
569ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
570ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
571ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
572ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
573ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
574ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
575ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
576ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
577ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
578ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
579ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
580ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
581ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
582ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
583ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
584d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
585d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
586d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
587d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
588d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
589d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
590ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
591f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
592f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
593f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
594f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
595f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
596f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
597d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
598f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
599f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
600f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
601f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
602f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
603f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
604c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
605f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
606f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
607f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
608f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
609d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
610d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
611f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
612d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
6136d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
614215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
6156d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
6166d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
6176d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6186d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
6196d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6203923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
6216d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
6223923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
6233923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
624627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
625627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
6266d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
627d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
628d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
629d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
6306d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
631d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
632d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
633d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
634ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
635d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
636f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
637f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
638f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
639f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
640f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
641f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
642f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
643f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
644f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
645c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
646f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
647f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
648f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
649f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
650d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
651a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
652a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
65360e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
65460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (E->isArrayForm()) {
65560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    ErrorUnsupported(E, "delete[] expression");
65660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    return;
65760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  };
65860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
65960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType DeleteTy =
66060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
66160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
66260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
66360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
66460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Null check the pointer.
66560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
66660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
66760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
66860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *IsNull =
66960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
67060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                         "isnull");
67160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
67360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteNotNull);
67460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call the destructor if necessary.
67660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
67760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
67860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      if (!RD->hasTrivialDestructor()) {
67960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
68060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        if (Dtor->isVirtual()) {
68160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          ErrorUnsupported(E, "delete expression with virtual destructor");
68260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          return;
68360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        }
68460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
68660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      }
68760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    }
68860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  }
68960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call delete.
69160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  FunctionDecl *DeleteFD = E->getOperatorDelete();
69260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  const FunctionProtoType *DeleteFTy =
69360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    DeleteFD->getType()->getAsFunctionProtoType();
69460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  CallArgList DeleteArgs;
69660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType ArgTy = DeleteFTy->getArgType(0);
69860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
69960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
70060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Emit the call to delete.
70260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
70360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                                          DeleteArgs),
70460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)),
70560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           DeleteArgs, DeleteFD);
70660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteEnd);
70860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson}
70960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
71127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
71259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
71359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
71459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
71559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
71617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
71717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
71859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
71959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
72059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
72159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
72259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
72359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
72459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
72559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
72695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
72727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
72859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
72959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
73059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
73195d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
7322a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
7332a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
73495d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
735363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
73627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
73727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
73827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
73927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
74027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
74127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
74227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
74327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
74427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
74527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
74627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
747363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
748363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
749363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
750363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
751363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
752363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
753363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
754b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
755b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
756363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
75727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
75827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
75927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
76027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
76127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
76227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
76327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
76427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
76527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
76627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
76727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
76827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
76927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
77027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
77127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
77227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
77327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
77527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
77627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
77727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
77927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
78027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
78127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
78327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
78527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
78627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
78727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
78927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
79027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
79127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
79227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
79327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
795b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
796b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
79727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
79827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
80027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
80127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
80227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
80327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
80427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
80527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
80627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
80727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
808e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
80932f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
810738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
8110032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
812cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
813738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
814738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
815cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
816738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
817738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
818738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
819738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
820e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
821738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
822738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
823738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
824738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
8254ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti descriptor");
826738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
827738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
8284ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti ts");
829738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
830738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
831738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
832738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
833738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
834738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
83532f3701853a8237704065c77abc17369dd02c39bMike Stump  Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C,
8367765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                  Out.str());
837cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
838cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
839738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
840738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
841eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stumpclass VtableBuilder {
8427c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  std::vector<llvm::Constant *> &methods;
8437c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::Type *Ptr8Ty;
844b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Class - The most derived class that this vtable is being built for.
84532f3701853a8237704065c77abc17369dd02c39bMike Stump  const CXXRecordDecl *Class;
846b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// BLayout - Layout for the most derived class that this vtable is being
847b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// built for.
848b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  const ASTRecordLayout &BLayout;
849ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
8507fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
85132f3701853a8237704065c77abc17369dd02c39bMike Stump  llvm::Constant *rtti;
8527c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::LLVMContext &VMContext;
85365defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  CodeGenModule &CGM;  // Per-module state.
854b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Index - Maps a method decl into a vtable index.  Useful for virtual
855b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// dispatch codegen.
856b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  llvm::DenseMap<const CXXMethodDecl *, int32_t> Index;
857552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump  typedef CXXRecordDecl::method_iterator method_iter;
8587c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic:
859eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder(std::vector<llvm::Constant *> &meth,
860eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                const CXXRecordDecl *c,
861eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                CodeGenModule &cgm)
862b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
863b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
864b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      CGM(cgm) {
8657c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
8667c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  }
86732f3701853a8237704065c77abc17369dd02c39bMike Stump
868b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
869b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                const CXXRecordDecl *RD,
870b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool VBoundary,
871b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool SecondaryVirtual) {
872b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    llvm::Constant *m = 0;
873b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
874b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    // FIXME: vcall: offset for virtual base for this function
875b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (SecondaryVirtual || VBoundary)
876b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      m = llvm::Constant::getNullValue(Ptr8Ty);
877b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    return m;
878b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  }
879b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
880b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
881b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                      bool SecondaryVirtual) {
8827c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    llvm::Constant *m;
8837c435fa7f7666b22abbe8494c537ebc25209223dMike Stump
884552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump    for (method_iter mi = RD->method_begin(),
8857c435fa7f7666b22abbe8494c537ebc25209223dMike Stump           me = RD->method_end(); mi != me; ++mi) {
8867c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      if (mi->isVirtual()) {
887b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
888b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        if (m)
889b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump          methods.push_back(m);
8907c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      }
8914c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump    }
89280a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump  }
8934c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump
8947fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
895b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump                            const CXXRecordDecl *RD, uint64_t Offset) {
8967fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
8977fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump           e = RD->bases_end(); i != e; ++i) {
8987fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      const CXXRecordDecl *Base =
8997fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
9007fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      if (i->isVirtual() && !SeenVBase.count(Base)) {
9017fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        SeenVBase.insert(Base);
902b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
9037fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        llvm::Constant *m;
904b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),BaseOffset);
9057fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
9067fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        offsets.push_back(m);
9077fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      }
908b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, Base, Offset);
9097fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    }
9107fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  }
9117fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump
912b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void StartNewTable() {
913b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    SeenVBase.clear();
914b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
91565defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump
916b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  inline uint32_t nottoobig(uint64_t t) {
917b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    assert(t < (uint32_t)-1ULL || "vtable too big");
918b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    return t;
919b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
920b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump#if 0
921b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  inline uint32_t nottoobig(uint32_t t) {
922b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    return t;
923b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
924b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump#endif
925b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
926b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void AddMethod(const CXXMethodDecl *MD, int32_t FirstIndex) {
927b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    typedef CXXMethodDecl::method_iterator meth_iter;
928b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
929b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    llvm::Constant *m;
930b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    m = CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty);
931b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
932b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
933b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // FIXME: Don't like the nested loops.  For very large inheritance
934b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // heirarchies we could have a table on the side with the final overridder
935b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // and just replace each instance of an overridden method once.  Would be
936b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // nice to measure the cost/benefit on real code.
937b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
938b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // If we can find a previously allocated slot for this, reuse it.
939b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (meth_iter mi = MD->begin_overridden_methods(),
940b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump           e = MD->end_overridden_methods();
941b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         mi != e; ++mi) {
942b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      const CXXMethodDecl *OMD = *mi;
943b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      llvm::Constant *om;
944b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = CGM.GetAddrOfFunction(GlobalDecl(OMD), Ptr8Ty);
945b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty);
946b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
947b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      for (int32_t i = FirstIndex, e = nottoobig(methods.size()); i != e; ++i) {
948b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        // FIXME: begin_overridden_methods might be too lax, covariance */
949b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        if (methods[i] == om) {
950b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          methods[i] = m;
951b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          Index[MD] = i;
952b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          return;
953b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        }
95465defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      }
955bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump    }
956b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
957b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // else allocate a new slot.
958b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    Index[MD] = methods.size();
959b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    methods.push_back(m);
960b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
961b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
962b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void GenerateMethods(const CXXRecordDecl *RD, int32_t FirstIndex) {
963b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
964b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         ++mi)
965b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      if (mi->isVirtual())
966b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        AddMethod(*mi, FirstIndex);
967bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump  }
968bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump
969109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForBase(const CXXRecordDecl *RD,
970109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             bool forPrimary,
971b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                             bool VBoundary,
972109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             int64_t Offset,
973b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                             bool ForVirtualBase,
974b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                             int32_t FirstIndex) {
975109b13db3391face0b393c730f0326ca51d25b52Mike Stump    llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
976276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
977109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (RD && !RD->isDynamicClass())
978109b13db3391face0b393c730f0326ca51d25b52Mike Stump      return;
979109b13db3391face0b393c730f0326ca51d25b52Mike Stump
980109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
981109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
982109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
983109b13db3391face0b393c730f0326ca51d25b52Mike Stump
984b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (VBoundary || forPrimary || ForVirtualBase) {
985b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      // then comes the the vcall offsets for all our functions...
986b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
987b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    }
988b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
989109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // The virtual base offsets come first...
990109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // FIXME: Audit, is this right?
99109765ece710f29dcdbd66eec361d60e53bd5a4fdMike Stump    if (PrimaryBase == 0 || forPrimary || !PrimaryBaseWasVirtual) {
992109b13db3391face0b393c730f0326ca51d25b52Mike Stump      std::vector<llvm::Constant *> offsets;
993b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, RD, Offset);
994109b13db3391face0b393c730f0326ca51d25b52Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
995109b13db3391face0b393c730f0326ca51d25b52Mike Stump             e = offsets.rend(); i != e; ++i)
996109b13db3391face0b393c730f0326ca51d25b52Mike Stump        methods.push_back(*i);
997276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    }
9984ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump
999109b13db3391face0b393c730f0326ca51d25b52Mike Stump    bool Top = true;
100002cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
1001109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // vtables are composed from the chain of primaries.
1002109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (PrimaryBase) {
1003109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (PrimaryBaseWasVirtual)
1004109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(PrimaryBase);
1005109b13db3391face0b393c730f0326ca51d25b52Mike Stump      Top = false;
1006b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
1007b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                            Offset, PrimaryBaseWasVirtual, FirstIndex);
1008109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1009276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1010109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (Top) {
1011109b13db3391face0b393c730f0326ca51d25b52Mike Stump      int64_t BaseOffset;
1012109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (ForVirtualBase) {
1013109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
1014109b13db3391face0b393c730f0326ca51d25b52Mike Stump      } else
1015109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -Offset/8;
1016109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
1017109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
1018109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(m);
1019109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(rtti);
1020109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1021276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1022109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // And add the virtuals for the class to the primary vtable.
1023b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    GenerateMethods(RD, FirstIndex);
1024109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1025109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // and then the non-virtual bases.
1026109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1027109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
1028109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual())
1029109b13db3391face0b393c730f0326ca51d25b52Mike Stump        continue;
1030109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
1031109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1032109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
1033109b13db3391face0b393c730f0326ca51d25b52Mike Stump        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
1034b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1035b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        FirstIndex = methods.size();
1036b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        GenerateVtableForBase(Base, true, false, o, false, FirstIndex);
1037109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1038109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1039276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
1040276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1041109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForVBases(const CXXRecordDecl *RD,
1042ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump                               const CXXRecordDecl *Class) {
1043109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1044109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
1045109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
1046109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1047109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !IndirectPrimary.count(Base)) {
1048109b13db3391face0b393c730f0326ca51d25b52Mike Stump        // Mark it so we don't output it twice.
1049109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(Base);
1050b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1051b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
1052b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        int32_t FirstIndex = methods.size();
1053b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        GenerateVtableForBase(Base, false, true, BaseOffset, true, FirstIndex);
1054109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1055109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base->getNumVBases())
1056ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump        GenerateVtableForVBases(Base, Class);
1057109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1058e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
1059109b13db3391face0b393c730f0326ca51d25b52Mike Stump};
10608a12b564923a72224730a467007e61b5701e4aa7Mike Stump
1061f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
1062f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
1063f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
1064f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
1065e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
1066f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
106782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
106882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
106982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
1070276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
10716f376336138ea719e3c4757ae046a5768043b276Mike Stump  int64_t Offset = 0;
1072e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
1073e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
1074e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
10756f376336138ea719e3c4757ae046a5768043b276Mike Stump
1076eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder b(methods, RD, CGM);
1077109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1078276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // First comes the vtables for all the non-virtual bases...
1079b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  b.GenerateVtableForBase(RD, true, false, 0, false, 0);
108070101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
1081276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // then the vtables for all the virtual bases.
1082ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  b.GenerateVtableForVBases(RD, RD);
10836f376336138ea719e3c4757ae046a5768043b276Mike Stump
108482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
108582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
108682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
108782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
10887765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                                 linktype, C, Out.str());
1089f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
1090f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
1091276b9f1d814f4f6551cc3000590759a34185d6daMike Stump                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
10926f376336138ea719e3c4757ae046a5768043b276Mike Stump                                                    Offset/8));
1093f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
1094f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
1095f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
1096eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class
1097eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// array of objects from SrcValue to DestValue. Copying can be either a bitwise
1098eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// copy or via a copy constructor call.
1099eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanianvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest,
1100eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            llvm::Value *Src,
1101eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            const ArrayType *Array,
1102eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            const CXXRecordDecl *BaseClassDecl,
1103eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                            QualType Ty) {
1104eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1105eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  assert(CA && "VLA cannot be copied over");
1106eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor();
1107eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1108eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1109eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1110eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                           "loop.index");
1111eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value* zeroConstant =
1112eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1113eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    Builder.CreateStore(zeroConstant, IndexPtr, false);
1114eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Start the loop with a block that tests the condition.
1115eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1116eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
1117eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1118eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(CondBlock);
1119eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1120eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1121eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1122eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // otherwise, go to the block after the for-loop.
1123eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
1124eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value * NumElementsPtr =
1125eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1126eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
1127eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1128eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                              "isless");
1129eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // If the condition is true, execute the body.
1130eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
1131eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1132eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ForBody);
1133eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1134eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
1135eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1136eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1137eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1138eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  if (BitwiseCopy)
1139eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1140eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  else if (CXXConstructorDecl *BaseCopyCtor =
1141eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian           BaseClassDecl->getCopyConstructor(getContext(), 0)) {
1142eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1143eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                                      Ctor_Complete);
1144eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgList CallArgs;
1145eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the this (Dest) ptr.
1146eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1147eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
1148eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1149eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    // Push the Src ptr.
1150eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1151eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                      BaseCopyCtor->getParamDecl(0)->getType()));
1152eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    QualType ResultType =
1153eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1154eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1155eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1156eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  }
1157eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(ContinueBlock);
1158eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1159eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the increment of the loop counter.
1160eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1161eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1162eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1163eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
1164eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1165eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1166eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBranch(CondBlock);
1167eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1168eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  // Emit the fall-through block.
1169eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian  EmitBlock(AfterFor, true);
1170eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian}
1171eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
1172c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// EmitClassAggrCopyAssignment - This routine generates code to assign a class
1173c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// array of objects from SrcValue to DestValue. Assignment can be either a
1174c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// bitwise assignment or via a copy assignment operator function call.
1175c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy
1176c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanianvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest,
1177c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            llvm::Value *Src,
1178c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            const ArrayType *Array,
1179c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            const CXXRecordDecl *BaseClassDecl,
1180c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                            QualType Ty) {
1181c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
1182c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  assert(CA && "VLA cannot be asssigned");
1183c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment();
1184c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1185c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Create a temporary for the loop index and initialize it with 0.
1186c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
1187c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                           "loop.index");
1188c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value* zeroConstant =
1189c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
1190c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(zeroConstant, IndexPtr, false);
1191c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Start the loop with a block that tests the condition.
1192c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
1193c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
1194c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1195c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(CondBlock);
1196c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1197c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
1198c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Generate: if (loop-index < number-of-elements fall to the loop body,
1199c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // otherwise, go to the block after the for-loop.
1200c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  uint64_t NumElements = getContext().getConstantArrayElementCount(CA);
1201c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value * NumElementsPtr =
1202c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements);
1203c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
1204c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr,
1205c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                              "isless");
1206c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // If the condition is true, execute the body.
1207c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateCondBr(IsLess, ForBody, AfterFor);
1208c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1209c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ForBody);
1210c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
1211c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Inside the loop body, emit the assignment operator call on array element.
1212c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1213c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress");
1214c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress");
1215c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  const CXXMethodDecl *MD = 0;
1216c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  if (BitwiseAssign)
1217c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1218c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  else {
1219c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    bool hasCopyAssign = BaseClassDecl->hasConstCopyAssignment(getContext(),
1220c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                                               MD);
1221c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    assert(hasCopyAssign && "EmitClassAggrCopyAssignment - No user assign");
1222c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    (void)hasCopyAssign;
1223c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1224c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const llvm::Type *LTy =
1225c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1226c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                   FPT->isVariadic());
1227c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
1228c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1229c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgList CallArgs;
1230c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the this (Dest) ptr.
1231c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1232c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getThisType(getContext())));
1233c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1234c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    // Push the Src ptr.
1235c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1236c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                      MD->getParamDecl(0)->getType()));
1237c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    QualType ResultType =
1238c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
1239c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1240c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian             Callee, CallArgs, MD);
1241c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  }
1242c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(ContinueBlock);
1243c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1244c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the increment of the loop counter.
1245c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
1246c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
1247c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
1248c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
1249c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1250c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
1251c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBranch(CondBlock);
1252c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1253c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  // Emit the fall-through block.
1254c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian  EmitBlock(AfterFor, true);
1255c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian}
1256c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian
1257ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
1258ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
1259eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// or via a copy constructor call.
1260ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
1261942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
1262ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                        const CXXRecordDecl *ClassDecl,
1263942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
1264942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
1265942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
1266942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
1267942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1268942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
1269942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1270ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
1271942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1272942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
1273ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  if (CXXConstructorDecl *BaseCopyCtor =
127480e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
1275ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1276ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
1277ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
1278ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
1279ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1280ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
1281ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
1282ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
1283ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1284370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian                       BaseCopyCtor->getParamDecl(0)->getType()));
1285ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    QualType ResultType =
1286ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1287ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1288ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1289ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
1290ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
129106f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
12920270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class
12930270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// object from SrcValue to DestValue. Assignment can be either a bitwise
12940270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call.
1295c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot.
12960270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment(
12970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        llvm::Value *Dest, llvm::Value *Src,
12980270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *ClassDecl,
12990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *BaseClassDecl,
13000270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        QualType Ty) {
13010270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (ClassDecl) {
13020270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
13030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
13040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
13050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyAssignment()) {
13060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
13070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    return;
13080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
13090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXMethodDecl *MD = 0;
1311e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(),
1312e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                                                 MD);
1313e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign");
1314e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  (void)ConstCopyAssignOp;
1315e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian
1316e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1317e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const llvm::Type *LTy =
1318e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1319e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                   FPT->isVariadic());
1320e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
13210270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1322e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgList CallArgs;
1323e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the this (Dest) ptr.
1324e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Dest),
1325e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getThisType(getContext())));
13260270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1327e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the Src ptr.
1328e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Src),
1329e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getParamDecl(0)->getType()));
1330e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  QualType ResultType =
1331e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
1332e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1333e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian           Callee, CallArgs, MD);
13340270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian}
13350270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
133606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor
133706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanianvoid
133806f598aa45b651f9f3be0b916d43876eae747af0Fariborz JahanianCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *CD,
133906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionDecl *FD,
134006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              llvm::Function *Fn,
134106f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionArgList &Args) {
134206f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
134306f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  EmitCtorPrologue(CD);
134406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  FinishFunction();
134506f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian}
134606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
13478c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
134897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
134997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise
135097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order
135197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
135297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
135397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of class type, the copy constructor for the class is
135497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
135597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is an array, each element is copied, in the manner
135697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
135797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of scalar type, the built-in assignment operator is
135897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
135997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the
136097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor
136197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
13628c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
13638c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
13648c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
1365ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
136697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
136797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
13688c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
13698c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
137097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
13711e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
13721e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
13731e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
13741e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
13751e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
13761e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
13771e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
13781e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
137997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
138097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
138197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
138297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
138397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
1384ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
138597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
138697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1387942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
1388942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
138997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
139097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
13911e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
13921e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
13931e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
13941e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1395eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    const ConstantArrayType *Array =
1396eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1397eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian    if (Array)
1398eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
1399eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian
14001e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
14011e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
14021e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
14031e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
14041e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1405eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      if (Array) {
1406eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1407eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1408eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        llvm::Value *DestBaseAddrPtr =
1409eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1410eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        llvm::Value *SrcBaseAddrPtr =
1411eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1412eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1413eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                    FieldClassDecl, FieldType);
1414eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      }
1415eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian      else
1416eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
1417eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian                                0 /*ClassDecl*/, FieldClassDecl, FieldType);
14181e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
14191e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
1420f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    // Do a built-in assignment of scalar data members.
1421f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1422f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1423f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
1424f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
14251e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
14268c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
142797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian}
142897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
14292198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
14302198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// Before the implicitly-declared copy assignment operator for a class is
14312198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined, all implicitly- declared copy assignment operators for
14322198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// its direct base classes and its nonstatic data members shall have been
14332198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12]
14342198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// The implicitly-defined copy assignment operator for class X performs
14352198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// memberwise assignment of its subob- jects. The direct base classes of X are
14362198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// assigned first, in the order of their declaration in
14372198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// the base-specifier-list, and then the immediate nonstatic data members of X
14382198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// are assigned, in the order in which they were declared in the class
14392198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type:
14400270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of class type, the copy assignment operator for the
14410270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   class is used (as if by explicit qualification; that is, ignoring any
14422198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   possible virtual overriding functions in more derived classes);
14430270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
14440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is an array, each element is assigned, in the manner
14452198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   appropriate to the element type;
14460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
14470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of scalar type, the built-in assignment operator is
14482198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   used.
14492198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
14502198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionDecl *FD,
14512198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  llvm::Function *Fn,
14522198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionArgList &Args) {
14530270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
14540270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
14550270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
14560270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
14572198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
14582198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian
14590270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
14600270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *ThisArg = i->first;
14610270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
14620270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
14630270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
14640270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
14650270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
14660270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
14670270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
14680270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
14690270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
14700270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (Base->isVirtual())
14710270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
14720270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
14730270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
14740270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
14750270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
14760270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                            Base->getType());
14770270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
14780270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
14790270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
14800270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
14810270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Field != FieldEnd; ++Field) {
14820270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1483c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    const ConstantArrayType *Array =
1484c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      getContext().getAsConstantArrayType(FieldType);
1485c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian    if (Array)
1486c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
14870270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
14880270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
14890270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      CXXRecordDecl *FieldClassDecl
14900270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(FieldClassType->getDecl());
14910270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
14920270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1493c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      if (Array) {
1494c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1495c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1496c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *DestBaseAddrPtr =
1497c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1498c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        llvm::Value *SrcBaseAddrPtr =
1499c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian          Builder.CreateBitCast(RHS.getAddress(), BasePtr);
1500c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array,
1501c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                                    FieldClassDecl, FieldType);
1502c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      }
1503c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian      else
1504c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian        EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
1505c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian                               0 /*ClassDecl*/, FieldClassDecl, FieldType);
15060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
15070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    }
15080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // Do a built-in assignment of scalar data members.
15090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
15100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
15110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
15120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
1513183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  }
1514183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian
1515183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  // return *this;
1516183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  Builder.CreateStore(LoadOfThis, ReturnValue);
15170270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
15182198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  FinishFunction();
15192198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian}
152097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
1521e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
1522e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
1523e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
1524742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
1525eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
1526f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
15276d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
1528742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1529e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
1530e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
1531e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
1532e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
1533f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
15346d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
15356d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
15366217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
15376d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
15386d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
1539742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
1540742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
1541742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
1542742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
1543b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1544e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
1545e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
1546e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
154764a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian      const ConstantArrayType *Array =
1548eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
154964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian      if (Array)
155064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
15518c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian
1552f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1553e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
15546217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
1555e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        if (!Field->isAnonymousStructOrUnion()) {
155650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
155750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
155864a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          if (Array) {
155964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            const llvm::Type *BasePtr = ConvertType(FieldType);
156064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            BasePtr = llvm::PointerType::getUnqual(BasePtr);
156164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            llvm::Value *BaseAddrPtr =
156264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
156364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            EmitCXXAggrConstructorCall(Member->getConstructor(),
156464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                       Array, BaseAddrPtr);
156564a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          }
156664a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian          else
156764a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian            EmitCXXConstructorCall(Member->getConstructor(),
156864a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Ctor_Complete, LHS.getAddress(),
156964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Member->const_arg_begin(),
157064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian                                   Member->const_arg_end());
1571e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          continue;
1572e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
1573e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        else {
1574e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          // Initializing an anonymous union data member.
1575e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldDecl *anonMember = Member->getAnonUnionMember();
1576e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          LHS = EmitLValueForField(LHS.getAddress(), anonMember, false, 0);
1577e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldType = anonMember->getType();
1578e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
157950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
1580e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
1581e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
158250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
1583e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
15848c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian      EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
1585e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
1586e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
1587f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
15880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
15891d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    // Nontrivial default constructor with no initializer list. It may still
15900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // have bases classes and/or contain non-static data members which require
15910880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // construction.
15920880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (CXXRecordDecl::base_class_const_iterator Base =
15930880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          ClassDecl->bases_begin();
15940880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          Base != ClassDecl->bases_end(); ++Base) {
15950880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      // FIXME. copy assignment of virtual base NYI
15960880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (Base->isVirtual())
15970880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
15980880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15990880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *BaseClassDecl
16000880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
16010880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (BaseClassDecl->hasTrivialConstructor())
16020880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
16030880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *BaseCX =
16040880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            BaseClassDecl->getDefaultConstructor(getContext())) {
16050880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
16060880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
16070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                               BaseClassDecl);
16080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
16090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      }
16100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
16110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
16121d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
16131d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         FieldEnd = ClassDecl->field_end();
16141d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         Field != FieldEnd; ++Field) {
16151d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1616288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian      const ConstantArrayType *Array =
1617288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1618f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1619f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
16201d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
16211d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian        continue;
16221d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      const RecordType *ClassRec = FieldType->getAs<RecordType>();
16230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *MemberClassDecl =
16240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
16250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor())
16260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
16270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *MamberCX =
16280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            MemberClassDecl->getDefaultConstructor(getContext())) {
16290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
16300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1631288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        if (Array) {
1632288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          const llvm::Type *BasePtr = ConvertType(FieldType);
1633288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          BasePtr = llvm::PointerType::getUnqual(BasePtr);
1634288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          llvm::Value *BaseAddrPtr =
1635288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1636288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr);
1637288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        }
1638288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        else
1639288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(),
1640288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                 0, 0);
16411d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      }
16421d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    }
16430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
16440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
1645f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
1646b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
1647f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
1648f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1649f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
1650f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
16510032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1652f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
1653f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
1654f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
1655f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
1656f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
1657e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
1658426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1659426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
1660426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
1661426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
1662426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
1663426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
1664426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
1665426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
1666426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
1667426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1668426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
1669426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
1670426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
1671426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
1672426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
1673426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
1674f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1675f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1676f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1677f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
1678426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
1679426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1680426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
1681426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1682426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
1683426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
1684f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1685f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1686f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1687f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1688f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1689f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1690f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1691f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1692f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1693f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1694f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
1695b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1696426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
1697426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
1698426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1699426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
1700426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1701426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
1702426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
1703426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
1704426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
1705426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
1706426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
17070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial())
17080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
17090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // Case of destructor synthesis with fields and base classes
17100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // which have non-trivial destructors. They must be destructed in
17110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // reverse order of their construction.
17120880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<FieldDecl *, 16> DestructedFields;
17130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
17150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
17160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Field != FieldEnd; ++Field) {
17170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1718f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian    if (getContext().getAsConstantArrayType(FieldType))
1719f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
17200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (const RecordType *RT = FieldType->getAs<RecordType>()) {
17210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
17220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
17230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
17240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      DestructedFields.push_back(*Field);
17250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
17260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
17270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!DestructedFields.empty())
17280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (int i = DestructedFields.size() -1; i >= 0; --i) {
17290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      FieldDecl *Field = DestructedFields[i];
17300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      QualType FieldType = Field->getType();
1731f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1732f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1733f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        if (Array)
1734f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          FieldType = getContext().getBaseElementType(FieldType);
17350880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
17360880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
17370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
17380880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
1739f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1740f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1741f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1742f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1743f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1744f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1745f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1746f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1747f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1748f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1749f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
17500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
17510880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17520880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
17530880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
17540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
17550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
17560880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (Base->isVirtual())
17570880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
17580880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17590880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
17600880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
17610880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (BaseClassDecl->hasTrivialDestructor())
17620880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
17630880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    DestructedBases.push_back(BaseClassDecl);
17640880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
17650880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DestructedBases.empty())
17660880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
17670880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (int i = DestructedBases.size() -1; i >= 0; --i) {
17680880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl = DestructedBases[i];
17690880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
17700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                           ClassDecl,BaseClassDecl);
17710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
17720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                          Dtor_Complete, V);
17730880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
1774426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
17750880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17760880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanianvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *CD,
17770880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionDecl *FD,
17780880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  llvm::Function *Fn,
17790880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionArgList &Args) {
17800880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17810880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
17820880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredDestructor() &&
17830880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian         "SynthesizeDefaultDestructor - destructor has user declaration");
17840880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  (void) ClassDecl;
17850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
17860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
17870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  EmitDtorEpilogue(CD);
17880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  FinishFunction();
17890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian}
1790