CGCXX.cpp revision 942f4f33d02dba823594bd2d7b3d317cb01c74f8
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 =
343b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
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 =
413b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders Carlsson    llvm::FunctionType::get(llvm::Type::VoidTy, 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()) {
773b2e16b3d25f6b311dba2871e2a566c96238c3d2Anders 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
9989ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson  const llvm::FunctionType *FTy = llvm::FunctionType::get(llvm::Type::VoidTy,
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,
10989ed31d3f9eeb8ec77c284a5cf404a74bf5e7acfAnders Carlsson                                                   CXXGlobalInits.data(),
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 =
1431c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson    new llvm::GlobalVariable(CGM.getModule(), llvm::Type::Int64Ty, false,
1440096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar                             GV->getLinkage(),
145c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
1461c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson                             GuardVName.c_str());
147e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
148e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
14996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
150e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
151e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
152e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
153e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Compare it against 0.
154c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
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
1674a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 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
2310f294632f36459174199b77699e339715244b5abAnders Carlsson
2320f294632f36459174199b77699e339715244b5abAnders Carlsson  const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
2330f294632f36459174199b77699e339715244b5abAnders Carlsson  const llvm::Type *Ty =
2340f294632f36459174199b77699e339715244b5abAnders Carlsson  CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
2350f294632f36459174199b77699e339715244b5abAnders Carlsson                                 FPT->isVariadic());
2360f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
2370f294632f36459174199b77699e339715244b5abAnders Carlsson
2380f294632f36459174199b77699e339715244b5abAnders Carlsson  llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
2390f294632f36459174199b77699e339715244b5abAnders Carlsson
2400f294632f36459174199b77699e339715244b5abAnders Carlsson  return EmitCXXMemberCall(MD, Callee, This,
2410f294632f36459174199b77699e339715244b5abAnders Carlsson                           E->arg_begin() + 1, E->arg_end());
2420f294632f36459174199b77699e339715244b5abAnders Carlsson}
2430f294632f36459174199b77699e339715244b5abAnders Carlsson
2445f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() {
2455f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
2465f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2475f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
2485f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson         "Must be in a C++ member function decl to load 'this'");
2495f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson
2505f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  // FIXME: What if we're inside a block?
251f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // ans: See how CodeGenFunction::LoadObjCSelf() uses
252f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // CodeGenFunction::BlockForwardSelf() for how to do this.
2535f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
2545f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson}
25595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
256c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool
257c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths,
258c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *ClassDecl,
259c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian               const CXXRecordDecl *BaseClassDecl) {
260c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(),
261c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      e = ClassDecl->bases_end(); i != e; ++i) {
262c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (i->isVirtual())
263c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      continue;
264c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *Base =
265104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
266c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (Base == BaseClassDecl) {
267c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(BaseClassDecl);
268c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
269c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
270c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
271c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  // BaseClassDecl not an immediate base of ClassDecl.
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 =
277c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
278c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) {
279c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      NestedBasePaths.push_back(Base);
280c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      return true;
281c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    }
282c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
283c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  return false;
284c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian}
285c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
2869e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue,
2876d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *ClassDecl,
2886d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                          const CXXRecordDecl *BaseClassDecl) {
2899e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  if (ClassDecl == BaseClassDecl)
2909e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    return BaseValue;
2919e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
292c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
293c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths;
294c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl);
295c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  assert(NestedBasePaths.size() > 0 &&
296c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian         "AddressCXXOfBaseClass - inheritence path failed");
297c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  NestedBasePaths.push_back(ClassDecl);
298c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  uint64_t Offset = 0;
299c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian
3009e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // Accessing a member of the base class. Must add delata to
3019e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  // the load of 'this'.
302c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) {
303c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *DerivedClass = NestedBasePaths[i];
304c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const CXXRecordDecl *BaseClass = NestedBasePaths[i-1];
305c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    const ASTRecordLayout &Layout =
306c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian      getContext().getASTRecordLayout(DerivedClass);
307c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian    Offset += Layout.getBaseClassOffset(BaseClass) / 8;
308c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian  }
3095a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian  llvm::Value *OffsetVal =
3105a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian    llvm::ConstantInt::get(
3115a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian                  CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
3129e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr);
3139e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr");
3149e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  QualType BTy =
3159e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian    getContext().getCanonicalType(
3166d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
3179e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  const llvm::Type *BasePtr = ConvertType(BTy);
31896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson  BasePtr = llvm::PointerType::getUnqual(BasePtr);
3199e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  BaseValue = Builder.CreateBitCast(BaseValue, BasePtr);
3209e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian  return BaseValue;
3219e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian}
3229e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian
323b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
324b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
325b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CXXCtorType Type,
326b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        llvm::Value *This,
327b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgBeg,
328b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                                        CallExpr::const_arg_iterator ArgEnd) {
329b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
330b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson
331b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson  EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd);
332b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
333b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
3347267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D,
3357267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            CXXDtorType Type,
3367267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson                                            llvm::Value *This) {
3377267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type);
3387267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
3397267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson  EmitCXXMemberCall(D, Callee, This, 0, 0);
3407267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson}
3417267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson
342b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid
34331ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
34431ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson                                      const CXXConstructExpr *E) {
345b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  assert(Dest && "Must have a destination!");
346b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
347b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  const CXXRecordDecl *RD =
3486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
349b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  if (RD->hasTrivialConstructor())
350b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson    return;
3516904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian
3526904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // Code gen optimization to eliminate copy constructor and return
3536904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  // its first argument instead.
3541cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian  if (E->isElidable()) {
3556904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian    CXXConstructExpr::const_arg_iterator i = E->arg_begin();
3561cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    EmitAggExpr((*i), Dest, false);
3571cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian    return;
3586904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian  }
359b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  // Call the constructor.
360b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
361b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson                         E->arg_begin(), E->arg_end());
362b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson}
363b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson
364a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
365ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  if (E->isArray()) {
366ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    ErrorUnsupported(E, "new[] expression");
36703e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    return llvm::UndefValue::get(ConvertType(E->getType()));
368ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
369ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
370ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType AllocType = E->getAllocatedType();
371ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  FunctionDecl *NewFD = E->getOperatorNew();
372ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType();
373ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
374ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CallArgList NewArgs;
375ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
376ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // The allocation size is the first argument.
377ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  QualType SizeTy = getContext().getSizeType();
378ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  llvm::Value *AllocSize =
3794a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::ConstantInt::get(ConvertType(SizeTy),
380ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                           getContext().getTypeSize(AllocType) / 8);
381ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
382ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
383ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
384ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the rest of the arguments.
385ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // FIXME: Ideally, this should just use EmitCallArgs.
386ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
387ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
388ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // First, use the types from the function type.
389ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // We start at 1 here because the first argument (the allocation size)
390ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // has already been emitted.
391ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
392ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewFTy->getArgType(i);
393ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
394ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
395ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getTypePtr() ==
396ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
397ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson           "type mismatch in call argument!");
398ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
399ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
400ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
401ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
402ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
403ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
404ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Either we've emitted all the call args, or we have a call to a
405ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // variadic function.
406ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
407ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson         "Extra arguments in non-variadic function!");
408ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
409ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // If we still have any arguments, emit them using the type of the argument.
410ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
411ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson       NewArg != NewArgEnd; ++NewArg) {
412ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    QualType ArgType = NewArg->getType();
413ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
414ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson                                     ArgType));
415ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
416ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
417ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  // Emit the call to new.
418ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  RValue RV =
419ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
420ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
421ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson             NewArgs, NewFD);
422ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
423d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // If an allocation function is declared with an empty exception specification
424d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // it returns null to indicate failure to allocate storage. [expr.new]p13.
425d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // (We don't need to check for null when there's no new initializer and
426d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  // we're allocating a POD type).
427d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
428d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    !(AllocType->isPODType() && !E->hasInitializer());
429ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson
430f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNull = 0;
431f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewNotNull = 0;
432f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::BasicBlock *NewEnd = 0;
433f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
434f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  llvm::Value *NewPtr = RV.getScalarVal();
435f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
436d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  if (NullCheckResult) {
437f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNull = createBasicBlock("new.null");
438f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewNotNull = createBasicBlock("new.notnull");
439f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewEnd = createBasicBlock("new.end");
440f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
441f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::Value *IsNull =
442f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson      Builder.CreateICmpEQ(NewPtr,
443c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson                           llvm::Constant::getNullValue(NewPtr->getType()),
444f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson                           "isnull");
445f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
446f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
447f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNotNull);
448d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  }
449d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
450f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
451d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
4526d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson  if (AllocType->isPODType()) {
453215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson    if (E->getNumConstructorArgs() > 0) {
4546d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      assert(E->getNumConstructorArgs() == 1 &&
4556d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson             "Can only have one argument to initializer of POD type.");
4566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
4576d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson      const Expr *Init = E->getConstructorArg(0);
4586d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
4593923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      if (!hasAggregateLLVMType(AllocType))
4606d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
4613923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson      else if (AllocType->isAnyComplexType())
4623923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
463627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson      else
464627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
4656d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson    }
466d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  } else {
467d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    // Call the constructor.
468d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    CXXConstructorDecl *Ctor = E->getConstructor();
4696d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson
470d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
471d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_begin(),
472d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson                           E->constructor_arg_end());
473ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson  }
474d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson
475f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  if (NullCheckResult) {
476f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
477f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewNull);
478f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    Builder.CreateBr(NewEnd);
479f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    EmitBlock(NewEnd);
480f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
481f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
482f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->reserveOperandSpace(2);
483f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    PHI->addIncoming(NewPtr, NewNotNull);
484c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
485f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
486f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson    NewPtr = PHI;
487f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson  }
488f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson
489d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson  return NewPtr;
490a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson}
491a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson
49227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD,
49327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                   ASTContext &Context) {
49459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  // The class has base classes - we don't support that right now.
49559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  if (RD->getNumBases() > 0)
49659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return false;
49759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
49817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
49917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis         I != E; ++I) {
50059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    // We don't support ctors for fields that aren't POD.
50159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    if (!I->getType()->isPODType())
50259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson      return false;
50359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
50459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
50559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  return true;
50659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson}
50759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson
50895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
50927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
51059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    ErrorUnsupported(D, "C++ constructor", true);
51159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson    return;
51259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson  }
51395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson
5142a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Complete));
5152a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson  EmitGlobal(GlobalDecl(D, Ctor_Base));
51695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson}
517363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
51827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
51927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                       CXXCtorType Type) {
52027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
52127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type);
52227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
52327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
52427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
52527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
52627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
52727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
52827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
529363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function *
530363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
531363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson                                       CXXCtorType Type) {
532363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const llvm::FunctionType *FTy =
533363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
534363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson
535363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson  const char *Name = getMangledCXXCtorName(D, Type);
536b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
537b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
538363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson}
53927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
54027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
54127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXCtorType Type) {
54227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
54327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
54427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXCtor(D, Type, Context, Out);
54527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
54627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
54727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
54827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
54927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
55027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
55127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  if (!canGenerateCXXstructor(D->getParent(), getContext())) {
55227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    ErrorUnsupported(D, "C++ destructor", true);
55327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    return;
55427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  }
55527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
55627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Complete);
55727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  EmitCXXDestructor(D, Dtor_Base);
55827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
55927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
56027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
56127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
56227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type);
56327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
56427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  CodeGenFunction(*this).GenerateCode(D, Fn);
56527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
56627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetFunctionDefinitionAttributes(D, Fn);
56727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  SetLLVMFunctionAttributesForDefinition(D, Fn);
56827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
56927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
57027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function *
57127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
57227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                      CXXDtorType Type) {
57327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const llvm::FunctionType *FTy =
57427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson    getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
57527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
57627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  const char *Name = getMangledCXXDtorName(D, Type);
577b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner  return cast<llvm::Function>(
578b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
57927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
58027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
58127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
58227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson                                                 CXXDtorType Type) {
58327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::SmallString<256> Name;
58427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  llvm::raw_svector_ostream Out(Name);
58527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  mangleCXXDtor(D, Type, Context, Out);
58627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson
58727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  Name += '\0';
58827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson  return UniqueMangledName(Name.begin(), Name.end());
58927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson}
590e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
591738f8c278da5950d0d4607de2debe0bdfad64185Mike Stumpllvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) {
592738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Type *Ptr8Ty;
593738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
594cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty);
595738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
596738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  if (!getContext().getLangOptions().Rtti)
597cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump    return Rtti;
598738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
599738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::SmallString<256> OutName;
600738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::raw_svector_ostream Out(OutName);
601738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  QualType ClassTy;
602e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
603738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  mangleCXXRtti(ClassTy, getContext(), Out);
604738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  const char *Name = OutName.c_str();
605738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::GlobalVariable::LinkageTypes linktype;
606738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
607738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  std::vector<llvm::Constant *> info;
608e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  // assert (0 && "FIXME: implement rtti descriptor");
609738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: descriptor
610738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
611e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  // assert (0 && "FIXME: implement rtti ts");
612738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  // FIXME: TS
613738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  info.push_back(llvm::Constant::getNullValue(Ptr8Ty));
614738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
615738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::Constant *C;
616738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size());
617738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump  C = llvm::ConstantArray::get(type, info);
618cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C,
619738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump                                  Name);
620cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty);
621cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump  return Rtti;
622738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump}
623738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump
6248a12b564923a72224730a467007e61b5701e4aa7Mike Stumpvoid CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD,
625e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump                                            const CXXRecordDecl *Class,
626e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump                                            llvm::Constant *rtti,
627e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump                                         std::vector<llvm::Constant *> &methods,
62802cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump                                            bool isPrimary,
62902cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump                                            bool ForVirtualBase) {
6308a12b564923a72224730a467007e61b5701e4aa7Mike Stump  typedef CXXRecordDecl::method_iterator meth_iter;
6318a12b564923a72224730a467007e61b5701e4aa7Mike Stump  llvm::Type *Ptr8Ty;
6328a12b564923a72224730a467007e61b5701e4aa7Mike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
633e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
634e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
635e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  if (RD && !RD->isDynamicClass())
636e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    return;
63702cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
63802cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump  if (RD && ForVirtualBase)
63902cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump    for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
64002cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump         ++mi) {
64102cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump      if (mi->isVirtual()) {
64202cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        // FIXME: vcall: offset for virtual base for this function
64302cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        m = llvm::Constant::getNullValue(Ptr8Ty);
64402cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        methods.push_back(m);
64502cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump      }
64602cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump    }
64702cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump  if (isPrimary && ForVirtualBase)
64802cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump    for (meth_iter mi = Class->method_begin(),
64902cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump           me = Class->method_end(); mi != me; ++mi) {
65002cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump      if (mi->isVirtual()) {
65102cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        // FIXME: vcall: offset for virtual base for this function
65202cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        m = llvm::Constant::getNullValue(Ptr8Ty);
65302cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump        methods.push_back(m);
65402cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump      }
65502cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump    }
65602cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump
657e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  if (RD) {
658e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Class);
659e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    int64_t BaseOffset = -(Layout.getBaseClassOffset(RD) / 8);
660e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    m = llvm::ConstantInt::get(llvm::Type::Int64Ty, BaseOffset);
661e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
662e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  }
663e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  methods.push_back(m);
664e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  methods.push_back(rtti);
665e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
666e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  if (RD)
667e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
668e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump         ++mi) {
669e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump      if (mi->isVirtual()) {
670e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump        m = CGM.GetAddrOfFunction(GlobalDecl(*mi));
671e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump        m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
672e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump        methods.push_back(m);
673e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump      }
674e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    }
675e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  if (!isPrimary)
676e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump    return;
677e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
678e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  // And add the virtuals for the class to the primary vtable.
67902cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump  for (meth_iter mi = Class->method_begin(), me = Class->method_end(); mi != me;
6808a12b564923a72224730a467007e61b5701e4aa7Mike Stump       ++mi) {
6818a12b564923a72224730a467007e61b5701e4aa7Mike Stump    if (mi->isVirtual()) {
6828a12b564923a72224730a467007e61b5701e4aa7Mike Stump      m = CGM.GetAddrOfFunction(GlobalDecl(*mi));
6838a12b564923a72224730a467007e61b5701e4aa7Mike Stump      m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty);
6848a12b564923a72224730a467007e61b5701e4aa7Mike Stump      methods.push_back(m);
6858a12b564923a72224730a467007e61b5701e4aa7Mike Stump    }
6868a12b564923a72224730a467007e61b5701e4aa7Mike Stump  }
6878a12b564923a72224730a467007e61b5701e4aa7Mike Stump}
6888a12b564923a72224730a467007e61b5701e4aa7Mike Stump
689f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
690f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::SmallString<256> OutName;
691f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::raw_svector_ostream Out(OutName);
692f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  QualType ClassTy;
693e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump  ClassTy = getContext().getTagDeclType(RD);
694f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  mangleCXXVtable(ClassTy, getContext(), Out);
695f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  const char *Name = OutName.c_str();
69682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::GlobalVariable::LinkageTypes linktype;
69782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  linktype = llvm::GlobalValue::WeakAnyLinkage;
69882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  std::vector<llvm::Constant *> methods;
699f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  typedef CXXRecordDecl::method_iterator meth_iter;
70082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Type *Ptr8Ty;
70182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
7026f376336138ea719e3c4757ae046a5768043b276Mike Stump  int64_t Offset = 0;
703e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  llvm::Constant *rtti = GenerateRtti(RD);
704e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump
705e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
706e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump  Offset += LLVMPointerWidth;
7076f376336138ea719e3c4757ae046a5768043b276Mike Stump
7086f376336138ea719e3c4757ae046a5768043b276Mike Stump  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
7096f376336138ea719e3c4757ae046a5768043b276Mike Stump  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
710e6e1d609f6a14882be5336005f5d0222ef18b814Mike Stump  const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
711104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump
71257cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump  // The virtual base offsets come first.
71357cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump  for (CXXRecordDecl::reverse_base_class_const_iterator i = RD->vbases_rbegin(),
71457cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump         e = RD->vbases_rend(); i != e; ++i) {
71557cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    const CXXRecordDecl *Base =
71657cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
71757cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    int64_t BaseOffset = Layout.getBaseClassOffset(Base) / 8;
71857cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    llvm::Constant *m;
71957cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    m = llvm::ConstantInt::get(llvm::Type::Int64Ty, BaseOffset);
72057cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
72157cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump    methods.push_back(m);
72257cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump  }
72357cf2f3abad1c3541cd388d9b7882d65cf6daa7cMike Stump
72470101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump  // The primary base comes first.
725928f1506eb38bb26a1284b876213a8f5244f6933Mike Stump  GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
726928f1506eb38bb26a1284b876213a8f5244f6933Mike Stump                        PrimaryBaseWasVirtual);
727104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
728104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump         e = RD->bases_end(); i != e; ++i) {
729104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump    if (i->isVirtual())
730104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump      continue;
731104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump    const CXXRecordDecl *Base =
732104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
7336f376336138ea719e3c4757ae046a5768043b276Mike Stump    if (PrimaryBase != Base) {
734e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump      GenerateVtableForBase(Base, RD, rtti, methods);
73582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump    }
736f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
73770101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump
7388a12b564923a72224730a467007e61b5701e4aa7Mike Stump  // FIXME: finish layout for virtual bases
7398a12b564923a72224730a467007e61b5701e4aa7Mike Stump  // FIXME: audit indirect virtual bases
7408a12b564923a72224730a467007e61b5701e4aa7Mike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
7418a12b564923a72224730a467007e61b5701e4aa7Mike Stump         e = RD->vbases_end(); i != e; ++i) {
7428a12b564923a72224730a467007e61b5701e4aa7Mike Stump    const CXXRecordDecl *Base =
7438a12b564923a72224730a467007e61b5701e4aa7Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
7448a12b564923a72224730a467007e61b5701e4aa7Mike Stump    if (Base != PrimaryBase)
74502cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump      GenerateVtableForBase(Base, RD, rtti, methods, false, true);
7468a12b564923a72224730a467007e61b5701e4aa7Mike Stump  }
7476f376336138ea719e3c4757ae046a5768043b276Mike Stump
74882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Constant *C;
74982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
75082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  C = llvm::ConstantArray::get(type, methods);
75182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump  llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true,
75282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump                                                 linktype, C, Name);
753f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
754f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  vtable = Builder.CreateGEP(vtable,
755f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump                             llvm::ConstantInt::get(llvm::Type::Int64Ty,
7566f376336138ea719e3c4757ae046a5768043b276Mike Stump                                                    Offset/8));
757f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  return vtable;
758f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump}
759f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
760ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class
761ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy
762ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// of via a copy constructor call.
763ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy(
764942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        llvm::Value *Dest, llvm::Value *Src,
765ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                        const CXXRecordDecl *ClassDecl,
766942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                        const CXXRecordDecl *BaseClassDecl, QualType Ty) {
767942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (ClassDecl) {
768942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl);
769942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ;
770942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
771942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  if (BaseClassDecl->hasTrivialCopyConstructor()) {
772942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitAggregateCopy(Dest, Src, Ty);
773ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    return;
774942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian  }
775942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
776ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  if (CXXConstructorDecl *BaseCopyCtor =
77780e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian      BaseClassDecl->getCopyConstructor(getContext(), 0)) {
778ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
779ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                                      Ctor_Complete);
780ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgList CallArgs;
781ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the this (Dest) ptr.
782ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Dest),
783ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
784ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
785ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    // Push the Src ptr.
786ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    CallArgs.push_back(std::make_pair(RValue::get(Src),
787ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                      BaseCopyCtor->getThisType(getContext())));
788ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    QualType ResultType =
789ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    BaseCopyCtor->getType()->getAsFunctionType()->getResultType();
790ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
791ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian             Callee, CallArgs, BaseCopyCtor);
792ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian  }
793ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian}
794ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
7958c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy
79697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
79797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise
79897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order
79997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor
80097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type:
80197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of class type, the copy constructor for the class is
80297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used;
80397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is an array, each element is copied, in the manner
80497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  appropriate to the element type;
80597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  if the subobject is of scalar type, the built-in assignment operator is
80697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian///  used.
80797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the
80897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor
80997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
8108c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
8118c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       const FunctionDecl *FD,
8128c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian                                       llvm::Function *Fn,
813ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian                                       const FunctionArgList &Args) {
81497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
81597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
8168c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian         "SynthesizeCXXCopyConstructor - copy constructor has definition already");
8178c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
81897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
8191e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  FunctionArgList::const_iterator i = Args.begin();
8201e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *ThisArg = i->first;
8211e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg);
8221e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this");
8231e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  const VarDecl *SrcArg = (i+1)->first;
8241e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg);
8251e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj);
8261e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
82797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
82897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian       Base != ClassDecl->bases_end(); ++Base) {
82997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    // FIXME. copy constrution of virtual base NYI
83097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    if (Base->isVirtual())
83197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      continue;
832ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian
83397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian    CXXRecordDecl *BaseClassDecl
83497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
835942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian    EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
836942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                            Base->getType());
83797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian  }
83897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
8391e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
8401e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       FieldEnd = ClassDecl->field_end();
8411e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian       Field != FieldEnd; ++Field) {
8421e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    QualType FieldType = getContext().getCanonicalType((*Field)->getType());
8431e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
8441e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    // FIXME. How about copying arrays!
8451e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    assert(!getContext().getAsArrayType(FieldType) &&
8461e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian           "FIXME. Copying arrays NYI");
8471e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian
8481e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
8491e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      CXXRecordDecl *FieldClassDecl
8501e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian        = cast<CXXRecordDecl>(FieldClassType->getDecl());
8511e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
8521e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
853942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian
8541e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
855942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian                              0 /*ClassDecl*/, FieldClassDecl, FieldType);
8561e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian      continue;
8571e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    }
8581e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian    // FIXME. Do a built-in assignment of scalar data members.
8591e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian  }
8608c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian  FinishFunction();
86197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian}
86297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
86397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian
864e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize
865e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor.
866e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
867742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
868eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  // FIXME: Add vbase initialization
869f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  llvm::Value *LoadOfThis = 0;
8706d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian
871742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian  for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
872e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       E = CD->init_end();
873e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian       B != E; ++B) {
874e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    CXXBaseOrMemberInitializer *Member = (*B);
875e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    if (Member->isBaseInitializer()) {
876f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
8776d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      Type *BaseType = Member->getBaseClass();
8786d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      CXXRecordDecl *BaseClassDecl =
8796217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek        cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
8806d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl,
8816d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian                                             BaseClassDecl);
882742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian      EmitCXXConstructorCall(Member->getConstructor(),
883742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Ctor_Complete, V,
884742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_begin(),
885742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian                             Member->const_arg_end());
886b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
887e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      // non-static data member initilaizers.
888e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      FieldDecl *Field = Member->getMember();
889e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      QualType FieldType = getContext().getCanonicalType((Field)->getType());
890e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
891e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian             && "FIXME. Field arrays initialization unsupported");
89250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
893f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
894e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
8956217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek      if (FieldType->getAs<RecordType>()) {
89650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian
89750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          assert(Member->getConstructor() &&
89850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                 "EmitCtorPrologue - no constructor to initialize member");
89950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian          EmitCXXConstructorCall(Member->getConstructor(),
90050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Ctor_Complete, LHS.getAddress(),
90150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_begin(),
90250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian                                 Member->const_arg_end());
90350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian        continue;
90450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      }
905e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian
906e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
90750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian      Expr *RhsExpr = *Member->arg_begin();
908e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
909e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      if (LHS.isBitfield())
910e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0);
911e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian      else
912e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian        EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
913e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian    }
914e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian  }
915f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump
916f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  // Initialize the vtable pointer
917b502d839994cc3828573bd9ea472418e3536f415Mike Stump  if (ClassDecl->isDynamicClass()) {
918f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    if (!LoadOfThis)
919f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump      LoadOfThis = LoadCXXThis();
920f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *VtableField;
921f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Type *Ptr8Ty, *PtrPtr8Ty;
922f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
923f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
924f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty);
925f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    llvm::Value *vtable = GenerateVtable(ClassDecl);
926f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump    Builder.CreateStore(vtable, VtableField);
927f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump  }
928e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian}
929426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
930426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's
931426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes
932426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction.
933426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
934426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
935426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  assert(!ClassDecl->isPolymorphic() &&
936426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian         "FIXME. polymorphic destruction not supported");
937426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  (void)ClassDecl;  // prevent warning.
938426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian
939426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
940426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian       *E = DD->destr_end(); B != E; ++B) {
941426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    uintptr_t BaseOrMember = (*B);
942426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    if (DD->isMemberToDestroy(BaseOrMember)) {
943426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
944426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      QualType FieldType = getContext().getCanonicalType((FD)->getType());
945426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      assert(!getContext().getAsArrayType(FieldType)
946426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian             && "FIXME. Field arrays destruction unsupported");
947426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT = FieldType->getAs<RecordType>();
948426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
949426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (FieldClassDecl->hasTrivialDestructor())
950426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
951426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *LoadOfThis = LoadCXXThis();
952426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
953426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
954426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, LHS.getAddress());
955b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump    } else {
956426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      const RecordType *RT =
957426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
958426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
959426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      if (BaseClassDecl->hasTrivialDestructor())
960426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian        continue;
961426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
962426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                                             ClassDecl,BaseClassDecl);
963426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian      EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
964426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian                            Dtor_Complete, V);
965426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian    }
966426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian  }
967426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian}
968