CGCXX.cpp revision b9871a253d351e8776cfa5483d6330d5dffe4562
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.
349288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext),
350288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                           "loop.index");
351288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value* zeroConstant =
352288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt32Ty(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 =
367288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::ConstantInt::get(llvm::Type::getInt32Ty(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())) {
3816147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    uint32_t delta = 1;
3826147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    const ConstantArrayType *CAW = CAT;
3836147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    do {
3846147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian      delta *= CAW->getSize().getZExtValue();
3856147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian      CAW = dyn_cast<ConstantArrayType>(CAW->getElementType());
3866147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    } while (CAW);
387995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian    // Address = This + delta*Counter for current loop iteration.
3886147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *DeltaPtr =
3896147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), delta);
3906147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    DeltaPtr = Builder.CreateMul(Counter, DeltaPtr, "mul");
3916147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *Address =
3926147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian      Builder.CreateInBoundsGEP(This, DeltaPtr, "arrayidx");
393288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian    EmitCXXAggrConstructorCall(D, CAT, Address);
394288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  }
3956147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian  else {
3966147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian    llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
397288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian    EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0);
3986147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian  }
3996147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian
400288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(ContinueBlock);
401288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
402288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the increment of the loop counter.
403288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
404288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
405288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  NextVal = Builder.CreateAdd(Counter, NextVal, "inc");
406288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  Builder.CreateStore(NextVal, IndexPtr, false);
407288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
408288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
409288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBranch(CondBlock);
410288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
411288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  // Emit the fall-through block.
412288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian  EmitBlock(AfterFor, true);
413288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian}
414288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian
4151c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// EmitCXXAggrDestructorCall - calls the default destructor on array
4161c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// elements in reverse order of construction.
417b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
418f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz JahanianCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
419f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           const ArrayType *Array,
420f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                           llvm::Value *This) {
4211c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
4221c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  assert(CA && "Do we support VLA for destruction ?");
4231c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
4241c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            1);
4251c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  uint64_t ElementCount = 1;
4261c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  const ConstantArrayType *CAW = CA;
4271c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  do {
4281c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    ElementCount *= CAW->getSize().getZExtValue();
4291c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    CAW = dyn_cast<ConstantArrayType>(CAW->getElementType());
4301c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  } while (CAW);
4311c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Create a temporary for the loop index and initialize it with count of
4321c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // array elements.
4331c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
4341c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                           "loop.index");
4351c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Index = ElementCount;
4361c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* UpperCount =
4371c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
4381c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(UpperCount, IndexPtr, false);
4391c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4401c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Start the loop with a block that tests the condition.
4411c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
4421c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *AfterFor = createBasicBlock("for.end");
4431c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4441c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(CondBlock);
4451c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4461c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ForBody = createBasicBlock("for.body");
4471c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4481c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Generate: if (loop-index != 0 fall to the loop body,
4491c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // otherwise, go to the block after the for-loop.
4501c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value* zeroConstant =
4511c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
4521c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
4531c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
4541c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian                                            "isne");
4551c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // If the condition is true, execute the body.
4561c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateCondBr(IsNE, ForBody, AfterFor);
4571c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4581c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ForBody);
4591c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4601c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc");
4611c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Inside the loop body, emit the constructor call on the array element.
4621c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4631c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One);
4641c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx");
4651c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitCXXDestructorCall(D, Dtor_Complete, Address);
4661c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4671c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(ContinueBlock);
4681c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4691c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the decrement of the loop counter.
4701c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateLoad(IndexPtr);
4711c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Counter = Builder.CreateSub(Counter, One, "dec");
4721c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  Builder.CreateStore(Counter, IndexPtr, false);
4731c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4741c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Finally, branch back up to the condition for the next iteration.
4751c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBranch(CondBlock);
4761c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian
4771c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  // Emit the fall-through block.
4781c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian  EmitBlock(AfterFor, true);
479f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian}
480f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian
481f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanianvoid
482b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
483b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
484b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
485b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
486b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
487343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  if (D->isCopyConstructor(getContext())) {
488343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
489343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    if (ClassDecl->hasTrivialCopyConstructor()) {
490343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
491343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian             "EmitCXXConstructorCall - user declared copy constructor");
492343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      const Expr *E = (*ArgBeg);
493343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      QualType Ty = E->getType();
494343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      llvm::Value *Src = EmitLValue(E).getAddress();
495343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
496343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      return;
497343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    }
498343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  }
499343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian
500b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
501b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
502b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
503b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
504b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
5057267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
5067267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
5077267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
5087267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
5097267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
5107267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
5117267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
5127267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
513b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
51431ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
51531ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
516b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
517b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
518b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
5196217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
520b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
521b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
5226904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
5236904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // Code gen optimization to eliminate copy constructor and return
5246904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
5251cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian  if (E->isElidable()) {
5266904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
5271cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
5281cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
5296904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
530b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
531b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
532b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
533b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
534b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
535a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
536ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
537ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
53803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
539ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
540ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
541ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
542ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
543ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
544ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
545ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
546ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
547ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
548ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
549ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
5504a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
551ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
552ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
553ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
554ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
555ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
556ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
557ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
558ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
559ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
560ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
561ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
562ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
563ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
564ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
565ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
566ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
567ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
568ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
569ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
570ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
571ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
572ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
573ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
574ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
575ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
576ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
577ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
578ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
579ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
580ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
581ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
582ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
583ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
584ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
585ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
586ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
587ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
588ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
589ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
590ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
591ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
592ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
593ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
594d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
595d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
596d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
597d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
598d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
599d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
600ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
601f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
602f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
603f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
604f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
605f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
606f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
607d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
608f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
609f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
610f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
611f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
612f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
613f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
614c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
615f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
616f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
617f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
618f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
619d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
620d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
621f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
622d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
6236d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
624215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
6256d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
6266d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
6276d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6286d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
6296d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
6303923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
6316d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
6323923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
6333923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
634627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
635627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
6366d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
637d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
638d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
639d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
6406d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
641d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
642d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
643d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
644ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
645d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
646f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
647f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
648f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
649f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
650f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
651f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
652f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
653f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
654f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
655c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
656f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
657f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
658f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
659f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
660d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
661a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
662a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
66360e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
66460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (E->isArrayForm()) {
66560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    ErrorUnsupported(E, "delete[] expression");
66660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    return;
66760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  };
66860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
66960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType DeleteTy =
67060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
67160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
67360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Null check the pointer.
67560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
67660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
67760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
67860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *IsNull =
67960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
68060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                         "isnull");
68160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
68360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteNotNull);
68460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
68560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call the destructor if necessary.
68660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
68760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
68860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      if (!RD->hasTrivialDestructor()) {
68960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
69060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        if (Dtor->isVirtual()) {
69160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          ErrorUnsupported(E, "delete expression with virtual destructor");
69260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          return;
69360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        }
69460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
69560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
69660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      }
69760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    }
69860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  }
69960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call delete.
70160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  FunctionDecl *DeleteFD = E->getOperatorDelete();
70260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  const FunctionProtoType *DeleteFTy =
70360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    DeleteFD->getType()->getAsFunctionProtoType();
70460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  CallArgList DeleteArgs;
70660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
70760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType ArgTy = DeleteFTy->getArgType(0);
70860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
70960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
71060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Emit the call to delete.
71260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
71360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                                          DeleteArgs),
71460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)),
71560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           DeleteArgs, DeleteFD);
71660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
71760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteEnd);
71860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson}
71960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
72027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
72127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
72259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
72359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
72459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
72559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
72617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
72717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
72859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
72959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
73059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
73159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
73259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
73359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
73459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
73559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
73695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
73727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
73859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
73959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
74059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
74195d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
7422a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
7432a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
74495d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
745363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
74627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
74727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
74827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
74927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
75027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
75127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
75227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
75327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
75427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
75527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
75627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
757363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
758363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
759363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
760363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
761363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
762363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
763363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
764b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
765b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
766363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
76727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
76827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
76927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
77027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
77127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
77227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
77327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
77527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
77627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
77727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
77827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
77927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
78027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
78127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
78227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
78327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
78527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
78627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
78727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
78827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
78927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
79027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
79127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
79327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
79527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
79627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
79727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
79827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
79927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
80027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
80127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
80227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
80327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
80427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
805b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
806b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
80727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
80827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
80927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
81027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
81127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
81227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
81327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
81427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
81527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
81627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
81727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
818e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
81932f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
820738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
8210032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
822cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
823738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
824738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
825cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
826738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
827738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
828738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
829738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
830e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
831738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
832738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
833738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
834738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
8354ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti descriptor");
836738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
837738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
8384ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti ts");
839738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
840738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
841738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
842738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
843738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
844738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
84532f3701853a8237704065c77abc17369dd02c39bMike Stump  Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C,
8467765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                  Out.str());
847cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
848cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
849738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
850738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
851eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stumpclass VtableBuilder {
8527c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  std::vector<llvm::Constant *> &methods;
8537c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::Type *Ptr8Ty;
854b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Class - The most derived class that this vtable is being built for.
85532f3701853a8237704065c77abc17369dd02c39bMike Stump  const CXXRecordDecl *Class;
856b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// BLayout - Layout for the most derived class that this vtable is being
857b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// built for.
858b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  const ASTRecordLayout &BLayout;
859ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
8607fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
86132f3701853a8237704065c77abc17369dd02c39bMike Stump  llvm::Constant *rtti;
8627c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::LLVMContext &VMContext;
86365defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  CodeGenModule &CGM;  // Per-module state.
864b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// Index - Maps a method decl into a vtable index.  Useful for virtual
865b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  /// dispatch codegen.
866b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  llvm::DenseMap<const CXXMethodDecl *, int32_t> Index;
867552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump  typedef CXXRecordDecl::method_iterator method_iter;
8687c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic:
869eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder(std::vector<llvm::Constant *> &meth,
870eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                const CXXRecordDecl *c,
871eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump                CodeGenModule &cgm)
872b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
873b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
874b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      CGM(cgm) {
8757c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
8767c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  }
87732f3701853a8237704065c77abc17369dd02c39bMike Stump
878b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
879b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                const CXXRecordDecl *RD,
880b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool VBoundary,
881b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool SecondaryVirtual) {
882b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    llvm::Constant *m = 0;
883b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
884b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    // FIXME: vcall: offset for virtual base for this function
885b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (SecondaryVirtual || VBoundary)
886b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      m = llvm::Constant::getNullValue(Ptr8Ty);
887b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    return m;
888b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  }
889b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
890b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
891b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                      bool SecondaryVirtual) {
8927c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    llvm::Constant *m;
8937c435fa7f7666b22abbe8494c537ebc25209223dMike Stump
894552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump    for (method_iter mi = RD->method_begin(),
8957c435fa7f7666b22abbe8494c537ebc25209223dMike Stump           me = RD->method_end(); mi != me; ++mi) {
8967c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      if (mi->isVirtual()) {
897b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
898b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        if (m)
899b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump          methods.push_back(m);
9007c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      }
9014c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump    }
90280a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump  }
9034c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump
9047fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
905b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump                            const CXXRecordDecl *RD, uint64_t Offset) {
9067fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
9077fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump           e = RD->bases_end(); i != e; ++i) {
9087fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      const CXXRecordDecl *Base =
9097fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
9107fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      if (i->isVirtual() && !SeenVBase.count(Base)) {
9117fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        SeenVBase.insert(Base);
912b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
9137fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        llvm::Constant *m;
914b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),BaseOffset);
9157fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
9167fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump        offsets.push_back(m);
9177fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump      }
918b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, Base, Offset);
9197fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump    }
9207fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump  }
9217fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump
922b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void StartNewTable() {
923b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    SeenVBase.clear();
924b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
92565defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump
926b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  inline uint32_t nottoobig(uint64_t t) {
927b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    assert(t < (uint32_t)-1ULL || "vtable too big");
928b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    return t;
929b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
930b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump#if 0
931b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  inline uint32_t nottoobig(uint32_t t) {
932b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    return t;
933b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
934b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump#endif
935b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
936b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void AddMethod(const CXXMethodDecl *MD, int32_t FirstIndex) {
937b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    typedef CXXMethodDecl::method_iterator meth_iter;
938b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
939b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    llvm::Constant *m;
940b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    m = CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty);
941b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
942b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
943b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // FIXME: Don't like the nested loops.  For very large inheritance
944b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // heirarchies we could have a table on the side with the final overridder
945b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // and just replace each instance of an overridden method once.  Would be
946b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // nice to measure the cost/benefit on real code.
947b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
948b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // If we can find a previously allocated slot for this, reuse it.
949b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (meth_iter mi = MD->begin_overridden_methods(),
950b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump           e = MD->end_overridden_methods();
951b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         mi != e; ++mi) {
952b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      const CXXMethodDecl *OMD = *mi;
953b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      llvm::Constant *om;
954b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = CGM.GetAddrOfFunction(GlobalDecl(OMD), Ptr8Ty);
955b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty);
956b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
957b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      for (int32_t i = FirstIndex, e = nottoobig(methods.size()); i != e; ++i) {
958b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        // FIXME: begin_overridden_methods might be too lax, covariance */
959b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        if (methods[i] == om) {
960b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          methods[i] = m;
961b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          Index[MD] = i;
962b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump          return;
963b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        }
96465defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      }
965bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump    }
966b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
967b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    // else allocate a new slot.
968b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    Index[MD] = methods.size();
969b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    methods.push_back(m);
970b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  }
971b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump
972b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  void GenerateMethods(const CXXRecordDecl *RD, int32_t FirstIndex) {
973b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
974b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump         ++mi)
975b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump      if (mi->isVirtual())
976b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        AddMethod(*mi, FirstIndex);
977bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump  }
978bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump
979109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForBase(const CXXRecordDecl *RD,
980109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             bool forPrimary,
981b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                             bool VBoundary,
982109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             int64_t Offset,
983b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                             bool ForVirtualBase,
984b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                             int32_t FirstIndex) {
985109b13db3391face0b393c730f0326ca51d25b52Mike Stump    llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
986276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
987109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (RD && !RD->isDynamicClass())
988109b13db3391face0b393c730f0326ca51d25b52Mike Stump      return;
989109b13db3391face0b393c730f0326ca51d25b52Mike Stump
990109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
991109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
992109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
993109b13db3391face0b393c730f0326ca51d25b52Mike Stump
994b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (VBoundary || forPrimary || ForVirtualBase) {
995b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      // then comes the the vcall offsets for all our functions...
996b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
997b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    }
998b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
999109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // The virtual base offsets come first...
1000109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // FIXME: Audit, is this right?
100109765ece710f29dcdbd66eec361d60e53bd5a4fdMike Stump    if (PrimaryBase == 0 || forPrimary || !PrimaryBaseWasVirtual) {
1002109b13db3391face0b393c730f0326ca51d25b52Mike Stump      std::vector<llvm::Constant *> offsets;
1003b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump      GenerateVBaseOffsets(offsets, RD, Offset);
1004109b13db3391face0b393c730f0326ca51d25b52Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
1005109b13db3391face0b393c730f0326ca51d25b52Mike Stump             e = offsets.rend(); i != e; ++i)
1006109b13db3391face0b393c730f0326ca51d25b52Mike Stump        methods.push_back(*i);
1007276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    }
10084ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump
1009109b13db3391face0b393c730f0326ca51d25b52Mike Stump    bool Top = true;
101002cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
1011109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // vtables are composed from the chain of primaries.
1012109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (PrimaryBase) {
1013109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (PrimaryBaseWasVirtual)
1014109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(PrimaryBase);
1015109b13db3391face0b393c730f0326ca51d25b52Mike Stump      Top = false;
1016b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
1017b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump                            Offset, PrimaryBaseWasVirtual, FirstIndex);
1018109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1019276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1020109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (Top) {
1021109b13db3391face0b393c730f0326ca51d25b52Mike Stump      int64_t BaseOffset;
1022109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (ForVirtualBase) {
1023109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
1024109b13db3391face0b393c730f0326ca51d25b52Mike Stump      } else
1025109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -Offset/8;
1026109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
1027109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
1028109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(m);
1029109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(rtti);
1030109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1031276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1032109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // And add the virtuals for the class to the primary vtable.
1033b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump    GenerateMethods(RD, FirstIndex);
1034109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1035109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // and then the non-virtual bases.
1036109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1037109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
1038109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual())
1039109b13db3391face0b393c730f0326ca51d25b52Mike Stump        continue;
1040109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
1041109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1042109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
1043109b13db3391face0b393c730f0326ca51d25b52Mike Stump        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
1044b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1045b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        FirstIndex = methods.size();
1046b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        GenerateVtableForBase(Base, true, false, o, false, FirstIndex);
1047109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1048109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1049276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
1050276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
1051109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForVBases(const CXXRecordDecl *RD,
1052ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump                               const CXXRecordDecl *Class) {
1053109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1054109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
1055109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
1056109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1057109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !IndirectPrimary.count(Base)) {
1058109b13db3391face0b393c730f0326ca51d25b52Mike Stump        // Mark it so we don't output it twice.
1059109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(Base);
1060b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        StartNewTable();
1061b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump        int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
1062b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        int32_t FirstIndex = methods.size();
1063b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump        GenerateVtableForBase(Base, false, true, BaseOffset, true, FirstIndex);
1064109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
1065109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base->getNumVBases())
1066ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump        GenerateVtableForVBases(Base, Class);
1067109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
1068e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
1069109b13db3391face0b393c730f0326ca51d25b52Mike Stump};
10708a12b564923a72224730a467007e61b5701e4aa7Mike Stump
1071f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
1072f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
1073f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
1074f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
1075e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
1076f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
107782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
107882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
107982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
1080276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
10816f376336138ea719e3c4757ae046a5768043b276Mike Stump  int64_t Offset = 0;
1082e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
1083e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
1084e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
10856f376336138ea719e3c4757ae046a5768043b276Mike Stump
1086eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump  VtableBuilder b(methods, RD, CGM);
1087109b13db3391face0b393c730f0326ca51d25b52Mike Stump
1088276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // First comes the vtables for all the non-virtual bases...
1089b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump  b.GenerateVtableForBase(RD, true, false, 0, false, 0);
109070101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
1091276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // then the vtables for all the virtual bases.
1092ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump  b.GenerateVtableForVBases(RD, RD);
10936f376336138ea719e3c4757ae046a5768043b276Mike Stump
109482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
109582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
109682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
109782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
10987765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar                                                 linktype, C, Out.str());
1099f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
1100f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
1101276b9f1d814f4f6551cc3000590759a34185d6daMike Stump                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
11026f376336138ea719e3c4757ae046a5768043b276Mike Stump                                                    Offset/8));
1103f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
1104f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
1105f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
1106ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
1107ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
1108ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// of via a copy constructor call.
1109ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
1110942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
1111ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                        const CXXRecordDecl *ClassDecl,
1112942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
1113942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
1114942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
1115942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
1116942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1117942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
1118942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
1119ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
1120942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
1121942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
1122ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  if (CXXConstructorDecl *BaseCopyCtor =
112380e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
1124ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
1125ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
1126ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
1127ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
1128ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
1129ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
1130ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
1131ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
1132ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
1133370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian                       BaseCopyCtor->getParamDecl(0)->getType()));
1134ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    QualType ResultType =
1135ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
1136ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1137ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
1138ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
1139ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
114006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
11410270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class
11420270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// object from SrcValue to DestValue. Assignment can be either a bitwise
11430270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call.
11440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment(
11450270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        llvm::Value *Dest, llvm::Value *Src,
11460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *ClassDecl,
11470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *BaseClassDecl,
11480270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        QualType Ty) {
11490270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (ClassDecl) {
11500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
11510270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
11520270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
11530270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyAssignment()) {
11540270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
11550270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    return;
11560270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
11570270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11580270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXMethodDecl *MD = 0;
1159e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(),
1160e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                                                 MD);
1161e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign");
1162e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  (void)ConstCopyAssignOp;
1163e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian
1164e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
1165e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const llvm::Type *LTy =
1166e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
1167e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                   FPT->isVariadic());
1168e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
11690270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1170e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgList CallArgs;
1171e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the this (Dest) ptr.
1172e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Dest),
1173e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getThisType(getContext())));
11740270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
1175e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the Src ptr.
1176e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Src),
1177e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getParamDecl(0)->getType()));
1178e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  QualType ResultType =
1179e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
1180e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
1181e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian           Callee, CallArgs, MD);
11820270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian}
11830270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
118406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor
118506f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanianvoid
118606f598aa45b651f9f3be0b916d43876eae747af0Fariborz JahanianCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *CD,
118706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionDecl *FD,
118806f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              llvm::Function *Fn,
118906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionArgList &Args) {
119006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
119106f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  EmitCtorPrologue(CD);
119206f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  FinishFunction();
119306f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian}
119406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
11958c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
119697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
119797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise
119897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order
119997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
120097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
120197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of class type, the copy constructor for the class is
120297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
120397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is an array, each element is copied, in the manner
120497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
120597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of scalar type, the built-in assignment operator is
120697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
120797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the
120897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor
120997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
12108c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
12118c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
12128c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
1213ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
121497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
121597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
12168c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
12178c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
121897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
12191e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
12201e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
12211e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
12221e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
12231e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
12241e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
12251e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
12261e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
122797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
122897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
122997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
123097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
123197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
1232ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
123397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
123497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1235942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
1236942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
123797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
123897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
12391e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
12401e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
12411e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
12421e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
12431e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
12441e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    // FIXME. How about copying arrays!
12451e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    assert(!getContext().getAsArrayType(FieldType) &&
12461e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian           "FIXME. Copying arrays NYI");
1247e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian
12481e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
12491e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
12501e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
12511e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
12521e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1253942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
12541e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
1255942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                              0 /*ClassDecl*/, FieldClassDecl, FieldType);
12561e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
12571e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
1258f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    // Do a built-in assignment of scalar data members.
1259f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1260f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1261f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
1262f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
12631e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
12648c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
126597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian}
126697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
12672198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
12682198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// Before the implicitly-declared copy assignment operator for a class is
12692198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined, all implicitly- declared copy assignment operators for
12702198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// its direct base classes and its nonstatic data members shall have been
12712198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12]
12722198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// The implicitly-defined copy assignment operator for class X performs
12732198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// memberwise assignment of its subob- jects. The direct base classes of X are
12742198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// assigned first, in the order of their declaration in
12752198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// the base-specifier-list, and then the immediate nonstatic data members of X
12762198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// are assigned, in the order in which they were declared in the class
12772198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type:
12780270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of class type, the copy assignment operator for the
12790270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   class is used (as if by explicit qualification; that is, ignoring any
12802198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   possible virtual overriding functions in more derived classes);
12810270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
12820270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is an array, each element is assigned, in the manner
12832198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   appropriate to the element type;
12840270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
12850270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of scalar type, the built-in assignment operator is
12862198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   used.
12872198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
12882198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionDecl *FD,
12892198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  llvm::Function *Fn,
12902198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionArgList &Args) {
12910270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
12920270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
12930270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
12940270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
12952198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
12962198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian
12970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
12980270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *ThisArg = i->first;
12990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
13000270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
13010270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
13020270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
13030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
13040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
13060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
13070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
13080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (Base->isVirtual())
13090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
13100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
13120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
13130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
13140270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                            Base->getType());
13150270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
13160270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13170270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
13180270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
13190270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Field != FieldEnd; ++Field) {
13200270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
13210270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13220270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. How about copy assignment of  arrays!
13230270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    assert(!getContext().getAsArrayType(FieldType) &&
13240270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian           "FIXME. Copy assignment of arrays NYI");
13250270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13260270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
13270270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      CXXRecordDecl *FieldClassDecl
13280270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(FieldClassType->getDecl());
13290270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
13300270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
13310270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13320270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
13330270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                              0 /*ClassDecl*/, FieldClassDecl, FieldType);
13340270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
13350270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    }
13360270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // Do a built-in assignment of scalar data members.
13370270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
13380270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
13390270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
13400270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
1341183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  }
1342183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian
1343183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  // return *this;
1344183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  Builder.CreateStore(LoadOfThis, ReturnValue);
13450270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
13462198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  FinishFunction();
13472198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian}
134897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
1349e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
1350e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
1351e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
1352742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
1353eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
1354f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
13556d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
1356742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1357e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
1358e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
1359e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
1360e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
1361f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
13626d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
13636d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
13646217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
13656d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
13666d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
1367742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
1368742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
1369742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
1370742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
1371b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1372e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
1373e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
1374e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
1375e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
1376e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian             && "FIXME. Field arrays initialization unsupported");
13778c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian
1378f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1379e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
13806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
1381e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        if (!Field->isAnonymousStructOrUnion()) {
138250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
138350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
138450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          EmitCXXConstructorCall(Member->getConstructor(),
138550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Ctor_Complete, LHS.getAddress(),
138650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_begin(),
138750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_end());
1388e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          continue;
1389e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
1390e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        else {
1391e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          // Initializing an anonymous union data member.
1392e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldDecl *anonMember = Member->getAnonUnionMember();
1393e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          LHS = EmitLValueForField(LHS.getAddress(), anonMember, false, 0);
1394e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldType = anonMember->getType();
1395e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
139650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
1397e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
1398e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
139950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
1400e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
14018c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian      EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
1402e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
1403e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
1404f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
14050880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
14061d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    // Nontrivial default constructor with no initializer list. It may still
14070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // have bases classes and/or contain non-static data members which require
14080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // construction.
14090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (CXXRecordDecl::base_class_const_iterator Base =
14100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          ClassDecl->bases_begin();
14110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          Base != ClassDecl->bases_end(); ++Base) {
14120880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      // FIXME. copy assignment of virtual base NYI
14130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (Base->isVirtual())
14140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
14150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
14160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *BaseClassDecl
14170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
14180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (BaseClassDecl->hasTrivialConstructor())
14190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
14200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *BaseCX =
14210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            BaseClassDecl->getDefaultConstructor(getContext())) {
14220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
14230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
14240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                               BaseClassDecl);
14250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
14260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      }
14270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
14280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
14291d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
14301d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         FieldEnd = ClassDecl->field_end();
14311d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         Field != FieldEnd; ++Field) {
14321d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1433288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian      const ConstantArrayType *Array =
1434288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1435f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1436f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
14371d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
14381d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian        continue;
14391d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      const RecordType *ClassRec = FieldType->getAs<RecordType>();
14400880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *MemberClassDecl =
14410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
14420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor())
14430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
14440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *MamberCX =
14450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            MemberClassDecl->getDefaultConstructor(getContext())) {
14460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
14470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1448288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        if (Array) {
1449288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          const llvm::Type *BasePtr = ConvertType(FieldType);
1450288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          BasePtr = llvm::PointerType::getUnqual(BasePtr);
1451288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          llvm::Value *BaseAddrPtr =
1452288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian            Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1453288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr);
1454288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        }
1455288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian        else
1456288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian          EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(),
1457288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian                                 0, 0);
14581d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      }
14591d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    }
14600880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
14610880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
1462f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
1463b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
1464f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
1465f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1466f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
1467f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
14680032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1469f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
1470f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
1471f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
1472f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
1473f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
1474e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
1475426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1476426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
1477426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
1478426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
1479426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
1480426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
1481426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
1482426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
1483426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
1484426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1485426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
1486426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
1487426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
1488426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
1489426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
1490426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
1491f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1492f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1493f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array)
1494f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        FieldType = getContext().getBaseElementType(FieldType);
1495426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
1496426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1497426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
1498426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1499426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
1500426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
1501f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1502f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1503f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1504f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1505f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1506f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1507f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1508f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1509f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1510f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1511f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
1512b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1513426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
1514426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
1515426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1516426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
1517426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1518426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
1519426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
1520426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
1521426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
1522426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
1523426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
15240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial())
15250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
15260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // Case of destructor synthesis with fields and base classes
15270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // which have non-trivial destructors. They must be destructed in
15280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // reverse order of their construction.
15290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<FieldDecl *, 16> DestructedFields;
15300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
15320880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
15330880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Field != FieldEnd; ++Field) {
15340880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
1535f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian    if (getContext().getAsConstantArrayType(FieldType))
1536f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      FieldType = getContext().getBaseElementType(FieldType);
15370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (const RecordType *RT = FieldType->getAs<RecordType>()) {
15380880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
15390880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
15400880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
15410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      DestructedFields.push_back(*Field);
15420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
15430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
15440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!DestructedFields.empty())
15450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (int i = DestructedFields.size() -1; i >= 0; --i) {
15460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      FieldDecl *Field = DestructedFields[i];
15470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      QualType FieldType = Field->getType();
1548f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      const ConstantArrayType *Array =
1549f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        getContext().getAsConstantArrayType(FieldType);
1550f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        if (Array)
1551f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian          FieldType = getContext().getBaseElementType(FieldType);
15520880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
15530880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
15540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
15550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
1556f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      if (Array) {
1557f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        const llvm::Type *BasePtr = ConvertType(FieldType);
1558f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        BasePtr = llvm::PointerType::getUnqual(BasePtr);
1559f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        llvm::Value *BaseAddrPtr =
1560f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        Builder.CreateBitCast(LHS.getAddress(), BasePtr);
1561f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
1562f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                                  Array, BaseAddrPtr);
1563f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      }
1564f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian      else
1565f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian        EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1566f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian                              Dtor_Complete, LHS.getAddress());
15670880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
15680880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15690880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
15700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
15710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
15720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
15730880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (Base->isVirtual())
15740880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
15750880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15760880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
15770880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
15780880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (BaseClassDecl->hasTrivialDestructor())
15790880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
15800880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    DestructedBases.push_back(BaseClassDecl);
15810880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
15820880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DestructedBases.empty())
15830880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
15840880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (int i = DestructedBases.size() -1; i >= 0; --i) {
15850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl = DestructedBases[i];
15860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
15870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                           ClassDecl,BaseClassDecl);
15880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
15890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                          Dtor_Complete, V);
15900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
1591426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
15920880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15930880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanianvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *CD,
15940880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionDecl *FD,
15950880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  llvm::Function *Fn,
15960880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionArgList &Args) {
15970880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
15980880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
15990880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredDestructor() &&
16000880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian         "SynthesizeDefaultDestructor - destructor has user declaration");
16010880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  (void) ClassDecl;
16020880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
16030880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
16040880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  EmitDtorEpilogue(CD);
16050880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  FinishFunction();
16060880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian}
1607