CGCXX.cpp revision e45c90f53e3fcb59a48e88862aa5cf5f5538556c
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 1814fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor // A call to a trivial destructor requires no code generation. 1824fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor if (const CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(MD)) 1834fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor if (Destructor->isTrivial()) 1844fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor return RValue::get(0); 1854fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor 186b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 187b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 188b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CallArgList Args; 189b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 190b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson // Push the this ptr. 191b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson Args.push_back(std::make_pair(RValue::get(This), 192b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson MD->getThisType(getContext()))); 193b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 194b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson // And the rest of the call args 195b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); 196774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 197b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); 198b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), 199b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson Callee, Args, MD); 200b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson} 201b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 202b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { 203b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()); 204b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); 205b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 206e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 2077116da1efe23f90eb22524ac9aa036153b74f482Mike Stump 208774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson const llvm::Type *Ty = 209e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 210e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson FPT->isVariadic()); 211b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *This; 212774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 213774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson if (ME->isArrow()) 214b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = EmitScalarExpr(ME->getBase()); 215774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson else { 216774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson LValue BaseLV = EmitLValue(ME->getBase()); 217b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = BaseLV.getAddress(); 218774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson } 219f0070dbae9535836ad41711081465dec2259786bMike Stump 220bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor // C++ [class.virtual]p12: 221bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor // Explicit qualification with the scope operator (5.1) suppresses the 222bd4c4aebe6035e7a7125470cc9f0f92511230ee3Douglas Gregor // virtual call mechanism. 223f0070dbae9535836ad41711081465dec2259786bMike Stump llvm::Value *Callee; 2240979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor if (MD->isVirtual() && !ME->hasQualifier()) 225f0070dbae9535836ad41711081465dec2259786bMike Stump Callee = BuildVirtualCall(MD, This, Ty); 2264fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor else if (const CXXDestructorDecl *Destructor 2274fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor = dyn_cast<CXXDestructorDecl>(MD)) 2284fe95f99a2693f1145785ea5835ba6937e49c730Douglas Gregor Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty); 2290979c805475d1ba49b5d6ef93c4d2ce6d2eab6edDouglas Gregor else 230f0070dbae9535836ad41711081465dec2259786bMike Stump Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 231774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 232b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson return EmitCXXMemberCall(MD, Callee, This, 233b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CE->arg_begin(), CE->arg_end()); 234774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson} 2355f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 2360f294632f36459174199b77699e339715244b5abAnders CarlssonRValue 2370f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 2380f294632f36459174199b77699e339715244b5abAnders Carlsson const CXXMethodDecl *MD) { 2390f294632f36459174199b77699e339715244b5abAnders Carlsson assert(MD->isInstance() && 2400f294632f36459174199b77699e339715244b5abAnders Carlsson "Trying to emit a member call expr on a static method!"); 2410f294632f36459174199b77699e339715244b5abAnders Carlsson 242ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian if (MD->isCopyAssignment()) { 243ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(MD->getDeclContext()); 244ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian if (ClassDecl->hasTrivialCopyAssignment()) { 245ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian assert(!ClassDecl->hasUserDeclaredCopyAssignment() && 246ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian "EmitCXXOperatorMemberCallExpr - user declared copy assignment"); 247ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 248ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress(); 249ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian QualType Ty = E->getType(); 250ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian EmitAggregateCopy(This, Src, Ty); 251ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian return RValue::get(This); 252ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian } 253ad25883a644dd6b52c7923dd128a7d05fb26213cFariborz Jahanian } 2540f294632f36459174199b77699e339715244b5abAnders Carlsson 2550f294632f36459174199b77699e339715244b5abAnders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 2560f294632f36459174199b77699e339715244b5abAnders Carlsson const llvm::Type *Ty = 257ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 258ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump FPT->isVariadic()); 2590f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 2600f294632f36459174199b77699e339715244b5abAnders Carlsson 2610f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 2620f294632f36459174199b77699e339715244b5abAnders Carlsson 2630f294632f36459174199b77699e339715244b5abAnders Carlsson return EmitCXXMemberCall(MD, Callee, This, 2640f294632f36459174199b77699e339715244b5abAnders Carlsson E->arg_begin() + 1, E->arg_end()); 2650f294632f36459174199b77699e339715244b5abAnders Carlsson} 2660f294632f36459174199b77699e339715244b5abAnders Carlsson 26764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz JahanianRValue 26864e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz JahanianCodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) { 26964e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian assert((E->getCastKind() == CastExpr::CK_UserDefinedConversion) && 27064e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian "EmitCXXFunctionalCastExpr - called with wrong cast"); 27164e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian 27264e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian CXXMethodDecl *MD = E->getTypeConversionMethod(); 2734fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian assert(MD && "EmitCXXFunctionalCastExpr - null conversion method"); 2744fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not" 2754fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian " method decl"); 27664e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 27764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian 2784fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian const llvm::Type *Ty = 2794fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 2804fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian FPT->isVariadic()); 2814fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 2824fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress(); 2834fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0); 2844fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian if (RV.isAggregate()) 2854fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian RV = RValue::get(RV.getAggregateAddr()); 2864fc7ab364110d6ad1c10dd38dbeb0597fed7e2f5Fariborz Jahanian return RV; 28764e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian} 28864e690ecf7ba7ad560b0af631bb6f323c38f6da4Fariborz Jahanian 2895f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() { 2905f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(isa<CXXMethodDecl>(CurFuncDecl) && 2915f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 2925f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && 2935f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 2945f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 2955f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson // FIXME: What if we're inside a block? 296f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ans: See how CodeGenFunction::LoadObjCSelf() uses 297f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // CodeGenFunction::BlockForwardSelf() for how to do this. 2985f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 2995f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson} 30095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 301c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool 302c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, 303c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *ClassDecl, 304c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *BaseClassDecl) { 305c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 306c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 307c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 308c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 309c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 310104ffaaa05d31d0a3dc886b7b18ebb2496bc2af4Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 311c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (Base == BaseClassDecl) { 312c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(BaseClassDecl); 313c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 314c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 315c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 316c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian // BaseClassDecl not an immediate base of ClassDecl. 317c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 318c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 319c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 320c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 321c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 322c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 323c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { 324c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(Base); 325c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 326c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 327c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 328c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return false; 329c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian} 330c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 3319e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, 3326d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *ClassDecl, 3336d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *BaseClassDecl) { 3349e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian if (ClassDecl == BaseClassDecl) 3359e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 3369e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 3370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); 338c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; 339c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); 340c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian assert(NestedBasePaths.size() > 0 && 341c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian "AddressCXXOfBaseClass - inheritence path failed"); 342c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(ClassDecl); 343c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian uint64_t Offset = 0; 344c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 3459e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // Accessing a member of the base class. Must add delata to 3469e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // the load of 'this'. 347c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { 348c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; 349c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; 350c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const ASTRecordLayout &Layout = 351c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian getContext().getASTRecordLayout(DerivedClass); 352c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian Offset += Layout.getBaseClassOffset(BaseClass) / 8; 353c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 3545a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::Value *OffsetVal = 3555a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::ConstantInt::get( 3565a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); 3579e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr); 3589e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr"); 3599e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian QualType BTy = 3609e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian getContext().getCanonicalType( 3616d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 3629e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian const llvm::Type *BasePtr = ConvertType(BTy); 36396e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson BasePtr = llvm::PointerType::getUnqual(BasePtr); 3649e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, BasePtr); 3659e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 3669e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian} 3679e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 368288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// EmitCXXAggrConstructorCall - This routine essentially creates a (nested) 369288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// for-loop to call the default constructor on individual members of the 370288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. 'Array' is the array type, 'This' is llvm pointer of the start 371288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// of the array and 'D' is the default costructor Decl for elements of the 372288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// array. It is assumed that all relevant checks have been made by the 373288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian/// caller. 374288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanianvoid 375288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz JahanianCodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 376288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian const ArrayType *Array, 377288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value *This) { 378288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 379288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian assert(CA && "Do we support VLA for construction ?"); 380288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 381288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Create a temporary for the loop index and initialize it with 0. 3820de78998e7bda473b408437053e48661b510d453Fariborz Jahanian llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 383288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian "loop.index"); 384288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value* zeroConstant = 3850de78998e7bda473b408437053e48661b510d453Fariborz Jahanian llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 386288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian Builder.CreateStore(zeroConstant, IndexPtr, false); 387288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 388288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Start the loop with a block that tests the condition. 389288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 390288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 391288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 392288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitBlock(CondBlock); 393288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 394288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 395288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 396288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Generate: if (loop-index < number-of-elements fall to the loop body, 397288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // otherwise, go to the block after the for-loop. 3984f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 399288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value * NumElementsPtr = 4004f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 401288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 402288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 403288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian "isless"); 404288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // If the condition is true, execute the body. 405288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian Builder.CreateCondBr(IsLess, ForBody, AfterFor); 406288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 407288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitBlock(ForBody); 408288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 409288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 410288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Inside the loop body, emit the constructor call on the array element. 411995d2818a11395b15995694a30f842a0e4fdee4fFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 4124f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); 4134f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian EmitCXXConstructorCall(D, Ctor_Complete, Address, 0, 0); 4146147a908f6d2a67dde46328c83332b92265ab3aeFariborz Jahanian 415288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitBlock(ContinueBlock); 416288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 417288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Emit the increment of the loop counter. 418288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 419288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 420288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 421288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian Builder.CreateStore(NextVal, IndexPtr, false); 422288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 423288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Finally, branch back up to the condition for the next iteration. 424288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitBranch(CondBlock); 425288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 426288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian // Emit the fall-through block. 427288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitBlock(AfterFor, true); 428288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian} 429288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 4301c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// EmitCXXAggrDestructorCall - calls the default destructor on array 4311c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian/// elements in reverse order of construction. 432b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 433f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz JahanianCodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, 434f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian const ArrayType *Array, 435f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian llvm::Value *This) { 4361c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 4371c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian assert(CA && "Do we support VLA for destruction ?"); 4381c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 4391c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 1); 4400de78998e7bda473b408437053e48661b510d453Fariborz Jahanian uint64_t ElementCount = getContext().getConstantArrayElementCount(CA); 4411c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Create a temporary for the loop index and initialize it with count of 4421c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // array elements. 4431c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 4441c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian "loop.index"); 4451c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Index = ElementCount; 4461c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value* UpperCount = 4471c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount); 4481c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Builder.CreateStore(UpperCount, IndexPtr, false); 4491c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4501c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Start the loop with a block that tests the condition. 4511c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 4521c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 4531c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4541c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitBlock(CondBlock); 4551c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4561c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 4571c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4581c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Generate: if (loop-index != 0 fall to the loop body, 4591c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // otherwise, go to the block after the for-loop. 4601c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value* zeroConstant = 4611c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 4621c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 4631c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant, 4641c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian "isne"); 4651c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // If the condition is true, execute the body. 4661c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Builder.CreateCondBr(IsNE, ForBody, AfterFor); 4671c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4681c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitBlock(ForBody); 4691c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4701c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 4711c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Inside the loop body, emit the constructor call on the array element. 4721c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 4731c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Counter = Builder.CreateSub(Counter, One); 4741c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); 4751c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitCXXDestructorCall(D, Dtor_Complete, Address); 4761c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4771c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitBlock(ContinueBlock); 4781c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4791c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Emit the decrement of the loop counter. 4801c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 4811c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Counter = Builder.CreateSub(Counter, One, "dec"); 4821c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian Builder.CreateStore(Counter, IndexPtr, false); 4831c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4841c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Finally, branch back up to the condition for the next iteration. 4851c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitBranch(CondBlock); 4861c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian 4871c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian // Emit the fall-through block. 4881c536bf6bbb0cdc039cff754825b36f9abfe0629Fariborz Jahanian EmitBlock(AfterFor, true); 489f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian} 490f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian 491f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanianvoid 492b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 493b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CXXCtorType Type, 494b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson llvm::Value *This, 495b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgBeg, 496b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgEnd) { 497343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian if (D->isCopyConstructor(getContext())) { 498343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D->getDeclContext()); 499343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian if (ClassDecl->hasTrivialCopyConstructor()) { 500343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 501343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian "EmitCXXConstructorCall - user declared copy constructor"); 502343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian const Expr *E = (*ArgBeg); 503343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian QualType Ty = E->getType(); 504343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian llvm::Value *Src = EmitLValue(E).getAddress(); 505343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian EmitAggregateCopy(This, Src, Ty); 506343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian return; 507343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian } 508343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian } 509343a3cf57ee950b024bade8b6b0a2b51663f43cdFariborz Jahanian 510b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 511b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 512b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 513b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 514b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 5157267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 5167267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson CXXDtorType Type, 5177267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *This) { 5187267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 5197267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 5207267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson EmitCXXMemberCall(D, Callee, This, 0, 0); 5217267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson} 5227267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 523b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 52431ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 52531ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson const CXXConstructExpr *E) { 526b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson assert(Dest && "Must have a destination!"); 527b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 528b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson const CXXRecordDecl *RD = 5296217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); 530b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson if (RD->hasTrivialConstructor()) 531b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson return; 5326904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian 5336904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian // Code gen optimization to eliminate copy constructor and return 5346904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian // its first argument instead. 53592f5822df6a0d7571df44b5d279ed4f017fbb0e6Anders Carlsson if (getContext().getLangOptions().ElideConstructors && E->isElidable()) { 5366904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian CXXConstructExpr::const_arg_iterator i = E->arg_begin(); 5371cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian EmitAggExpr((*i), Dest, false); 5381cf9ff87ee235ad252332a96699abdb32bd6facbFariborz Jahanian return; 5396904cbb1f21002317387e8fc7b14b7f8c09d198fFariborz Jahanian } 540b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson // Call the constructor. 541b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 542b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson E->arg_begin(), E->arg_end()); 543b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 544b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 545a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 546ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson if (E->isArray()) { 547ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ErrorUnsupported(E, "new[] expression"); 54803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return llvm::UndefValue::get(ConvertType(E->getType())); 549ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 550ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 551ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType AllocType = E->getAllocatedType(); 552ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson FunctionDecl *NewFD = E->getOperatorNew(); 553ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 554ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 555ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CallArgList NewArgs; 556ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 557ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // The allocation size is the first argument. 558ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType SizeTy = getContext().getSizeType(); 559ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson llvm::Value *AllocSize = 5604a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ConvertType(SizeTy), 561ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getTypeSize(AllocType) / 8); 562ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 563ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 564ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 565ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the rest of the arguments. 566ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // FIXME: Ideally, this should just use EmitCallArgs. 567ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 568ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 569ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // First, use the types from the function type. 570ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // We start at 1 here because the first argument (the allocation size) 571ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // has already been emitted. 572ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 573ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewFTy->getArgType(i); 574ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 575ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 576ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getTypePtr() == 577ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 578ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "type mismatch in call argument!"); 579ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 580ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 581ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 582ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 583ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 584ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 585ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Either we've emitted all the call args, or we have a call to a 586ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // variadic function. 587ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 588ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "Extra arguments in non-variadic function!"); 589ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 590ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // If we still have any arguments, emit them using the type of the argument. 591ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 592ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArg != NewArgEnd; ++NewArg) { 593ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewArg->getType(); 594ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 595ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 596ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 597ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 598ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the call to new. 599ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson RValue RV = 600ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 601ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 602ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs, NewFD); 603ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 604d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // If an allocation function is declared with an empty exception specification 605d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // it returns null to indicate failure to allocate storage. [expr.new]p13. 606d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // (We don't need to check for null when there's no new initializer and 607d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // we're allocating a POD type). 608d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 609d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson !(AllocType->isPODType() && !E->hasInitializer()); 610ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 611f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNull = 0; 612f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNotNull = 0; 613f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewEnd = 0; 614f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 615f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *NewPtr = RV.getScalarVal(); 616f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 617d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson if (NullCheckResult) { 618f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNull = createBasicBlock("new.null"); 619f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNotNull = createBasicBlock("new.notnull"); 620f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewEnd = createBasicBlock("new.end"); 621f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 622f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *IsNull = 623f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateICmpEQ(NewPtr, 624c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(NewPtr->getType()), 625f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson "isnull"); 626f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 627f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateCondBr(IsNull, NewNull, NewNotNull); 628f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNotNull); 629d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } 630d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 631f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); 632d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 6336d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson if (AllocType->isPODType()) { 634215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson if (E->getNumConstructorArgs() > 0) { 6356d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson assert(E->getNumConstructorArgs() == 1 && 6366d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson "Can only have one argument to initializer of POD type."); 6376d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 6386d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson const Expr *Init = E->getConstructorArg(0); 6396d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 6403923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson if (!hasAggregateLLVMType(AllocType)) 6416d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 6423923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson else if (AllocType->isAnyComplexType()) 6433923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 644627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson else 645627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 6466d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson } 647d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } else { 648d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // Call the constructor. 649d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson CXXConstructorDecl *Ctor = E->getConstructor(); 6506d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 651d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 652d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_begin(), 653d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_end()); 654ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 655d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 656f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson if (NullCheckResult) { 657f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 658f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNull); 659f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 660f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewEnd); 661f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 662f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); 663f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->reserveOperandSpace(2); 664f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->addIncoming(NewPtr, NewNotNull); 665c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull); 666f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 667f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = PHI; 668f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson } 669f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 670d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson return NewPtr; 671a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson} 672a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson 67360e282cc1e508be327b0481cecedc206873cb86aAnders Carlssonvoid CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { 67460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson if (E->isArrayForm()) { 67560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson ErrorUnsupported(E, "delete[] expression"); 67660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson return; 67760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson }; 67860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 67960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson QualType DeleteTy = 68060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson E->getArgument()->getType()->getAs<PointerType>()->getPointeeType(); 68160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 68260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson llvm::Value *Ptr = EmitScalarExpr(E->getArgument()); 68360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 68460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson // Null check the pointer. 68560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull"); 68660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end"); 68760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 68860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson llvm::Value *IsNull = 68960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()), 69060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson "isnull"); 69160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 69260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull); 69360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson EmitBlock(DeleteNotNull); 69460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 69560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson // Call the destructor if necessary. 69660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson if (const RecordType *RT = DeleteTy->getAs<RecordType>()) { 69760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 69860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson if (!RD->hasTrivialDestructor()) { 69960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson const CXXDestructorDecl *Dtor = RD->getDestructor(getContext()); 70060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson if (Dtor->isVirtual()) { 70160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson ErrorUnsupported(E, "delete expression with virtual destructor"); 70260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson return; 70360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson } 70460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 70560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr); 70660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson } 70760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson } 70860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson } 70960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 71060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson // Call delete. 71160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson FunctionDecl *DeleteFD = E->getOperatorDelete(); 71260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson const FunctionProtoType *DeleteFTy = 71360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson DeleteFD->getType()->getAsFunctionProtoType(); 71460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 71560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson CallArgList DeleteArgs; 71660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 71760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson QualType ArgTy = DeleteFTy->getArgType(0); 71860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy)); 71960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy)); 72060e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 72160e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson // Emit the call to delete. 72260e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(), 72360e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson DeleteArgs), 72460e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson CGM.GetAddrOfFunction(GlobalDecl(DeleteFD)), 72560e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson DeleteArgs, DeleteFD); 72660e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 72760e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson EmitBlock(DeleteEnd); 72860e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson} 72960e282cc1e508be327b0481cecedc206873cb86aAnders Carlsson 73095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 7312a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Complete)); 7322a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Base)); 73395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson} 734363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 73527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 73627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 73727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 73827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 73927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 74027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 74127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 74227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 74327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 74427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 74527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 746363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function * 747363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 748363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson CXXCtorType Type) { 749363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const llvm::FunctionType *FTy = 750363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 751363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 752363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const char *Name = getMangledCXXCtorName(D, Type); 753b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 754b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 755363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson} 75627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 75727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 75827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 75927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 76027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 76127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXCtor(D, Type, Context, Out); 76227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 76327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 76427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 76527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 76627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 76727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 76827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Complete); 76927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Base); 77027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 77127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 77227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 77327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 77427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 77527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 77627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 77727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 77827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 77927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 78027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 78127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 78227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function * 78327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 78427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 78527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const llvm::FunctionType *FTy = 78627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 78727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 78827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const char *Name = getMangledCXXDtorName(D, Type); 789b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 790b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 79127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 79227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 79327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 79427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 79527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 79627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 79727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXDtor(D, Type, Context, Out); 79827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 79927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 80027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 80127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 802e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 80332f3701853a8237704065c77abc17369dd02c39bMike Stumpllvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) { 804738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::Type *Ptr8Ty; 8050032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 806cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty); 807738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 808738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump if (!getContext().getLangOptions().Rtti) 809cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump return Rtti; 810738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 811738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::SmallString<256> OutName; 812738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::raw_svector_ostream Out(OutName); 813738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump QualType ClassTy; 814e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump ClassTy = getContext().getTagDeclType(RD); 815738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump mangleCXXRtti(ClassTy, getContext(), Out); 816738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::GlobalVariable::LinkageTypes linktype; 817738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump linktype = llvm::GlobalValue::WeakAnyLinkage; 818738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump std::vector<llvm::Constant *> info; 8194ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump // assert(0 && "FIXME: implement rtti descriptor"); 820738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // FIXME: descriptor 821738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 8224ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump // assert(0 && "FIXME: implement rtti ts"); 823738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // FIXME: TS 824738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 825738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 826738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::Constant *C; 827738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size()); 828738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump C = llvm::ConstantArray::get(type, info); 82932f3701853a8237704065c77abc17369dd02c39bMike Stump Rtti = new llvm::GlobalVariable(getModule(), type, true, linktype, C, 8307765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar Out.str()); 831cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty); 832cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump return Rtti; 833738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump} 834738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 835eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stumpclass VtableBuilder { 836f0070dbae9535836ad41711081465dec2259786bMike Stumppublic: 837f0070dbae9535836ad41711081465dec2259786bMike Stump /// Index_t - Vtable index type. 838f0070dbae9535836ad41711081465dec2259786bMike Stump typedef uint64_t Index_t; 839f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate: 8407c435fa7f7666b22abbe8494c537ebc25209223dMike Stump std::vector<llvm::Constant *> &methods; 84115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump std::vector<llvm::Constant *> submethods; 8427c435fa7f7666b22abbe8494c537ebc25209223dMike Stump llvm::Type *Ptr8Ty; 843b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump /// Class - The most derived class that this vtable is being built for. 84432f3701853a8237704065c77abc17369dd02c39bMike Stump const CXXRecordDecl *Class; 845b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump /// BLayout - Layout for the most derived class that this vtable is being 846b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump /// built for. 847b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump const ASTRecordLayout &BLayout; 848ee560f3b1fda7d5ec68b85b497c3e326ac5c3fdbMike Stump llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary; 8497fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase; 85032f3701853a8237704065c77abc17369dd02c39bMike Stump llvm::Constant *rtti; 8517c435fa7f7666b22abbe8494c537ebc25209223dMike Stump llvm::LLVMContext &VMContext; 85265defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump CodeGenModule &CGM; // Per-module state. 853b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump /// Index - Maps a method decl into a vtable index. Useful for virtual 854b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump /// dispatch codegen. 855f0070dbae9535836ad41711081465dec2259786bMike Stump llvm::DenseMap<const CXXMethodDecl *, Index_t> Index; 85615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall; 85715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset; 85877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump typedef llvm::DenseMap<const CXXMethodDecl *, 85977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump std::pair<Index_t, Index_t> > Thunks_t; 86077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Thunks_t Thunks; 86115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump std::vector<Index_t> VCalls; 862552b275708a25aa1d939b2b77e5419a0b4b8e6d4Mike Stump typedef CXXRecordDecl::method_iterator method_iter; 863ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump // FIXME: Linkage should follow vtable 864ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump const bool Extern; 86577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump const uint32_t LLVMPointerWidth; 86677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t extra; 8677c435fa7f7666b22abbe8494c537ebc25209223dMike Stumppublic: 868eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump VtableBuilder(std::vector<llvm::Constant *> &meth, 869eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump const CXXRecordDecl *c, 870eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump CodeGenModule &cgm) 871b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)), 872b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()), 87377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump CGM(cgm), Extern(true), 87477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) { 8757c435fa7f7666b22abbe8494c537ebc25209223dMike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 8767c435fa7f7666b22abbe8494c537ebc25209223dMike Stump } 87732f3701853a8237704065c77abc17369dd02c39bMike Stump 878f0070dbae9535836ad41711081465dec2259786bMike Stump llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; } 879b46c92dfedf02239e7c73b9a18dcf09071731793Mike Stump 88015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump llvm::Constant *wrap(Index_t i) { 8817c435fa7f7666b22abbe8494c537ebc25209223dMike Stump llvm::Constant *m; 88215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), i); 88315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump return llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty); 88415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump } 8857c435fa7f7666b22abbe8494c537ebc25209223dMike Stump 88615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump llvm::Constant *wrap(llvm::Constant *m) { 88715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump return llvm::ConstantExpr::getBitCast(m, Ptr8Ty); 88880a0e32d60e4ff7d78f411e73f3e8dea769ed313Mike Stump } 8894c3aedd3f1fff57d1906b0cdfa7a9ec81a361b2dMike Stump 8907fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets, 891b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump const CXXRecordDecl *RD, uint64_t Offset) { 8927fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(), 8937fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump e = RD->bases_end(); i != e; ++i) { 8947fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump const CXXRecordDecl *Base = 8957fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 8967fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump if (i->isVirtual() && !SeenVBase.count(Base)) { 8977fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump SeenVBase.insert(Base); 898b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8; 89915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump llvm::Constant *m = wrap(BaseOffset); 90015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump m = wrap((0?700:0) + BaseOffset); 9017fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump offsets.push_back(m); 9027fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump } 903b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump GenerateVBaseOffsets(offsets, Base, Offset); 9047fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump } 9057fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump } 9067fa0d93a3bbe290244f4f157078d9a0d6e87b44fMike Stump 907b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump void StartNewTable() { 908b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump SeenVBase.clear(); 909b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump } 91065defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump 91135191b61db617aefba43b8add88a2ec88af67592Mike Stump bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m, 912ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump bool MorallyVirtual, Index_t Offset, 913ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump std::vector<llvm::Constant *> &submethods, 914ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump Index_t AddressPoint) { 915b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump typedef CXXMethodDecl::method_iterator meth_iter; 916b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump 917b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // FIXME: Don't like the nested loops. For very large inheritance 918b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // heirarchies we could have a table on the side with the final overridder 919b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // and just replace each instance of an overridden method once. Would be 920b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // nice to measure the cost/benefit on real code. 921b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump 922b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump for (meth_iter mi = MD->begin_overridden_methods(), 923b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump e = MD->end_overridden_methods(); 924b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump mi != e; ++mi) { 925b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump const CXXMethodDecl *OMD = *mi; 926b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump llvm::Constant *om; 927b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump om = CGM.GetAddrOfFunction(GlobalDecl(OMD), Ptr8Ty); 928b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump om = llvm::ConstantExpr::getBitCast(om, Ptr8Ty); 929b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump 930ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump for (Index_t i = AddressPoint, e = submethods.size(); 931f0070dbae9535836ad41711081465dec2259786bMike Stump i != e; ++i) { 932b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // FIXME: begin_overridden_methods might be too lax, covariance */ 93377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (submethods[i] != om) 93477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump continue; 93577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump submethods[i] = m; 93677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index[MD] = i - AddressPoint; 93777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump 93877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Thunks.erase(OMD); 93977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (MorallyVirtual) { 94077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump VCallOffset[MD] = Offset/8; 94177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t &idx = VCall[OMD]; 94277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (idx == 0) { 94377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump idx = VCalls.size()+1; 94477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump VCalls.push_back(0); 94515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump } 94677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump VCalls[idx] = Offset/8 - VCallOffset[OMD]; 94777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump VCall[MD] = idx; 94877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump // FIXME: 0? 94977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Thunks[MD] = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8)); 95035191b61db617aefba43b8add88a2ec88af67592Mike Stump return true; 951b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump } 95277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#if 0 95377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump // FIXME: finish off 95477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump int64_t O = VCallOffset[OMD] - Offset/8; 95577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (O) { 95677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Thunks[MD] = std::make_pair(O, 0); 95777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 95877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump#endif 95977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump return true; 96065defe3ee7be121aef50b498e51f1d831b4a15f3Mike Stump } 961bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump } 962b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump 96335191b61db617aefba43b8add88a2ec88af67592Mike Stump return false; 96435191b61db617aefba43b8add88a2ec88af67592Mike Stump } 96535191b61db617aefba43b8add88a2ec88af67592Mike Stump 96677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump void InstallThunks(Index_t AddressPoint) { 96777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end(); 96877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump i != e; ++i) { 96977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump const CXXMethodDecl *MD = i->first; 97077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t idx = Index[MD]; 97177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t nv_O = i->second.first; 97277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t v_O = i->second.second; 97377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump methods[AddressPoint + idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O); 97477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 97577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Thunks.clear(); 97677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 97777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump 978f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump void OverrideMethods(const CXXRecordDecl *RD, Index_t AddressPoint, 979f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump bool MorallyVirtual, Index_t Offset) { 980f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 981f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump ++mi) 982f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump if (mi->isVirtual()) { 983f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump const CXXMethodDecl *MD = *mi; 984f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty)); 985ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump OverrideMethod(MD, m, MorallyVirtual, Offset, methods, AddressPoint); 986f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump } 987f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump } 988f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump 9896d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual, Index_t Offset) { 990f9a883c27e3b5724a5a59499691fa109eb5032f8Mike Stump llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty)); 99177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump // If we can find a previously allocated slot for this, reuse it. 992ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0)) 99335191b61db617aefba43b8add88a2ec88af67592Mike Stump return; 99435191b61db617aefba43b8add88a2ec88af67592Mike Stump 995b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump // else allocate a new slot. 99615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump Index[MD] = submethods.size(); 99715a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump if (MorallyVirtual) { 99815a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump VCallOffset[MD] = Offset/8; 99915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump Index_t &idx = VCall[MD]; 100015a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump // Allocate the first one, after that, we reuse the previous one. 100115a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump if (idx == 0) { 100215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump idx = VCalls.size()+1; 100315a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump VCalls.push_back(0); 100415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump } 100515a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump } 100615a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump submethods.push_back(m); 1007b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump } 1008b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump 10096d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual, 10106d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump Index_t Offset) { 1011b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 1012b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump ++mi) 1013b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump if (mi->isVirtual()) 10146d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump AddMethod(*mi, MorallyVirtual, Offset); 1015bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump } 1016bc16aeab78748cca01a9d84fff71dd1109633ecdMike Stump 101777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout, 101877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump const CXXRecordDecl *PrimaryBase, 101977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump bool PrimaryBaseWasVirtual, bool MorallyVirtual, 102077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump int64_t Offset) { 102177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 102277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump e = RD->bases_end(); i != e; ++i) { 102377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (i->isVirtual()) 102477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump continue; 102577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump const CXXRecordDecl *Base = 102677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 102777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump if (Base != PrimaryBase || PrimaryBaseWasVirtual) { 102877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump uint64_t o = Offset + Layout.getBaseClassOffset(Base); 102977ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump StartNewTable(); 103077ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump Index_t AP; 1031e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump AP = GenerateVtableForBase(Base, MorallyVirtual, o, false); 103277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump OverrideMethods(RD, AP, MorallyVirtual, o); 103377ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump InstallThunks(AP); 103477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 103577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 103677ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump } 103777ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump 10386d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant *> &offsets, 10396d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump const ASTRecordLayout &Layout, 10406d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump const CXXRecordDecl *PrimaryBase, 10416d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump bool PrimaryBaseWasVirtual, bool MorallyVirtual, 10426d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump int64_t Offset, bool ForVirtualBase) { 10436d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump StartNewTable(); 10446d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump extra = 0; 10456d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump // FIXME: Cleanup. 10466d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump if (!ForVirtualBase) { 10476d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump // then virtual base offsets... 10486d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(), 10496d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump e = offsets.rend(); i != e; ++i) 10506d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.push_back(*i); 10516d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump } 10526d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 10536d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump // The vcalls come first... 10546d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump for (std::vector<Index_t>::iterator i=VCalls.begin(), e=VCalls.end(); 10556d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump i < e; ++i) 10566d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.push_back(wrap((0?600:0) + *i)); 10576d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump VCalls.clear(); 10586d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 10596d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump if (ForVirtualBase) { 10606d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump // then virtual base offsets... 10616d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(), 10626d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump e = offsets.rend(); i != e; ++i) 10636d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.push_back(*i); 10646d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump } 10656d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 10666d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.push_back(wrap(-(Offset/8))); 10676d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.push_back(rtti); 10686d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump Index_t AddressPoint = methods.size(); 10696d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 10706d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump methods.insert(methods.end(), submethods.begin(), submethods.end()); 10716d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump submethods.clear(); 10726d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump InstallThunks(AddressPoint); 10736d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 10746d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump // and then the non-virtual bases. 10756d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, 10766d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump MorallyVirtual, Offset); 10776d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump return AddressPoint; 10786d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump } 10796d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump 1080078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual, int64_t Offset) { 10819bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump if (!RD->isDynamicClass()) 10829bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump return; 10839bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump 10849bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 10859bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 10869bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 10879bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump 10889bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump // vtables are composed from the chain of primaries. 10899bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump if (PrimaryBase) { 10909bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump if (PrimaryBaseWasVirtual) 10919bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump IndirectPrimary.insert(PrimaryBase); 1092078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset); 10939bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump } 10949bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump 10959bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump // And add the virtuals for the class to the primary vtable. 10969bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump AddMethods(RD, MorallyVirtual, Offset); 10979bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump } 10989bbe962611ebdcfdd1e5e312113ad4efd13472b2Mike Stump 1099e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump int64_t GenerateVtableForBase(const CXXRecordDecl *RD, 1100b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump bool MorallyVirtual, int64_t Offset, 1101b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump bool ForVirtualBase) { 1102bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump if (!RD->isDynamicClass()) 1103263b3522add846130ff5f0a85568234e612a81caMike Stump return 0; 1104109b13db3391face0b393c730f0326ca51d25b52Mike Stump 1105109b13db3391face0b393c730f0326ca51d25b52Mike Stump const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); 1106109b13db3391face0b393c730f0326ca51d25b52Mike Stump const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1107109b13db3391face0b393c730f0326ca51d25b52Mike Stump const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); 1108109b13db3391face0b393c730f0326ca51d25b52Mike Stump 110915a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump std::vector<llvm::Constant *> offsets; 1110b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump extra = 0; 1111b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump GenerateVBaseOffsets(offsets, RD, Offset); 1112b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump if (ForVirtualBase) 1113b4d2861371d84a5cc98462676da4e6bb8c2d7c03Mike Stump extra = offsets.size(); 111402cf1e264719b4dada4377cc8a43888cb66f8815Mike Stump 1115109b13db3391face0b393c730f0326ca51d25b52Mike Stump // vtables are composed from the chain of primaries. 1116109b13db3391face0b393c730f0326ca51d25b52Mike Stump if (PrimaryBase) { 1117109b13db3391face0b393c730f0326ca51d25b52Mike Stump if (PrimaryBaseWasVirtual) 1118109b13db3391face0b393c730f0326ca51d25b52Mike Stump IndirectPrimary.insert(PrimaryBase); 1119078d778d8ea4a3975a985da4e8aaef2d269c82faMike Stump Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual, Offset); 1120109b13db3391face0b393c730f0326ca51d25b52Mike Stump } 1121276b9f1d814f4f6551cc3000590759a34185d6daMike Stump 112215a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump // And add the virtuals for the class to the primary vtable. 11236d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump AddMethods(RD, MorallyVirtual, Offset); 112415a24e0e0737c3aa6f85fd18af64c3b6195454c3Mike Stump 11256d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual, 11266d10eb828b32b7a1058809c59ce6c3e2c46b18d7Mike Stump MorallyVirtual, Offset, ForVirtualBase); 1127276b9f1d814f4f6551cc3000590759a34185d6daMike Stump } 1128276b9f1d814f4f6551cc3000590759a34185d6daMike Stump 1129bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump void GenerateVtableForVBases(const CXXRecordDecl *RD) { 1130109b13db3391face0b393c730f0326ca51d25b52Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 1131109b13db3391face0b393c730f0326ca51d25b52Mike Stump e = RD->bases_end(); i != e; ++i) { 1132109b13db3391face0b393c730f0326ca51d25b52Mike Stump const CXXRecordDecl *Base = 1133109b13db3391face0b393c730f0326ca51d25b52Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 1134109b13db3391face0b393c730f0326ca51d25b52Mike Stump if (i->isVirtual() && !IndirectPrimary.count(Base)) { 1135109b13db3391face0b393c730f0326ca51d25b52Mike Stump // Mark it so we don't output it twice. 1136109b13db3391face0b393c730f0326ca51d25b52Mike Stump IndirectPrimary.insert(Base); 1137b9871a253d351e8776cfa5483d6330d5dffe4562Mike Stump StartNewTable(); 1138b983744cccb7e2e5c2bc96de3dcc090ed17fa392Mike Stump int64_t BaseOffset = BLayout.getVBaseClassOffset(Base); 1139ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump Index_t AP; 1140e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump AP = GenerateVtableForBase(Base, true, BaseOffset, true); 1141ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump OverrideMethods(RD, AP, true, BaseOffset); 114277ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump InstallThunks(AP); 1143109b13db3391face0b393c730f0326ca51d25b52Mike Stump } 1144109b13db3391face0b393c730f0326ca51d25b52Mike Stump if (Base->getNumVBases()) 1145bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump GenerateVtableForVBases(Base); 1146109b13db3391face0b393c730f0326ca51d25b52Mike Stump } 1147e1be2b16a3a24acda0b63c3dcb4ae3384fcdaf75Mike Stump } 1148109b13db3391face0b393c730f0326ca51d25b52Mike Stump}; 11498a12b564923a72224730a467007e61b5701e4aa7Mike Stump 1150f0070dbae9535836ad41711081465dec2259786bMike Stumpclass VtableInfo { 1151f0070dbae9535836ad41711081465dec2259786bMike Stumppublic: 1152f0070dbae9535836ad41711081465dec2259786bMike Stump typedef VtableBuilder::Index_t Index_t; 1153f0070dbae9535836ad41711081465dec2259786bMike Stumpprivate: 1154f0070dbae9535836ad41711081465dec2259786bMike Stump CodeGenModule &CGM; // Per-module state. 1155f0070dbae9535836ad41711081465dec2259786bMike Stump /// Index_t - Vtable index type. 1156f0070dbae9535836ad41711081465dec2259786bMike Stump typedef llvm::DenseMap<const CXXMethodDecl *, Index_t> ElTy; 1157f0070dbae9535836ad41711081465dec2259786bMike Stump typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy; 1158f0070dbae9535836ad41711081465dec2259786bMike Stump // FIXME: Move to Context. 1159f0070dbae9535836ad41711081465dec2259786bMike Stump static MapTy IndexFor; 1160f0070dbae9535836ad41711081465dec2259786bMike Stumppublic: 1161f0070dbae9535836ad41711081465dec2259786bMike Stump VtableInfo(CodeGenModule &cgm) : CGM(cgm) { } 1162f0070dbae9535836ad41711081465dec2259786bMike Stump void register_index(const CXXRecordDecl *RD, const ElTy &e) { 1163f0070dbae9535836ad41711081465dec2259786bMike Stump assert(IndexFor.find(RD) == IndexFor.end() && "Don't compute vtbl twice"); 1164f0070dbae9535836ad41711081465dec2259786bMike Stump // We own a copy of this, it will go away shortly. 1165f0070dbae9535836ad41711081465dec2259786bMike Stump new ElTy (e); 1166f0070dbae9535836ad41711081465dec2259786bMike Stump IndexFor[RD] = new ElTy (e); 1167f0070dbae9535836ad41711081465dec2259786bMike Stump } 1168f0070dbae9535836ad41711081465dec2259786bMike Stump Index_t lookup(const CXXMethodDecl *MD) { 1169f0070dbae9535836ad41711081465dec2259786bMike Stump const CXXRecordDecl *RD = MD->getParent(); 1170f0070dbae9535836ad41711081465dec2259786bMike Stump MapTy::iterator I = IndexFor.find(RD); 1171f0070dbae9535836ad41711081465dec2259786bMike Stump if (I == IndexFor.end()) { 1172f0070dbae9535836ad41711081465dec2259786bMike Stump std::vector<llvm::Constant *> methods; 1173f0070dbae9535836ad41711081465dec2259786bMike Stump VtableBuilder b(methods, RD, CGM); 1174e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump b.GenerateVtableForBase(RD, false, 0, false); 1175bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump b.GenerateVtableForVBases(RD); 1176f0070dbae9535836ad41711081465dec2259786bMike Stump register_index(RD, b.getIndex()); 1177f0070dbae9535836ad41711081465dec2259786bMike Stump I = IndexFor.find(RD); 1178f0070dbae9535836ad41711081465dec2259786bMike Stump } 1179f0070dbae9535836ad41711081465dec2259786bMike Stump assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index"); 1180f0070dbae9535836ad41711081465dec2259786bMike Stump return (*I->second)[MD]; 1181f0070dbae9535836ad41711081465dec2259786bMike Stump } 1182f0070dbae9535836ad41711081465dec2259786bMike Stump}; 1183f0070dbae9535836ad41711081465dec2259786bMike Stump 1184f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: Move to Context. 1185f0070dbae9535836ad41711081465dec2259786bMike StumpVtableInfo::MapTy VtableInfo::IndexFor; 1186f0070dbae9535836ad41711081465dec2259786bMike Stump 1187f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { 1188f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::SmallString<256> OutName; 1189f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::raw_svector_ostream Out(OutName); 1190f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump QualType ClassTy; 1191e607ed068334bacb8d7b093996b4671c6ca79e25Mike Stump ClassTy = getContext().getTagDeclType(RD); 1192f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump mangleCXXVtable(ClassTy, getContext(), Out); 119382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::GlobalVariable::LinkageTypes linktype; 119482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump linktype = llvm::GlobalValue::WeakAnyLinkage; 119582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump std::vector<llvm::Constant *> methods; 1196276b9f1d814f4f6551cc3000590759a34185d6daMike Stump llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 1197263b3522add846130ff5f0a85568234e612a81caMike Stump int64_t Offset; 11986f376336138ea719e3c4757ae046a5768043b276Mike Stump 1199eb7e9c39f3b8ac815a78003992f2c2c662c0ab52Mike Stump VtableBuilder b(methods, RD, CGM); 1200109b13db3391face0b393c730f0326ca51d25b52Mike Stump 1201276b9f1d814f4f6551cc3000590759a34185d6daMike Stump // First comes the vtables for all the non-virtual bases... 1202e45c90f53e3fcb59a48e88862aa5cf5f5538556cMike Stump Offset = b.GenerateVtableForBase(RD, false, 0, false); 120370101ce87ff1d73ac90e4d99a3af0ae509e5934fMike Stump 1204276b9f1d814f4f6551cc3000590759a34185d6daMike Stump // then the vtables for all the virtual bases. 1205bf595a3b1f1737eb60203856ea34b759c4c09c46Mike Stump b.GenerateVtableForVBases(RD); 12066f376336138ea719e3c4757ae046a5768043b276Mike Stump 120782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Constant *C; 120882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size()); 120982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump C = llvm::ConstantArray::get(type, methods); 121082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true, 12117765934ad7e157b5fcf925792a38e01b1edbcf8aDaniel Dunbar linktype, C, Out.str()); 1212f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateBitCast(vtable, Ptr8Ty); 1213f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateGEP(vtable, 1214276b9f1d814f4f6551cc3000590759a34185d6daMike Stump llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 1215263b3522add846130ff5f0a85568234e612a81caMike Stump Offset*LLVMPointerWidth/8)); 1216f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump return vtable; 1217f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump} 1218f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 1219f0070dbae9535836ad41711081465dec2259786bMike Stump// FIXME: move to Context 1220f0070dbae9535836ad41711081465dec2259786bMike Stumpstatic VtableInfo *vtableinfo; 1221f0070dbae9535836ad41711081465dec2259786bMike Stump 1222ed032eb5c18b99528cbd76415337b6056a72b911Mike Stumpllvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn, 1223ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump const CXXMethodDecl *MD, 122477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump bool Extern, int64_t nv, 122577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump int64_t v) { 1226ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump QualType R = MD->getType()->getAsFunctionType()->getResultType(); 1227ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump 1228ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump FunctionArgList Args; 1229ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump ImplicitParamDecl *ThisDecl = 1230ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, 1231ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump MD->getThisType(getContext())); 1232ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump Args.push_back(std::make_pair(ThisDecl, ThisDecl->getType())); 1233ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump for (FunctionDecl::param_const_iterator i = MD->param_begin(), 1234ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump e = MD->param_end(); 1235ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump i != e; ++i) { 1236ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump ParmVarDecl *D = *i; 1237ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump Args.push_back(std::make_pair(D, D->getType())); 1238ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump } 1239ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump IdentifierInfo *II 1240ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump = &CGM.getContext().Idents.get("__thunk_named_foo_"); 1241ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump FunctionDecl *FD = FunctionDecl::Create(getContext(), 1242ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump getContext().getTranslationUnitDecl(), 1243ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump SourceLocation(), II, R, 0, 1244ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump Extern 1245ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump ? FunctionDecl::Extern 1246ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump : FunctionDecl::Static, 1247ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump false, true); 1248ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump StartFunction(FD, R, Fn, Args, SourceLocation()); 1249ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump // FIXME: generate body 1250ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump FinishFunction(); 1251ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump return Fn; 1252ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump} 1253ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump 125477ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stumpllvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern, 125577ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump int64_t nv, int64_t v) { 1256ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::SmallString<256> OutName; 1257ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::raw_svector_ostream Out(OutName); 125877ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump mangleThunk(MD, nv, v, getContext(), Out); 1259ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::GlobalVariable::LinkageTypes linktype; 1260ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump linktype = llvm::GlobalValue::WeakAnyLinkage; 1261ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump if (!Extern) 1262ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump linktype = llvm::GlobalValue::InternalLinkage; 1263ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); 1264ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1265ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump const llvm::FunctionType *FTy = 1266ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), 1267ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump FPT->isVariadic()); 1268ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump 1269ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(), 1270ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump &getModule()); 127177ca8f6c5e666ef873066b580bf1b7fabd41d4f5Mike Stump CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v); 1272ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump // Fn = Builder.CreateBitCast(Fn, Ptr8Ty); 1273ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty); 1274ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump return m; 1275ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump} 1276ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump 1277f0070dbae9535836ad41711081465dec2259786bMike Stumpllvm::Value * 1278f0070dbae9535836ad41711081465dec2259786bMike StumpCodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *&This, 1279f0070dbae9535836ad41711081465dec2259786bMike Stump const llvm::Type *Ty) { 1280f0070dbae9535836ad41711081465dec2259786bMike Stump // FIXME: If we know the dynamic type, we don't have to do a virtual dispatch. 1281f0070dbae9535836ad41711081465dec2259786bMike Stump 1282f0070dbae9535836ad41711081465dec2259786bMike Stump // FIXME: move to Context 1283f0070dbae9535836ad41711081465dec2259786bMike Stump if (vtableinfo == 0) 1284f0070dbae9535836ad41711081465dec2259786bMike Stump vtableinfo = new VtableInfo(CGM); 1285f0070dbae9535836ad41711081465dec2259786bMike Stump 1286f0070dbae9535836ad41711081465dec2259786bMike Stump VtableInfo::Index_t Idx = vtableinfo->lookup(MD); 1287f0070dbae9535836ad41711081465dec2259786bMike Stump 1288f0070dbae9535836ad41711081465dec2259786bMike Stump Ty = llvm::PointerType::get(Ty, 0); 1289f0070dbae9535836ad41711081465dec2259786bMike Stump Ty = llvm::PointerType::get(Ty, 0); 1290f0070dbae9535836ad41711081465dec2259786bMike Stump Ty = llvm::PointerType::get(Ty, 0); 1291f0070dbae9535836ad41711081465dec2259786bMike Stump llvm::Value *vtbl = Builder.CreateBitCast(This, Ty); 1292f0070dbae9535836ad41711081465dec2259786bMike Stump vtbl = Builder.CreateLoad(vtbl); 1293f0070dbae9535836ad41711081465dec2259786bMike Stump llvm::Value *vfn = Builder.CreateConstInBoundsGEP1_64(vtbl, 1294f0070dbae9535836ad41711081465dec2259786bMike Stump Idx, "vfn"); 1295f0070dbae9535836ad41711081465dec2259786bMike Stump vfn = Builder.CreateLoad(vfn); 1296f0070dbae9535836ad41711081465dec2259786bMike Stump return vfn; 1297f0070dbae9535836ad41711081465dec2259786bMike Stump} 1298f0070dbae9535836ad41711081465dec2259786bMike Stump 1299eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// EmitClassAggrMemberwiseCopy - This routine generates code to copy a class 1300eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// array of objects from SrcValue to DestValue. Copying can be either a bitwise 1301eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// copy or via a copy constructor call. 13024f68d537c3f072366b25f3137f052eee36fddfcdFariborz Jahanian// FIXME. Consolidate this with EmitCXXAggrConstructorCall. 1303eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanianvoid CodeGenFunction::EmitClassAggrMemberwiseCopy(llvm::Value *Dest, 1304eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *Src, 1305eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian const ArrayType *Array, 1306eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian const CXXRecordDecl *BaseClassDecl, 1307eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian QualType Ty) { 1308eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 1309eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian assert(CA && "VLA cannot be copied over"); 1310eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian bool BitwiseCopy = BaseClassDecl->hasTrivialCopyConstructor(); 1311eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1312eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Create a temporary for the loop index and initialize it with 0. 1313eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 1314eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian "loop.index"); 1315eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value* zeroConstant = 1316eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 1317eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Builder.CreateStore(zeroConstant, IndexPtr, false); 1318eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Start the loop with a block that tests the condition. 1319eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 1320eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 1321eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1322eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitBlock(CondBlock); 1323eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1324eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 1325eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Generate: if (loop-index < number-of-elements fall to the loop body, 1326eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // otherwise, go to the block after the for-loop. 1327eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 1328eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value * NumElementsPtr = 1329eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 1330eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 1331eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 1332eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian "isless"); 1333eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // If the condition is true, execute the body. 1334eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Builder.CreateCondBr(IsLess, ForBody, AfterFor); 1335eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1336eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitBlock(ForBody); 1337eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 1338eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Inside the loop body, emit the constructor call on the array element. 1339eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 1340eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 1341eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 1342eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian if (BitwiseCopy) 1343eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitAggregateCopy(Dest, Src, Ty); 1344eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian else if (CXXConstructorDecl *BaseCopyCtor = 1345eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian BaseClassDecl->getCopyConstructor(getContext(), 0)) { 1346eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, 1347eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Ctor_Complete); 1348eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian CallArgList CallArgs; 1349eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Push the this (Dest) ptr. 1350eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Dest), 1351eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian BaseCopyCtor->getThisType(getContext()))); 1352eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1353eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Push the Src ptr. 1354eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Src), 1355eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian BaseCopyCtor->getParamDecl(0)->getType())); 1356eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian QualType ResultType = 1357eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian BaseCopyCtor->getType()->getAsFunctionType()->getResultType(); 1358eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1359eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Callee, CallArgs, BaseCopyCtor); 1360eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian } 1361eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitBlock(ContinueBlock); 1362eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1363eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Emit the increment of the loop counter. 1364eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 1365eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 1366eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 1367eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Builder.CreateStore(NextVal, IndexPtr, false); 1368eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1369eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Finally, branch back up to the condition for the next iteration. 1370eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitBranch(CondBlock); 1371eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1372eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian // Emit the fall-through block. 1373eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitBlock(AfterFor, true); 1374eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian} 1375eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 1376c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// EmitClassAggrCopyAssignment - This routine generates code to assign a class 1377c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// array of objects from SrcValue to DestValue. Assignment can be either a 1378c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// bitwise assignment or via a copy assignment operator function call. 1379c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian/// FIXME. This can be consolidated with EmitClassAggrMemberwiseCopy 1380c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanianvoid CodeGenFunction::EmitClassAggrCopyAssignment(llvm::Value *Dest, 1381c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *Src, 1382c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const ArrayType *Array, 1383c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const CXXRecordDecl *BaseClassDecl, 1384c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian QualType Ty) { 1385c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array); 1386c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian assert(CA && "VLA cannot be asssigned"); 1387c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian bool BitwiseAssign = BaseClassDecl->hasTrivialCopyAssignment(); 1388c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1389c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Create a temporary for the loop index and initialize it with 0. 1390c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext), 1391c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian "loop.index"); 1392c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value* zeroConstant = 1393c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)); 1394c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Builder.CreateStore(zeroConstant, IndexPtr, false); 1395c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Start the loop with a block that tests the condition. 1396c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 1397c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 1398c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1399c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitBlock(CondBlock); 1400c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1401c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 1402c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Generate: if (loop-index < number-of-elements fall to the loop body, 1403c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // otherwise, go to the block after the for-loop. 1404c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian uint64_t NumElements = getContext().getConstantArrayElementCount(CA); 1405c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value * NumElementsPtr = 1406c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), NumElements); 1407c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *Counter = Builder.CreateLoad(IndexPtr); 1408c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *IsLess = Builder.CreateICmpULT(Counter, NumElementsPtr, 1409c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian "isless"); 1410c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // If the condition is true, execute the body. 1411c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Builder.CreateCondBr(IsLess, ForBody, AfterFor); 1412c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1413c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitBlock(ForBody); 1414c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::BasicBlock *ContinueBlock = createBasicBlock("for.inc"); 1415c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Inside the loop body, emit the assignment operator call on array element. 1416c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 1417c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Src = Builder.CreateInBoundsGEP(Src, Counter, "srcaddress"); 1418c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Dest = Builder.CreateInBoundsGEP(Dest, Counter, "destaddress"); 1419c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const CXXMethodDecl *MD = 0; 1420c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian if (BitwiseAssign) 1421c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitAggregateCopy(Dest, Src, Ty); 1422c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian else { 1423c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian bool hasCopyAssign = BaseClassDecl->hasConstCopyAssignment(getContext(), 1424c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian MD); 1425c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian assert(hasCopyAssign && "EmitClassAggrCopyAssignment - No user assign"); 1426c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian (void)hasCopyAssign; 1427c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1428c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const llvm::Type *LTy = 1429c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 1430c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian FPT->isVariadic()); 1431c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy); 1432c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1433c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian CallArgList CallArgs; 1434c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Push the this (Dest) ptr. 1435c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Dest), 1436c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian MD->getThisType(getContext()))); 1437c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1438c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Push the Src ptr. 1439c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Src), 1440c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian MD->getParamDecl(0)->getType())); 1441ed032eb5c18b99528cbd76415337b6056a72b911Mike Stump QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); 1442c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1443c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Callee, CallArgs, MD); 1444c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian } 1445c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitBlock(ContinueBlock); 1446c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1447c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Emit the increment of the loop counter. 1448c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1); 1449c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Counter = Builder.CreateLoad(IndexPtr); 1450c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian NextVal = Builder.CreateAdd(Counter, NextVal, "inc"); 1451c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Builder.CreateStore(NextVal, IndexPtr, false); 1452c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1453c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Finally, branch back up to the condition for the next iteration. 1454c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitBranch(CondBlock); 1455c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1456c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian // Emit the fall-through block. 1457c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitBlock(AfterFor, true); 1458c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian} 1459c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 1460ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// EmitClassMemberwiseCopy - This routine generates code to copy a class 1461ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian/// object from SrcValue to DestValue. Copying can be either a bitwise copy 1462eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian/// or via a copy constructor call. 1463ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanianvoid CodeGenFunction::EmitClassMemberwiseCopy( 1464942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian llvm::Value *Dest, llvm::Value *Src, 1465ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian const CXXRecordDecl *ClassDecl, 1466942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian const CXXRecordDecl *BaseClassDecl, QualType Ty) { 1467942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian if (ClassDecl) { 1468942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl); 1469942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ; 1470942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian } 1471942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian if (BaseClassDecl->hasTrivialCopyConstructor()) { 1472942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian EmitAggregateCopy(Dest, Src, Ty); 1473ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian return; 1474942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian } 1475942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian 1476ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian if (CXXConstructorDecl *BaseCopyCtor = 147780e4b9e0e87064a824d72b6ff89074206ecced58Fariborz Jahanian BaseClassDecl->getCopyConstructor(getContext(), 0)) { 1478ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, 1479ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian Ctor_Complete); 1480ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian CallArgList CallArgs; 1481ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian // Push the this (Dest) ptr. 1482ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Dest), 1483ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian BaseCopyCtor->getThisType(getContext()))); 1484ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian 1485ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian // Push the Src ptr. 1486ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Src), 1487370c884d172329384973e452647fba0b2f5146d5Fariborz Jahanian BaseCopyCtor->getParamDecl(0)->getType())); 1488ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian QualType ResultType = 1489ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian BaseCopyCtor->getType()->getAsFunctionType()->getResultType(); 1490ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1491ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian Callee, CallArgs, BaseCopyCtor); 1492ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian } 1493ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian} 149406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian 14950270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// EmitClassCopyAssignment - This routine generates code to copy assign a class 14960270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// object from SrcValue to DestValue. Assignment can be either a bitwise 14970270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// assignment of via an assignment operator call. 1498c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian// FIXME. Consolidate this with EmitClassMemberwiseCopy as they share a lot. 14990270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanianvoid CodeGenFunction::EmitClassCopyAssignment( 15000270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian llvm::Value *Dest, llvm::Value *Src, 15010270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const CXXRecordDecl *ClassDecl, 15020270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const CXXRecordDecl *BaseClassDecl, 15030270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian QualType Ty) { 15040270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian if (ClassDecl) { 15050270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl); 15060270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ; 15070270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian } 15080270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian if (BaseClassDecl->hasTrivialCopyAssignment()) { 15090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian EmitAggregateCopy(Dest, Src, Ty); 15100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian return; 15110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian } 15120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 15130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const CXXMethodDecl *MD = 0; 1514e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian bool ConstCopyAssignOp = BaseClassDecl->hasConstCopyAssignment(getContext(), 1515e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian MD); 1516e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian assert(ConstCopyAssignOp && "EmitClassCopyAssignment - missing copy assign"); 1517e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian (void)ConstCopyAssignOp; 1518e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian 1519e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1520e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian const llvm::Type *LTy = 1521e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 1522e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian FPT->isVariadic()); 1523e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), LTy); 15240270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 1525e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian CallArgList CallArgs; 1526e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian // Push the this (Dest) ptr. 1527e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Dest), 1528e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian MD->getThisType(getContext()))); 15290270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 1530e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian // Push the Src ptr. 1531e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian CallArgs.push_back(std::make_pair(RValue::get(Src), 1532e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian MD->getParamDecl(0)->getType())); 1533e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian QualType ResultType = 1534e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian MD->getType()->getAsFunctionType()->getResultType(); 1535e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1536e82c3e269f0edd6d531b93114e97573792e808e0Fariborz Jahanian Callee, CallArgs, MD); 15370270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian} 15380270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 153906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian/// SynthesizeDefaultConstructor - synthesize a default constructor 154006f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanianvoid 154106f598aa45b651f9f3be0b916d43876eae747af0Fariborz JahanianCodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *CD, 154206f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian const FunctionDecl *FD, 154306f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian llvm::Function *Fn, 154406f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian const FunctionArgList &Args) { 154506f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation()); 154606f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian EmitCtorPrologue(CD); 154706f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian FinishFunction(); 154806f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian} 154906f598aa45b651f9f3be0b916d43876eae747af0Fariborz Jahanian 15508c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian/// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a copy 155197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// constructor, in accordance with section 12.8 (p7 and p8) of C++03 155297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// The implicitly-defined copy constructor for class X performs a memberwise 155397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// copy of its subobjects. The order of copying is the same as the order 155497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// of initialization of bases and members in a user-defined constructor 155597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Each subobject is copied in the manner appropriate to its type: 155697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// if the subobject is of class type, the copy constructor for the class is 155797a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// used; 155897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// if the subobject is an array, each element is copied, in the manner 155997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// appropriate to the element type; 156097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// if the subobject is of scalar type, the built-in assignment operator is 156197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// used. 156297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// Virtual base class subobjects shall be copied only once by the 156397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian/// implicitly-defined copy constructor 156497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian 15658c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD, 15668c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian const FunctionDecl *FD, 15678c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian llvm::Function *Fn, 1568ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian const FunctionArgList &Args) { 156997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 157097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian assert(!ClassDecl->hasUserDeclaredCopyConstructor() && 15718c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian "SynthesizeCXXCopyConstructor - copy constructor has definition already"); 15728c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation()); 157397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian 15741e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian FunctionArgList::const_iterator i = Args.begin(); 15751e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian const VarDecl *ThisArg = i->first; 15761e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 15771e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 15781e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian const VarDecl *SrcArg = (i+1)->first; 15791e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 15801e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 15811e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian 158297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 158397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian Base != ClassDecl->bases_end(); ++Base) { 158497a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian // FIXME. copy constrution of virtual base NYI 158597a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian if (Base->isVirtual()) 158697a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian continue; 1587ca28361fb0a72c50e0a400fae2fad9520e61c0a5Fariborz Jahanian 158897a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian CXXRecordDecl *BaseClassDecl 158997a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1590942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 1591942f4f33d02dba823594bd2d7b3d317cb01c74f8Fariborz Jahanian Base->getType()); 159297a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian } 159397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian 15941e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 15951e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian FieldEnd = ClassDecl->field_end(); 15961e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian Field != FieldEnd; ++Field) { 15971e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 1598eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian const ConstantArrayType *Array = 1599eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian getContext().getAsConstantArrayType(FieldType); 1600eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian if (Array) 1601eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 1602eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 16031e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 16041e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian CXXRecordDecl *FieldClassDecl 16051e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian = cast<CXXRecordDecl>(FieldClassType->getDecl()); 16061e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); 16071e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0); 1608eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian if (Array) { 1609eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 1610eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 1611eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *DestBaseAddrPtr = 1612eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 1613eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian llvm::Value *SrcBaseAddrPtr = 1614eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian Builder.CreateBitCast(RHS.getAddress(), BasePtr); 1615eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitClassAggrMemberwiseCopy(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 1616eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian FieldClassDecl, FieldType); 1617eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian } 1618eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian else 1619eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(), 1620eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian 0 /*ClassDecl*/, FieldClassDecl, FieldType); 16211e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian continue; 16221e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian } 1623f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian // Do a built-in assignment of scalar data members. 1624f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); 1625f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0); 1626f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian RValue RVRHS = EmitLoadOfLValue(RHS, FieldType); 1627f05fe65e64a5de93ba6d30e1b830fd0fc36358e9Fariborz Jahanian EmitStoreThroughLValue(RVRHS, LHS, FieldType); 16281e4edd5474f8cb966356afa6175d658002ff819cFariborz Jahanian } 16298c241a2844428eb1589c7b77fc6c1888295a2045Fariborz Jahanian FinishFunction(); 163097a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian} 163197a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian 16322198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator. 16332198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// Before the implicitly-declared copy assignment operator for a class is 16342198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined, all implicitly- declared copy assignment operators for 16352198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// its direct base classes and its nonstatic data members shall have been 16362198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// implicitly defined. [12.8-p12] 16372198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// The implicitly-defined copy assignment operator for class X performs 16382198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// memberwise assignment of its subob- jects. The direct base classes of X are 16392198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// assigned first, in the order of their declaration in 16402198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// the base-specifier-list, and then the immediate nonstatic data members of X 16412198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// are assigned, in the order in which they were declared in the class 16422198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// definition.Each subobject is assigned in the manner appropriate to its type: 16430270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// if the subobject is of class type, the copy assignment operator for the 16440270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// class is used (as if by explicit qualification; that is, ignoring any 16452198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// possible virtual overriding functions in more derived classes); 16460270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// 16470270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// if the subobject is an array, each element is assigned, in the manner 16482198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// appropriate to the element type; 16490270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// 16500270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian/// if the subobject is of scalar type, the built-in assignment operator is 16512198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian/// used. 16522198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanianvoid CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD, 16532198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian const FunctionDecl *FD, 16542198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian llvm::Function *Fn, 16552198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian const FunctionArgList &Args) { 16560270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 16570270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 16580270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian assert(!ClassDecl->hasUserDeclaredCopyAssignment() && 16590270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian "SynthesizeCXXCopyAssignment - copy assignment has user declaration"); 16602198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation()); 16612198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian 16620270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian FunctionArgList::const_iterator i = Args.begin(); 16630270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const VarDecl *ThisArg = i->first; 16640270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); 16650270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); 16660270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian const VarDecl *SrcArg = (i+1)->first; 16670270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); 16680270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); 16690270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 16700270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 16710270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian Base != ClassDecl->bases_end(); ++Base) { 16720270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian // FIXME. copy assignment of virtual base NYI 16730270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian if (Base->isVirtual()) 16740270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian continue; 16750270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 16760270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian CXXRecordDecl *BaseClassDecl 16770270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 16780270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian EmitClassCopyAssignment(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, 16790270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian Base->getType()); 16800270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian } 16810270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 16820270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 16830270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian FieldEnd = ClassDecl->field_end(); 16840270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian Field != FieldEnd; ++Field) { 16850270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 1686c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const ConstantArrayType *Array = 1687c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian getContext().getAsConstantArrayType(FieldType); 1688c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian if (Array) 1689c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 16900270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 16910270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { 16920270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian CXXRecordDecl *FieldClassDecl 16930270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian = cast<CXXRecordDecl>(FieldClassType->getDecl()); 16940270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); 16950270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0); 1696c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian if (Array) { 1697c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 1698c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 1699c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *DestBaseAddrPtr = 1700c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 1701c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian llvm::Value *SrcBaseAddrPtr = 1702c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian Builder.CreateBitCast(RHS.getAddress(), BasePtr); 1703c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitClassAggrCopyAssignment(DestBaseAddrPtr, SrcBaseAddrPtr, Array, 1704c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian FieldClassDecl, FieldType); 1705c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian } 1706c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian else 1707c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian EmitClassCopyAssignment(LHS.getAddress(), RHS.getAddress(), 1708c28bbc2d2271aab6c5d79ef2758604221cd92a4bFariborz Jahanian 0 /*ClassDecl*/, FieldClassDecl, FieldType); 17090270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian continue; 17100270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian } 17110270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian // Do a built-in assignment of scalar data members. 17120270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); 17130270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0); 17140270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian RValue RVRHS = EmitLoadOfLValue(RHS, FieldType); 17150270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian EmitStoreThroughLValue(RVRHS, LHS, FieldType); 1716183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian } 1717183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian 1718183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian // return *this; 1719183d7181fd59842ac969cbc6fe0376f85dc63ae4Fariborz Jahanian Builder.CreateStore(LoadOfThis, ReturnValue); 17200270b8aa3f9b50ec3acd1abfd2b97377a3e1bb05Fariborz Jahanian 17212198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian FinishFunction(); 17222198ba12b73a8e6801d13f25de38031da6df46b6Fariborz Jahanian} 172397a937532c24a8ea44317d4fdee26d9701a1e83cFariborz Jahanian 1724e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize 1725e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor. 1726174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXCtorType. 1727e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { 1728742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 1729eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump // FIXME: Add vbase initialization 1730f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *LoadOfThis = 0; 17316d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian 1732742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 1733e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian E = CD->init_end(); 1734e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian B != E; ++B) { 1735e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian CXXBaseOrMemberInitializer *Member = (*B); 1736e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian if (Member->isBaseInitializer()) { 1737f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 17386d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian Type *BaseType = Member->getBaseClass(); 17396d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian CXXRecordDecl *BaseClassDecl = 17406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 17416d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 17426d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian BaseClassDecl); 1743742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 1744742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Ctor_Complete, V, 1745742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_begin(), 1746742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_end()); 1747b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 1748e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian // non-static data member initilaizers. 1749e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian FieldDecl *Field = Member->getMember(); 1750e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian QualType FieldType = getContext().getCanonicalType((Field)->getType()); 175164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian const ConstantArrayType *Array = 1752eb0b6d556ff2b4a5053e89fd084eb34e44cea14cFariborz Jahanian getContext().getAsConstantArrayType(FieldType); 175364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian if (Array) 175464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 17558c64e007d9b2f719613f7d79b0b32d2f50da9332Fariborz Jahanian 1756f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 1757e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman LValue LHS; 1758e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman if (FieldType->isReferenceType()) { 1759e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman // FIXME: This is really ugly; should be refactored somehow 1760e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); 1761e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman llvm::Value *V = Builder.CreateStructGEP(LoadOfThis, idx, "tmp"); 1762e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman LHS = LValue::MakeAddr(V, FieldType.getCVRQualifiers(), 1763e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman QualType::GCNone, FieldType.getAddressSpace()); 1764e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman } else { 1765e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman LHS = EmitLValueForField(LoadOfThis, Field, false, 0); 1766e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman } 17676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (FieldType->getAs<RecordType>()) { 1768e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian if (!Field->isAnonymousStructOrUnion()) { 176950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian assert(Member->getConstructor() && 177050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian "EmitCtorPrologue - no constructor to initialize member"); 177164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian if (Array) { 177264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 177364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 177464a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian llvm::Value *BaseAddrPtr = 177564a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 177664a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian EmitCXXAggrConstructorCall(Member->getConstructor(), 177764a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian Array, BaseAddrPtr); 177864a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian } 177964a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian else 178064a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 178164a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian Ctor_Complete, LHS.getAddress(), 178264a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian Member->const_arg_begin(), 178364a54ad29929443006d4c8502173c163bedaa223Fariborz Jahanian Member->const_arg_end()); 1784e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian continue; 1785e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian } 1786e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian else { 1787e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian // Initializing an anonymous union data member. 1788e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian FieldDecl *anonMember = Member->getAnonUnionMember(); 1789c186b8fe4a308b53569fe839a3224de70d92ab0eAnders Carlsson LHS = EmitLValueForField(LHS.getAddress(), anonMember, 1790c186b8fe4a308b53569fe839a3224de70d92ab0eAnders Carlsson /*IsUnion=*/true, 0); 1791e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian FieldType = anonMember->getType(); 1792e64941280877d065a27e8cefd2a9038256d0e3acFariborz Jahanian } 179350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian } 1794e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 1795e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only"); 179650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Expr *RhsExpr = *Member->arg_begin(); 1797e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman RValue RHS; 1798e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman if (FieldType->isReferenceType()) 1799e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman RHS = EmitReferenceBindingToExpr(RhsExpr, FieldType, 1800e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman /*IsInitializer=*/true); 1801e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman else 1802e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman RHS = RValue::get(EmitScalarExpr(RhsExpr, true)); 1803e3a97db45ac46adf963115d0266cfd3e6bc2dce8Eli Friedman EmitStoreThroughLValue(RHS, LHS, FieldType); 1804e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 1805e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 1806f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 18070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) { 18081d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian // Nontrivial default constructor with no initializer list. It may still 18090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // have bases classes and/or contain non-static data members which require 18100880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // construction. 18110880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator Base = 18120880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian ClassDecl->bases_begin(); 18130880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian Base != ClassDecl->bases_end(); ++Base) { 18140880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // FIXME. copy assignment of virtual base NYI 18150880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (Base->isVirtual()) 18160880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 18170880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 18180880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *BaseClassDecl 18190880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 18200880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (BaseClassDecl->hasTrivialConstructor()) 18210880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 18220880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (CXXConstructorDecl *BaseCX = 18230880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian BaseClassDecl->getDefaultConstructor(getContext())) { 18240880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian LoadOfThis = LoadCXXThis(); 18250880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 18260880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian BaseClassDecl); 18270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0); 18280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 18290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 18300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 18311d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 18321d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian FieldEnd = ClassDecl->field_end(); 18331d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian Field != FieldEnd; ++Field) { 18341d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 1835288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian const ConstantArrayType *Array = 1836288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian getContext().getAsConstantArrayType(FieldType); 1837f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (Array) 1838f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 18391d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian if (!FieldType->getAs<RecordType>() || Field->isAnonymousStructOrUnion()) 18401d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian continue; 18411d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian const RecordType *ClassRec = FieldType->getAs<RecordType>(); 18420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *MemberClassDecl = 18430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian dyn_cast<CXXRecordDecl>(ClassRec->getDecl()); 18440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (!MemberClassDecl || MemberClassDecl->hasTrivialConstructor()) 18450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 18460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (CXXConstructorDecl *MamberCX = 18470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian MemberClassDecl->getDefaultConstructor(getContext())) { 18480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian LoadOfThis = LoadCXXThis(); 18490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); 1850288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian if (Array) { 1851288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 1852288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 1853288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian llvm::Value *BaseAddrPtr = 1854288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 1855288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr); 1856288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian } 1857288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian else 1858288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian EmitCXXConstructorCall(MamberCX, Ctor_Complete, LHS.getAddress(), 1859288dcaf329c49b01dacd5c1dd9f35609555feecdFariborz Jahanian 0, 0); 18601d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian } 18611d9b5efffaec2349f33510dee2cf2e90c3d2d6aaFariborz Jahanian } 18620880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 18630880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 1864f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // Initialize the vtable pointer 1865b502d839994cc3828573bd9ea472418e3536f415Mike Stump if (ClassDecl->isDynamicClass()) { 1866f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (!LoadOfThis) 1867f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 1868f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *VtableField; 1869f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Type *Ptr8Ty, *PtrPtr8Ty; 18700032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 1871f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0); 1872f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty); 1873f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *vtable = GenerateVtable(ClassDecl); 1874f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Builder.CreateStore(vtable, VtableField); 1875f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump } 1876e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian} 1877426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 1878426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's 1879426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes 1880426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction. 1881174754cda4596f3bb2539df61ab2ab7a17aad6bfAnders Carlsson/// FIXME: This needs to take a CXXDtorType. 1882426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { 1883426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext()); 1884de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson assert(!ClassDecl->getNumVBases() && 1885de738fe899b5c1d387dbc66a1122032e694d3d6fAnders Carlsson "FIXME: Destruction of virtual bases not supported"); 1886426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian (void)ClassDecl; // prevent warning. 1887426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 1888426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(), 1889426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian *E = DD->destr_end(); B != E; ++B) { 1890426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian uintptr_t BaseOrMember = (*B); 1891426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (DD->isMemberToDestroy(BaseOrMember)) { 1892426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember); 1893426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian QualType FieldType = getContext().getCanonicalType((FD)->getType()); 1894f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian const ConstantArrayType *Array = 1895f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian getContext().getAsConstantArrayType(FieldType); 1896f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (Array) 1897f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 1898426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = FieldType->getAs<RecordType>(); 1899426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1900426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (FieldClassDecl->hasTrivialDestructor()) 1901426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 1902426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *LoadOfThis = LoadCXXThis(); 1903426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0); 1904f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (Array) { 1905f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 1906f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 1907f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian llvm::Value *BaseAddrPtr = 1908f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 1909f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 1910f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Array, BaseAddrPtr); 1911f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian } 1912f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian else 1913f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 1914f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Dtor_Complete, LHS.getAddress()); 1915b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 1916426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = 1917426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>(); 1918426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 1919426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (BaseClassDecl->hasTrivialDestructor()) 1920426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 1921426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 1922426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian ClassDecl,BaseClassDecl); 1923426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), 1924426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian Dtor_Complete, V); 1925426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 1926426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 19270880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (DD->getNumBaseOrMemberDestructions() || DD->isTrivial()) 19280880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian return; 19290880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // Case of destructor synthesis with fields and base classes 19300880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // which have non-trivial destructors. They must be destructed in 19310880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // reverse order of their construction. 19320880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::SmallVector<FieldDecl *, 16> DestructedFields; 19330880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 19340880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 19350880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian FieldEnd = ClassDecl->field_end(); 19360880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian Field != FieldEnd; ++Field) { 19370880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian QualType FieldType = getContext().getCanonicalType((*Field)->getType()); 1938f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (getContext().getAsConstantArrayType(FieldType)) 1939f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 19400880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (const RecordType *RT = FieldType->getAs<RecordType>()) { 19410880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 19420880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (FieldClassDecl->hasTrivialDestructor()) 19430880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 19440880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian DestructedFields.push_back(*Field); 19450880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 19460880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 19470880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (!DestructedFields.empty()) 19480880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian for (int i = DestructedFields.size() -1; i >= 0; --i) { 19490880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian FieldDecl *Field = DestructedFields[i]; 19500880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian QualType FieldType = Field->getType(); 1951f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian const ConstantArrayType *Array = 1952f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian getContext().getAsConstantArrayType(FieldType); 1953f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (Array) 1954f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian FieldType = getContext().getBaseElementType(FieldType); 19550880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian const RecordType *RT = FieldType->getAs<RecordType>(); 19560880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 19570880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::Value *LoadOfThis = LoadCXXThis(); 19580880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); 1959f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian if (Array) { 1960f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian const llvm::Type *BasePtr = ConvertType(FieldType); 1961f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian BasePtr = llvm::PointerType::getUnqual(BasePtr); 1962f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian llvm::Value *BaseAddrPtr = 1963f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Builder.CreateBitCast(LHS.getAddress(), BasePtr); 1964f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()), 1965f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Array, BaseAddrPtr); 1966f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian } 1967f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian else 1968f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 1969f800f6c09ed4a71bcb593d6962e0fda2c2845a70Fariborz Jahanian Dtor_Complete, LHS.getAddress()); 19700880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 19710880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 19720880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::SmallVector<CXXRecordDecl*, 4> DestructedBases; 19730880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); 19740880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian Base != ClassDecl->bases_end(); ++Base) { 19750880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian // FIXME. copy assignment of virtual base NYI 19760880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (Base->isVirtual()) 19770880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 19780880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 19790880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *BaseClassDecl 19800880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 19810880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (BaseClassDecl->hasTrivialDestructor()) 19820880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian continue; 19830880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian DestructedBases.push_back(BaseClassDecl); 19840880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 19850880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian if (DestructedBases.empty()) 19860880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian return; 19870880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian for (int i = DestructedBases.size() -1; i >= 0; --i) { 19880880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian CXXRecordDecl *BaseClassDecl = DestructedBases[i]; 19890880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 19900880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian ClassDecl,BaseClassDecl); 19910880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), 19920880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian Dtor_Complete, V); 19930880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian } 1994426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian} 19950880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 19960880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanianvoid CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *CD, 19970880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian const FunctionDecl *FD, 19980880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian llvm::Function *Fn, 19990880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian const FunctionArgList &Args) { 20000880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 20010880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 20020880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian assert(!ClassDecl->hasUserDeclaredDestructor() && 20030880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian "SynthesizeDefaultDestructor - destructor has user declaration"); 20040880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian (void) ClassDecl; 20050880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian 20060880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation()); 20070880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian EmitDtorEpilogue(CD); 20080880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian FinishFunction(); 20090880bacf8fdb7de9d9c5b53b81ea0e53afccafb5Fariborz Jahanian} 2010