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