CGCXX.cpp revision 09765ece710f29dcdbd66eec361d60e53bd5a4fd
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)),
1461c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             GuardVName.c_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
335b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
336b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
337b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
338b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
339b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
340b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
341343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  if (D->isCopyConstructor(getContext())) {
342343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext());
343343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    if (ClassDecl->hasTrivialCopyConstructor()) {
344343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
345343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian             "EmitCXXConstructorCall - user declared copy constructor");
346343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      const Expr *E = (*ArgBeg);
347343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      QualType Ty = E->getType();
348343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      llvm::Value *Src = EmitLValue(E).getAddress();
349343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      EmitAggregateCopy(This, Src, Ty);
350343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian      return;
351343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian    }
352343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian  }
353343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian
354b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
355b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
356b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
357b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
358b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
3597267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
3607267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
3617267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
3627267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
3637267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
3647267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
3657267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
3667267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
367b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
36831ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
36931ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
370b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
371b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
372b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
3736217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
374b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
375b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
3766904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
3776904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // Code gen optimization to eliminate copy constructor and return
3786904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
3791cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian  if (E->isElidable()) {
3806904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
3811cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
3821cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
3836904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
384b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
385b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
386b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
387b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
388b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
389a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
390ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
391ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
39203e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
393ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
394ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
395ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
396ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
397ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
398ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
399ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
400ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
401ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
402ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
403ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
4044a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
405ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
406ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
407ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
408ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
409ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
410ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
411ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
412ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
413ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
414ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
415ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
416ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
417ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
418ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
419ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
420ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
421ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
422ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
423ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
424ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
425ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
426ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
427ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
428ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
429ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
430ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
431ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
432ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
433ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
434ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
435ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
436ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
437ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
438ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
439ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
440ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
441ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
442ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
443ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
444ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
445ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
446ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
447ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
448d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
449d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
450d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
451d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
452d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
453d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
454ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
455f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
456f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
457f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
458f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
459f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
460f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
461d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
462f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
463f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
464f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
465f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
466f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
467f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
468c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
469f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
470f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
471f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
472f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
473d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
474d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
475f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
476d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
4776d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
478215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
4796d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
4806d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
4816d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
4826d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
4836d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
4843923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
4856d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
4863923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
4873923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
488627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
489627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
4906d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
491d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
492d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
493d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
4946d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
495d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
496d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
497d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
498ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
499d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
500f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
501f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
502f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
503f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
504f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
505f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
506f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
507f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
508f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
509c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
510f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
511f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
512f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
513f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
514d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
515a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
516a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
51760e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
51860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (E->isArrayForm()) {
51960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    ErrorUnsupported(E, "delete[] expression");
52060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    return;
52160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  };
52260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
52360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType DeleteTy =
52460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
52560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
52660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
52760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
52860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Null check the pointer.
52960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
53060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
53160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
53260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *IsNull =
53360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
53460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                         "isnull");
53560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
53660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
53760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteNotNull);
53860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
53960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call the destructor if necessary.
54060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
54160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
54260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      if (!RD->hasTrivialDestructor()) {
54360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
54460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        if (Dtor->isVirtual()) {
54560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          ErrorUnsupported(E, "delete expression with virtual destructor");
54660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson          return;
54760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        }
54860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
54960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson        EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
55060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson      }
55160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    }
55260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  }
55360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
55460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Call delete.
55560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  FunctionDecl *DeleteFD = E->getOperatorDelete();
55660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  const FunctionProtoType *DeleteFTy =
55760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson    DeleteFD->getType()->getAsFunctionProtoType();
55860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
55960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  CallArgList DeleteArgs;
56060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
56160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  QualType ArgTy = DeleteFTy->getArgType(0);
56260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
56360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
56460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
56560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  // Emit the call to delete.
56660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
56760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson                                          DeleteArgs),
56860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)),
56960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson           DeleteArgs, DeleteFD);
57060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
57160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson  EmitBlock(DeleteEnd);
57260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson}
57360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson
57427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
57527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
57659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
57759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
57859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
57959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
58017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
58117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
58259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
58359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
58459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
58559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
58659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
58759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
58859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
58959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
59095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
59127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
59259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
59359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
59459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
59595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
5962a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
5972a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
59895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
599363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
60027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
60127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
60227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
60327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
60427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
60527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
60627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
60727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
60827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
60927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
61027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
611363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
612363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
613363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
614363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
615363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
616363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
617363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
618b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
619b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
620363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
62127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
62227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
62327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
62427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
62527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
62627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
62727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
62827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
62927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
63027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
63127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
63227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
63327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
63427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
63527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
63627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
63727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
63827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
63927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
64027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
64127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
64227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
64327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
64427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
64527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
64627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
64727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
64827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
64927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
65027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
65127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
65227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
65327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
65427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
65527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
65627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
65727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
65827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
659b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
660b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
66127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
66227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
66327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
66427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
66527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
66627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
66727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
66827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
66927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
67027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
67127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
672e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
67332f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
674738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
6750032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson  Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
676cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
677738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
678738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
679cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
680738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
681738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
682738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
683738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
684e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
685738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
686738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  const char *Name = OutName.c_str();
687738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
688738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
689738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
6904ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti descriptor");
691738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
692738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
6934ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  // assert(0 && "FIXME: implement rtti ts");
694738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
695738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
696738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
697738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
698738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
699738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
70032f3701853a8237704065c77abc17369dd02c39bMike Stump  Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C,
701738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump                                  Name);
702cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
703cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
704738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
705738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
7067c435fa7f7666b22abbe8494c537ebc25209223dMike Stumpclass ABIBuilder {
7077c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  std::vector<llvm::Constant *> &methods;
7087c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::Type *Ptr8Ty;
70932f3701853a8237704065c77abc17369dd02c39bMike Stump  const CXXRecordDecl *Class;
710b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  const ASTRecordLayout &BLayout;
71132f3701853a8237704065c77abc17369dd02c39bMike Stump  llvm::Constant *rtti;
7127c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  llvm::LLVMContext &VMContext;
71365defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  CodeGenModule &CGM;  // Per-module state.
714552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump
715552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump  typedef CXXRecordDecl::method_iterator method_iter;
7167c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic:
71765defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  ABIBuilder(std::vector<llvm::Constant *> &meth,
71832f3701853a8237704065c77abc17369dd02c39bMike Stump             const CXXRecordDecl *c,
71965defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump             CodeGenModule &cgm)
720b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
721b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
722b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      CGM(cgm) {
7237c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
7247c435fa7f7666b22abbe8494c537ebc25209223dMike Stump  }
72532f3701853a8237704065c77abc17369dd02c39bMike Stump
726b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
727b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                const CXXRecordDecl *RD,
728b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool VBoundary,
729b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                                bool SecondaryVirtual) {
730b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    llvm::Constant *m = 0;
731b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
732b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    // FIXME: vcall: offset for virtual base for this function
733b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (SecondaryVirtual || VBoundary)
734b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      m = llvm::Constant::getNullValue(Ptr8Ty);
735b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    return m;
736b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  }
737b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
738b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
739b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                      bool SecondaryVirtual) {
7407c435fa7f7666b22abbe8494c537ebc25209223dMike Stump    llvm::Constant *m;
7417c435fa7f7666b22abbe8494c537ebc25209223dMike Stump
742552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump    for (method_iter mi = RD->method_begin(),
7437c435fa7f7666b22abbe8494c537ebc25209223dMike Stump           me = RD->method_end(); mi != me; ++mi) {
7447c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      if (mi->isVirtual()) {
745b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
746b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        if (m)
747b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump          methods.push_back(m);
7487c435fa7f7666b22abbe8494c537ebc25209223dMike Stump      }
7494c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump    }
75080a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump  }
7514c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump
75265defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump  void GenerateMethods(const CXXRecordDecl *RD) {
75365defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump    llvm::Constant *m;
75465defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump
755552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump    for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
75665defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump         ++mi) {
75765defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      if (mi->isVirtual()) {
75865defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump        m = CGM.GetAddrOfFunction(GlobalDecl(*mi));
75965defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump        m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
76065defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump        methods.push_back(m);
76165defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump      }
762bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump    }
763bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump  }
764bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump
765109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForBase(const CXXRecordDecl *RD,
766109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             bool forPrimary,
767b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                             bool VBoundary,
768109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             int64_t Offset,
769109b13db3391face0b393c730f0326ca51d25b52Mike Stump                             bool ForVirtualBase,
7704ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump                   llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
771109b13db3391face0b393c730f0326ca51d25b52Mike Stump    llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
772276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
773109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (RD && !RD->isDynamicClass())
774109b13db3391face0b393c730f0326ca51d25b52Mike Stump      return;
775109b13db3391face0b393c730f0326ca51d25b52Mike Stump
776109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
777109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
778109b13db3391face0b393c730f0326ca51d25b52Mike Stump    const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
779109b13db3391face0b393c730f0326ca51d25b52Mike Stump
780b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    if (VBoundary || forPrimary || ForVirtualBase) {
781b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      // then comes the the vcall offsets for all our functions...
782b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
783b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump    }
784b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump
785109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // The virtual base offsets come first...
786109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // FIXME: Audit, is this right?
78709765ece710f29dcdbd66eec361d60e53bd5a4fdMike Stump    if (PrimaryBase == 0 || forPrimary || !PrimaryBaseWasVirtual) {
788109b13db3391face0b393c730f0326ca51d25b52Mike Stump      llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
789109b13db3391face0b393c730f0326ca51d25b52Mike Stump      std::vector<llvm::Constant *> offsets;
790109b13db3391face0b393c730f0326ca51d25b52Mike Stump      GenerateVBaseOffsets(offsets, RD, SeenVBase, Offset, Layout);
791109b13db3391face0b393c730f0326ca51d25b52Mike Stump      for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
792109b13db3391face0b393c730f0326ca51d25b52Mike Stump             e = offsets.rend(); i != e; ++i)
793109b13db3391face0b393c730f0326ca51d25b52Mike Stump        methods.push_back(*i);
794276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    }
7954ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump
796109b13db3391face0b393c730f0326ca51d25b52Mike Stump    bool Top = true;
79702cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
798109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // vtables are composed from the chain of primaries.
799109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (PrimaryBase) {
800109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (PrimaryBaseWasVirtual)
801109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(PrimaryBase);
802109b13db3391face0b393c730f0326ca51d25b52Mike Stump      Top = false;
803b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump      GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
804b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump                            Offset, PrimaryBaseWasVirtual, IndirectPrimary);
805109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
806276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
807109b13db3391face0b393c730f0326ca51d25b52Mike Stump    if (Top) {
808109b13db3391face0b393c730f0326ca51d25b52Mike Stump      int64_t BaseOffset;
809109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (ForVirtualBase) {
810109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
811109b13db3391face0b393c730f0326ca51d25b52Mike Stump      } else
812109b13db3391face0b393c730f0326ca51d25b52Mike Stump        BaseOffset = -Offset/8;
813109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
814109b13db3391face0b393c730f0326ca51d25b52Mike Stump      m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
815109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(m);
816109b13db3391face0b393c730f0326ca51d25b52Mike Stump      methods.push_back(rtti);
817109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
818276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
819109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // And add the virtuals for the class to the primary vtable.
820109b13db3391face0b393c730f0326ca51d25b52Mike Stump    GenerateMethods(RD);
821109b13db3391face0b393c730f0326ca51d25b52Mike Stump
822109b13db3391face0b393c730f0326ca51d25b52Mike Stump    // and then the non-virtual bases.
823109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
824109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
825109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual())
826109b13db3391face0b393c730f0326ca51d25b52Mike Stump        continue;
827109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
828109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
829109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
830109b13db3391face0b393c730f0326ca51d25b52Mike Stump        uint64_t o = Offset + Layout.getBaseClassOffset(Base);
831b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        GenerateVtableForBase(Base, true, false, o, false, IndirectPrimary);
832109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
833109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
834276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
835276b9f1d814f4f6551cc3000590759a34185d6daMike Stump
836109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVtableForVBases(const CXXRecordDecl *RD,
837109b13db3391face0b393c730f0326ca51d25b52Mike Stump                               const CXXRecordDecl *Class,
838109b13db3391face0b393c730f0326ca51d25b52Mike Stump                   llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
839109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
840109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
841109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
842109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
843109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !IndirectPrimary.count(Base)) {
844109b13db3391face0b393c730f0326ca51d25b52Mike Stump        // Mark it so we don't output it twice.
845109b13db3391face0b393c730f0326ca51d25b52Mike Stump        IndirectPrimary.insert(Base);
846b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump        GenerateVtableForBase(Base, false, true, 0, true, IndirectPrimary);
847109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
848109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (Base->getNumVBases())
84932f3701853a8237704065c77abc17369dd02c39bMike Stump        GenerateVtableForVBases(Base, Class, IndirectPrimary);
850109b13db3391face0b393c730f0326ca51d25b52Mike Stump    }
851e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
852e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
853109b13db3391face0b393c730f0326ca51d25b52Mike Stump  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
854109b13db3391face0b393c730f0326ca51d25b52Mike Stump                            const CXXRecordDecl *RD,
855109b13db3391face0b393c730f0326ca51d25b52Mike Stump                           llvm::SmallSet<const CXXRecordDecl *, 32> &SeenVBase,
856109b13db3391face0b393c730f0326ca51d25b52Mike Stump                            uint64_t Offset, const ASTRecordLayout &BLayout) {
857109b13db3391face0b393c730f0326ca51d25b52Mike Stump    for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
858109b13db3391face0b393c730f0326ca51d25b52Mike Stump           e = RD->bases_end(); i != e; ++i) {
859109b13db3391face0b393c730f0326ca51d25b52Mike Stump      const CXXRecordDecl *Base =
860109b13db3391face0b393c730f0326ca51d25b52Mike Stump        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
861109b13db3391face0b393c730f0326ca51d25b52Mike Stump      if (i->isVirtual() && !SeenVBase.count(Base)) {
862109b13db3391face0b393c730f0326ca51d25b52Mike Stump        SeenVBase.insert(Base);
863109b13db3391face0b393c730f0326ca51d25b52Mike Stump        int64_t BaseOffset = Offset/8 + BLayout.getVBaseClassOffset(Base) / 8;
864109b13db3391face0b393c730f0326ca51d25b52Mike Stump        llvm::Constant *m;
865109b13db3391face0b393c730f0326ca51d25b52Mike Stump        m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
866109b13db3391face0b393c730f0326ca51d25b52Mike Stump        m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
867109b13db3391face0b393c730f0326ca51d25b52Mike Stump        offsets.push_back(m);
868109b13db3391face0b393c730f0326ca51d25b52Mike Stump      }
869109b13db3391face0b393c730f0326ca51d25b52Mike Stump      GenerateVBaseOffsets(offsets, Base, SeenVBase, Offset, BLayout);
870276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    }
871276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
872109b13db3391face0b393c730f0326ca51d25b52Mike Stump};
8738a12b564923a72224730a467007e61b5701e4aa7Mike Stump
874f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
875f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
876f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
877f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
878e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
879f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
880f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  const char *Name = OutName.c_str();
88182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
88282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
88382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
884276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
8856f376336138ea719e3c4757ae046a5768043b276Mike Stump  int64_t Offset = 0;
886e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
887e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
888e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
8896f376336138ea719e3c4757ae046a5768043b276Mike Stump
8904ffe91eae351d6ef68256ce77fc549557702d3e3Mike Stump  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
891104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump
89232f3701853a8237704065c77abc17369dd02c39bMike Stump  ABIBuilder b(methods, RD, CGM);
893109b13db3391face0b393c730f0326ca51d25b52Mike Stump
894276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // First comes the vtables for all the non-virtual bases...
895b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump  b.GenerateVtableForBase(RD, true, false, 0, false, IndirectPrimary);
89670101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
897276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // then the vtables for all the virtual bases.
89832f3701853a8237704065c77abc17369dd02c39bMike Stump  b.GenerateVtableForVBases(RD, RD, IndirectPrimary);
8996f376336138ea719e3c4757ae046a5768043b276Mike Stump
90082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
90182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
90282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
90382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
90482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump                                                 linktype, C, Name);
905f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
906f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
907276b9f1d814f4f6551cc3000590759a34185d6daMike Stump                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
9086f376336138ea719e3c4757ae046a5768043b276Mike Stump                                                    Offset/8));
909f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
910f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
911f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
912ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
913ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
914ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// of via a copy constructor call.
915ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
916942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
917ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                        const CXXRecordDecl *ClassDecl,
918942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
919942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
920942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
921942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
922942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
923942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
924942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
925ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
926942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
927942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
928ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  if (CXXConstructorDecl *BaseCopyCtor =
92980e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
930ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
931ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
932ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
933ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
934ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
935ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
936ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
937ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
938ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
939370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian                       BaseCopyCtor->getParamDecl(0)->getType()));
940ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    QualType ResultType =
941ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
942ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
943ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
944ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
945ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
94606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
9470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class
9480270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// object from SrcValue to DestValue. Assignment can be either a bitwise
9490270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call.
9500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment(
9510270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        llvm::Value *Dest, llvm::Value *Src,
9520270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *ClassDecl,
9530270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        const CXXRecordDecl *BaseClassDecl,
9540270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                                        QualType Ty) {
9550270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (ClassDecl) {
9560270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
9570270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
9580270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
9590270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyAssignment()) {
9600270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
9610270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    return;
9620270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
9630270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
9640270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXMethodDecl *MD = 0;
965e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(),
966e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                                                 MD);
967e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign");
968e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  (void)ConstCopyAssignOp;
969e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian
970e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
971e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  const llvm::Type *LTy =
972e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
973e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                   FPT->isVariadic());
974e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy);
9750270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
976e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgList CallArgs;
977e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the this (Dest) ptr.
978e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Dest),
979e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getThisType(getContext())));
9800270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
981e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  // Push the Src ptr.
982e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  CallArgs.push_back(std::make_pair(RValue::get(Src),
983e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian                                    MD->getParamDecl(0)->getType()));
984e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  QualType ResultType =
985e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian    MD->getType()->getAsFunctionType()->getResultType();
986e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
987e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian           Callee, CallArgs, MD);
9880270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian}
9890270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
99006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor
99106f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanianvoid
99206f598aa45b651f9f3be0b916d43876eae747af0Fariborz JahanianCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *CD,
99306f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionDecl *FD,
99406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              llvm::Function *Fn,
99506f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian                                              const FunctionArgList &Args) {
99606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
99706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  EmitCtorPrologue(CD);
99806f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian  FinishFunction();
99906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian}
100006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian
10018c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
100297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
100397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise
100497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order
100597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
100697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
100797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of class type, the copy constructor for the class is
100897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
100997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is an array, each element is copied, in the manner
101097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
101197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of scalar type, the built-in assignment operator is
101297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
101397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the
101497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor
101597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
10168c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
10178c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
10188c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
1019ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
102097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
102197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
10228c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
10238c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
102497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
10251e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
10261e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
10271e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
10281e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
10291e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
10301e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
10311e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
10321e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
103397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
103497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
103597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
103697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
103797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
1038ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
103997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
104097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1041942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
1042942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
104397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
104497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
10451e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
10461e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
10471e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
10481e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
10491e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
10501e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    // FIXME. How about copying arrays!
10511e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    assert(!getContext().getAsArrayType(FieldType) &&
10521e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian           "FIXME. Copying arrays NYI");
1053e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian
10541e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
10551e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
10561e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
10571e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
10581e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1059942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
10601e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
1061942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                              0 /*ClassDecl*/, FieldClassDecl, FieldType);
10621e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
10631e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
1064f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    // Do a built-in assignment of scalar data members.
1065f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
1066f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
1067f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
1068f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
10691e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
10708c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
107197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian}
107297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
10732198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
10742198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// Before the implicitly-declared copy assignment operator for a class is
10752198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined, all implicitly- declared copy assignment operators for
10762198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// its direct base classes and its nonstatic data members shall have been
10772198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12]
10782198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// The implicitly-defined copy assignment operator for class X performs
10792198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// memberwise assignment of its subob- jects. The direct base classes of X are
10802198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// assigned first, in the order of their declaration in
10812198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// the base-specifier-list, and then the immediate nonstatic data members of X
10822198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// are assigned, in the order in which they were declared in the class
10832198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type:
10840270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of class type, the copy assignment operator for the
10850270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   class is used (as if by explicit qualification; that is, ignoring any
10862198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   possible virtual overriding functions in more derived classes);
10870270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
10880270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is an array, each element is assigned, in the manner
10892198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   appropriate to the element type;
10900270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///
10910270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian///   if the subobject is of scalar type, the built-in assignment operator is
10922198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian///   used.
10932198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD,
10942198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionDecl *FD,
10952198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  llvm::Function *Fn,
10962198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian                                                  const FunctionArgList &Args) {
10970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
10980270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
10990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
11000270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian         "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
11012198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
11022198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian
11030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
11040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *ThisArg = i->first;
11050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
11060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
11070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
11080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
11090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
11100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
11120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
11130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
11140270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (Base->isVirtual())
11150270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
11160270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11170270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
11180270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
11190270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
11200270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                            Base->getType());
11210270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  }
11220270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11230270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
11240270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
11250270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian       Field != FieldEnd; ++Field) {
11260270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
11270270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11280270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // FIXME. How about copy assignment of  arrays!
11290270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    assert(!getContext().getAsArrayType(FieldType) &&
11300270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian           "FIXME. Copy assignment of arrays NYI");
11310270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11320270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
11330270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      CXXRecordDecl *FieldClassDecl
11340270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      = cast<CXXRecordDecl>(FieldClassType->getDecl());
11350270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
11360270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
11370270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11380270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(),
11390270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian                              0 /*ClassDecl*/, FieldClassDecl, FieldType);
11400270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian      continue;
11410270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    }
11420270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    // Do a built-in assignment of scalar data members.
11430270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
11440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
11450270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    RValue RVRHS = EmitLoadOfLValue(RHS, FieldType);
11460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian    EmitStoreThroughLValue(RVRHS, LHS, FieldType);
1147183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  }
1148183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian
1149183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  // return *this;
1150183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian  Builder.CreateStore(LoadOfThis, ReturnValue);
11510270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian
11522198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian  FinishFunction();
11532198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian}
115497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
1155e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
1156e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
1157e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
1158742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
1159eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
1160f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
11616d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
1162742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1163e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
1164e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
1165e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
1166e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
1167f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
11686d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
11696d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
11706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
11716d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
11726d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
1173742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
1174742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
1175742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
1176742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
1177b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1178e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
1179e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
1180e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
1181e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
1182e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian             && "FIXME. Field arrays initialization unsupported");
11838c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian
1184f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1185e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
11866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
1187e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        if (!Field->isAnonymousStructOrUnion()) {
118850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
118950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
119050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          EmitCXXConstructorCall(Member->getConstructor(),
119150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Ctor_Complete, LHS.getAddress(),
119250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_begin(),
119350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_end());
1194e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          continue;
1195e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
1196e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        else {
1197e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          // Initializing an anonymous union data member.
1198e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldDecl *anonMember = Member->getAnonUnionMember();
1199e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          LHS = EmitLValueForField(LHS.getAddress(), anonMember, false, 0);
1200e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian          FieldType = anonMember->getType();
1201e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian        }
120250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
1203e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
1204e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
120550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
1206e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
12078c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian      EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
1208e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
1209e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
1210f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
12110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
12121d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    // Nontrivial default constructor with no initializer list. It may still
12130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // have bases classes and/or contain non-static data members which require
12140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // construction.
12150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (CXXRecordDecl::base_class_const_iterator Base =
12160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          ClassDecl->bases_begin();
12170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian          Base != ClassDecl->bases_end(); ++Base) {
12180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      // FIXME. copy assignment of virtual base NYI
12190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (Base->isVirtual())
12200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
12210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
12220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *BaseClassDecl
12230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
12240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (BaseClassDecl->hasTrivialConstructor())
12250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
12260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *BaseCX =
12270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            BaseClassDecl->getDefaultConstructor(getContext())) {
12280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
12290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
12300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                               BaseClassDecl);
12310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
12320880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      }
12330880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
12340880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
12351d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
12361d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         FieldEnd = ClassDecl->field_end();
12371d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian         Field != FieldEnd; ++Field) {
12381d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((*Field)->getType());
12391d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion())
12401d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian        continue;
12411d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      const RecordType *ClassRec = FieldType->getAs<RecordType>();
12420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *MemberClassDecl =
12430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
12440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor())
12450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
12460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (CXXConstructorDecl *MamberCX =
12470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian            MemberClassDecl->getDefaultConstructor(getContext())) {
12480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LoadOfThis = LoadCXXThis();
12490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
12500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(), 0, 0);
12511d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian      }
12521d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian    }
12530880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
12540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
1255f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
1256b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
1257f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
1258f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
1259f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
1260f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
12610032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
1262f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
1263f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
1264f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
1265f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
1266f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
1267e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
1268426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1269426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
1270426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
1271426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
1272426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
1273426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
1274426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
1275426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
1276426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
1277426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
1278426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
1279426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
1280426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
1281426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
1282426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
1283426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
1284426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
1285426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian             && "FIXME. Field arrays destruction unsupported");
1286426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
1287426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1288426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
1289426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1290426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
1291426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
1292426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
1293426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, LHS.getAddress());
1294b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
1295426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
1296426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
1297426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1298426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
1299426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
1300426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
1301426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
1302426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
1303426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
1304426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
1305426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
13060880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial())
13070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
13080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // Case of destructor synthesis with fields and base classes
13090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // which have non-trivial destructors. They must be destructed in
13100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  // reverse order of their construction.
13110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<FieldDecl *, 16> DestructedFields;
13120880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
13140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       FieldEnd = ClassDecl->field_end();
13150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Field != FieldEnd; ++Field) {
13160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
13170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. Assert on arrays for now.
13180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (const RecordType *RT = FieldType->getAs<RecordType>()) {
13190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
13200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
13210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian        continue;
13220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      DestructedFields.push_back(*Field);
13230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
13240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
13250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (!DestructedFields.empty())
13260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    for (int i = DestructedFields.size() -1; i >= 0; --i) {
13270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      FieldDecl *Field = DestructedFields[i];
13280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      QualType FieldType = Field->getType();
13290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
13300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
13310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
13320880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
13330880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
13340880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                            Dtor_Complete, LHS.getAddress());
13350880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    }
13360880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases;
13380880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
13390880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
13400880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    // FIXME. copy assignment of virtual base NYI
13410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (Base->isVirtual())
13420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
13430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl
13450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
13460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    if (BaseClassDecl->hasTrivialDestructor())
13470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian      continue;
13480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    DestructedBases.push_back(BaseClassDecl);
13490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
13500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  if (DestructedBases.empty())
13510880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    return;
13520880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  for (int i = DestructedBases.size() -1; i >= 0; --i) {
13530880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    CXXRecordDecl *BaseClassDecl = DestructedBases[i];
13540880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
13550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                           ClassDecl,BaseClassDecl);
13560880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian    EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
13570880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                          Dtor_Complete, V);
13580880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  }
1359426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
13600880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13610880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanianvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *CD,
13620880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionDecl *FD,
13630880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  llvm::Function *Fn,
13640880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian                                                  const FunctionArgList &Args) {
13650880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13660880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
13670880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  assert(!ClassDecl->hasUserDeclaredDestructor() &&
13680880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian         "SynthesizeDefaultDestructor - destructor has user declaration");
13690880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  (void) ClassDecl;
13700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian
13710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
13720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  EmitDtorEpilogue(CD);
13730880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian  FinishFunction();
13740880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian}
1375