CGCXX.cpp revision f121677b6bbbf4e4a51ee7a1120b77adf187bad4
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 290096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel DunbarCodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, 300096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar llvm::GlobalVariable *GV) { 310096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar // FIXME: This should use __cxa_guard_{acquire,release}? 320096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar 33e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson assert(!getContext().getLangOptions().ThreadsafeStatics && 34e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson "thread safe statics are currently not supported!"); 35e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 36283a062a633d6e868aa2be319da812341fe73728Anders Carlsson llvm::SmallString<256> GuardVName; 37283a062a633d6e868aa2be319da812341fe73728Anders Carlsson llvm::raw_svector_ostream GuardVOut(GuardVName); 38283a062a633d6e868aa2be319da812341fe73728Anders Carlsson mangleGuardVariable(&D, getContext(), GuardVOut); 39283a062a633d6e868aa2be319da812341fe73728Anders Carlsson 40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // Create the guard variable. 41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::GlobalValue *GuardV = 421c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson new llvm::GlobalVariable(CGM.getModule(), llvm::Type::Int64Ty, false, 430096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar GV->getLinkage(), 44a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson VMContext.getNullValue(llvm::Type::Int64Ty), 451c431b323d776362490bbf7cc796b74fedaf19f2Owen Anderson GuardVName.c_str()); 46e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 47e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // Load the first byte of the guard variable. 4896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 49e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy), 50e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson "tmp"); 51e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 52e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // Compare it against 0. 53a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson llvm::Value *nullValue = VMContext.getNullValue(llvm::Type::Int8Ty); 54e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool"); 55e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 5655e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *InitBlock = createBasicBlock("init"); 579615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 58e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 59e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // If the guard variable is 0, jump to the initializer code. 60e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson Builder.CreateCondBr(ICmp, InitBlock, EndBlock); 61e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 62e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson EmitBlock(InitBlock); 63e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 64e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson const Expr *Init = D.getInit(); 65e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson if (!hasAggregateLLVMType(Init->getType())) { 66e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::Value *V = EmitScalarExpr(Init); 67e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson Builder.CreateStore(V, GV, D.getType().isVolatileQualified()); 68e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson } else if (Init->getType()->isAnyComplexType()) { 69e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified()); 70e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson } else { 71e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson EmitAggExpr(Init, GV, D.getType().isVolatileQualified()); 72e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson } 73e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 744a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1), 75e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson Builder.CreateBitCast(GuardV, PtrTy)); 76e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 77e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson EmitBlock(EndBlock); 78e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson} 79e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 80b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, 81b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *Callee, 82b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *This, 83b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CallExpr::const_arg_iterator ArgBeg, 84b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CallExpr::const_arg_iterator ArgEnd) { 85774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson assert(MD->isInstance() && 86774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson "Trying to emit a member call expr on a static method!"); 87b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 88b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 89b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 90b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CallArgList Args; 91b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 92b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson // Push the this ptr. 93b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson Args.push_back(std::make_pair(RValue::get(This), 94b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson MD->getThisType(getContext()))); 95b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 96b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson // And the rest of the call args 97b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); 98774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 99b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); 100b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), 101b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson Callee, Args, MD); 102b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson} 103b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 104b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders CarlssonRValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { 105b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()); 106b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); 107b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 108e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1097116da1efe23f90eb22524ac9aa036153b74f482Mike Stump 110f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (MD->isVirtual()) { 1117116da1efe23f90eb22524ac9aa036153b74f482Mike Stump ErrorUnsupported(CE, "virtual dispatch"); 1127116da1efe23f90eb22524ac9aa036153b74f482Mike Stump } 1137116da1efe23f90eb22524ac9aa036153b74f482Mike Stump 114774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson const llvm::Type *Ty = 115e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 116e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson FPT->isVariadic()); 117b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 118774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 119b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *This; 120774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 121774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson if (ME->isArrow()) 122b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = EmitScalarExpr(ME->getBase()); 123774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson else { 124774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson LValue BaseLV = EmitLValue(ME->getBase()); 125b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = BaseLV.getAddress(); 126774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson } 127774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 128b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson return EmitCXXMemberCall(MD, Callee, This, 129b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CE->arg_begin(), CE->arg_end()); 130774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson} 1315f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 1320f294632f36459174199b77699e339715244b5abAnders CarlssonRValue 1330f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 1340f294632f36459174199b77699e339715244b5abAnders Carlsson const CXXMethodDecl *MD) { 1350f294632f36459174199b77699e339715244b5abAnders Carlsson assert(MD->isInstance() && 1360f294632f36459174199b77699e339715244b5abAnders Carlsson "Trying to emit a member call expr on a static method!"); 1370f294632f36459174199b77699e339715244b5abAnders Carlsson 1380f294632f36459174199b77699e339715244b5abAnders Carlsson 1390f294632f36459174199b77699e339715244b5abAnders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1400f294632f36459174199b77699e339715244b5abAnders Carlsson const llvm::Type *Ty = 1410f294632f36459174199b77699e339715244b5abAnders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 1420f294632f36459174199b77699e339715244b5abAnders Carlsson FPT->isVariadic()); 1430f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 1440f294632f36459174199b77699e339715244b5abAnders Carlsson 1450f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 1460f294632f36459174199b77699e339715244b5abAnders Carlsson 1470f294632f36459174199b77699e339715244b5abAnders Carlsson return EmitCXXMemberCall(MD, Callee, This, 1480f294632f36459174199b77699e339715244b5abAnders Carlsson E->arg_begin() + 1, E->arg_end()); 1490f294632f36459174199b77699e339715244b5abAnders Carlsson} 1500f294632f36459174199b77699e339715244b5abAnders Carlsson 1515f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() { 1525f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(isa<CXXMethodDecl>(CurFuncDecl) && 1535f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 1545f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && 1555f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 1565f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 1575f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson // FIXME: What if we're inside a block? 158f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ans: See how CodeGenFunction::LoadObjCSelf() uses 159f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // CodeGenFunction::BlockForwardSelf() for how to do this. 1605f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 1615f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson} 16295d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 163c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanianstatic bool 164c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz JahanianGetNestedPaths(llvm::SmallVectorImpl<const CXXRecordDecl *> &NestedBasePaths, 165c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *ClassDecl, 166c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *BaseClassDecl) { 167c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian assert(!ClassDecl->isPolymorphic() && 168c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian "FIXME: We don't support polymorphic classes yet!"); 169c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 170c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 171c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 172c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 173c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 174c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 175c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (Base == BaseClassDecl) { 176c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(BaseClassDecl); 177c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 178c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 179c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 180c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian // BaseClassDecl not an immediate base of ClassDecl. 181c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 182c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 183c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 184c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 185c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 186c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 187c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { 188c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(Base); 189c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 190c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 191c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 192c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return false; 193c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian} 194c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 1959e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, 1966d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *ClassDecl, 1976d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *BaseClassDecl) { 1989e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian if (ClassDecl == BaseClassDecl) 1999e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 2009e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 201c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 202c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; 203c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); 204c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian assert(NestedBasePaths.size() > 0 && 205c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian "AddressCXXOfBaseClass - inheritence path failed"); 206c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(ClassDecl); 207c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian uint64_t Offset = 0; 208c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 2099e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // Accessing a member of the base class. Must add delata to 2109e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // the load of 'this'. 211c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { 212c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; 213c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; 214c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const ASTRecordLayout &Layout = 215c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian getContext().getASTRecordLayout(DerivedClass); 216c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian Offset += Layout.getBaseClassOffset(BaseClass) / 8; 217c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 2185a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::Value *OffsetVal = 2195a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::ConstantInt::get( 2205a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); 2219e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr); 2229e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr"); 2239e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian QualType BTy = 2249e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian getContext().getCanonicalType( 2256d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 2269e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian const llvm::Type *BasePtr = ConvertType(BTy); 22796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson BasePtr = llvm::PointerType::getUnqual(BasePtr); 2289e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, BasePtr); 2299e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 2309e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian} 2319e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 232b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 233b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 234b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CXXCtorType Type, 235b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson llvm::Value *This, 236b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgBeg, 237b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgEnd) { 238b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 239b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 240b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 241b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 242b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 2437267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 2447267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson CXXDtorType Type, 2457267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *This) { 2467267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 2477267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 2487267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson EmitCXXMemberCall(D, Callee, This, 0, 0); 2497267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson} 2507267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 251b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 25231ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 25331ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson const CXXConstructExpr *E) { 254b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson assert(Dest && "Must have a destination!"); 255b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 256b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson const CXXRecordDecl *RD = 2576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); 258b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson if (RD->hasTrivialConstructor()) 259b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson return; 260b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 261b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson // Call the constructor. 262b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 263b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson E->arg_begin(), E->arg_end()); 264b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 265b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 266a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 267ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson if (E->isArray()) { 268ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ErrorUnsupported(E, "new[] expression"); 26903e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return llvm::UndefValue::get(ConvertType(E->getType())); 270ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 271ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 272ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType AllocType = E->getAllocatedType(); 273ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson FunctionDecl *NewFD = E->getOperatorNew(); 274ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 275ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 276ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CallArgList NewArgs; 277ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 278ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // The allocation size is the first argument. 279ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType SizeTy = getContext().getSizeType(); 280ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson llvm::Value *AllocSize = 2814a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ConvertType(SizeTy), 282ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getTypeSize(AllocType) / 8); 283ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 284ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 285ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 286ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the rest of the arguments. 287ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // FIXME: Ideally, this should just use EmitCallArgs. 288ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 289ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 290ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // First, use the types from the function type. 291ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // We start at 1 here because the first argument (the allocation size) 292ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // has already been emitted. 293ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 294ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewFTy->getArgType(i); 295ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 296ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 297ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getTypePtr() == 298ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 299ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "type mismatch in call argument!"); 300ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 301ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 302ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 303ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 304ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 305ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 306ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Either we've emitted all the call args, or we have a call to a 307ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // variadic function. 308ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 309ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "Extra arguments in non-variadic function!"); 310ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 311ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // If we still have any arguments, emit them using the type of the argument. 312ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 313ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArg != NewArgEnd; ++NewArg) { 314ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewArg->getType(); 315ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 316ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 317ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 318ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 319ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the call to new. 320ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson RValue RV = 321ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 322ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 323ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs, NewFD); 324ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 325d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // If an allocation function is declared with an empty exception specification 326d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // it returns null to indicate failure to allocate storage. [expr.new]p13. 327d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // (We don't need to check for null when there's no new initializer and 328d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // we're allocating a POD type). 329d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 330d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson !(AllocType->isPODType() && !E->hasInitializer()); 331ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 332f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNull = 0; 333f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNotNull = 0; 334f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewEnd = 0; 335f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 336f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *NewPtr = RV.getScalarVal(); 337f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 338d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson if (NullCheckResult) { 339f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNull = createBasicBlock("new.null"); 340f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNotNull = createBasicBlock("new.notnull"); 341f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewEnd = createBasicBlock("new.end"); 342f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 343f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *IsNull = 344f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateICmpEQ(NewPtr, 345a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson VMContext.getNullValue(NewPtr->getType()), 346f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson "isnull"); 347f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 348f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateCondBr(IsNull, NewNull, NewNotNull); 349f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNotNull); 350d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } 351d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 352f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); 353d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 3546d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson if (AllocType->isPODType()) { 355215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson if (E->getNumConstructorArgs() > 0) { 3566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson assert(E->getNumConstructorArgs() == 1 && 3576d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson "Can only have one argument to initializer of POD type."); 3586d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3596d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson const Expr *Init = E->getConstructorArg(0); 3606d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3613923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson if (!hasAggregateLLVMType(AllocType)) 3626d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 3633923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson else if (AllocType->isAnyComplexType()) 3643923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 365627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson else 366627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 3676d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson } 368d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } else { 369d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // Call the constructor. 370d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson CXXConstructorDecl *Ctor = E->getConstructor(); 3716d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 372d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 373d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_begin(), 374d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_end()); 375ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 376d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 377f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson if (NullCheckResult) { 378f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 379f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNull); 380f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 381f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewEnd); 382f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 383f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); 384f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->reserveOperandSpace(2); 385f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->addIncoming(NewPtr, NewNotNull); 386a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson PHI->addIncoming(VMContext.getNullValue(NewPtr->getType()), NewNull); 387f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 388f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = PHI; 389f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson } 390f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 391d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson return NewPtr; 392a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson} 393a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson 39427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD, 39527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ASTContext &Context) { 39659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // The class has base classes - we don't support that right now. 39759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (RD->getNumBases() > 0) 39859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 39959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 40017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 40117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis I != E; ++I) { 40259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // We don't support ctors for fields that aren't POD. 40359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (!I->getType()->isPODType()) 40459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 40559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 40659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 40759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return true; 40859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson} 40959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 41095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 41127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 41259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson ErrorUnsupported(D, "C++ constructor", true); 41359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return; 41459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 41595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 4162a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Complete)); 4172a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Base)); 41895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson} 419363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 42027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 42127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 42227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 42427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 42627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 42827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 42927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 43027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 431363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function * 432363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 433363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson CXXCtorType Type) { 434363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const llvm::FunctionType *FTy = 435363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 436363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 437363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const char *Name = getMangledCXXCtorName(D, Type); 438b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 439b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 440363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson} 44127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 44227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 44327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 44427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 44527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 44627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXCtor(D, Type, Context, Out); 44727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 44827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 44927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 45027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 45127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 45227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 45327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 45427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ErrorUnsupported(D, "C++ destructor", true); 45527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return; 45627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson } 45727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 45827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Complete); 45927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Base); 46027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 46127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 46327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 46427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 46527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 46727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 46927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 47027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 47127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 47227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function * 47327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 47427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 47527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const llvm::FunctionType *FTy = 47627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 47727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 47827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const char *Name = getMangledCXXDtorName(D, Type); 479b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 480b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 48127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 48227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 48327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 48427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 48527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 48627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 48727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXDtor(D, Type, Context, Out); 48827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 48927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 49027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 49127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 492e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 493f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { 494f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump const llvm::FunctionType *FTy; 495f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump FTy = llvm::FunctionType::get(llvm::Type::VoidTy, 496f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump std::vector<const llvm::Type*>(), false); 497f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 498f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::SmallString<256> OutName; 499f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::raw_svector_ostream Out(OutName); 500f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump QualType ClassTy; 501f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // FIXME: What is the design on getTagDeclType when it requires casting 502f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // away const? mutable? 503f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); 504f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump mangleCXXVtable(ClassTy, getContext(), Out); 505f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump const char *Name = OutName.c_str(); 506f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *vtable = CGM.CreateRuntimeFunction(FTy, Name); 507f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::SmallVector<CXXMethodDecl *,32> methods; 508f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump typedef CXXRecordDecl::method_iterator meth_iter; 509f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 510f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump ++mi) { 511f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (mi->isVirtual()) 512f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump methods.push_back(*mi); 513f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump } 514f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 515f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Type *Ptr8Ty; 516f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 517f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateBitCast(vtable, Ptr8Ty); 518f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // FIXME: finish layout for virtual bases and fix for 32-bit 519f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump int64_t offset = 16; 520f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateGEP(vtable, 521f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::ConstantInt::get(llvm::Type::Int64Ty, 522f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump offset)); 523f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump return vtable; 524f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump} 525f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 526e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize 527e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor. 528e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { 529742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 5307116da1efe23f90eb22524ac9aa036153b74f482Mike Stump assert(ClassDecl->getNumVBases() == 0 5317116da1efe23f90eb22524ac9aa036153b74f482Mike Stump && "FIXME: virtual base initialization unsupported"); 532f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *LoadOfThis = 0; 533f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 5346d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian 535742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 536e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian E = CD->init_end(); 537e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian B != E; ++B) { 538e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian CXXBaseOrMemberInitializer *Member = (*B); 539e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian if (Member->isBaseInitializer()) { 540f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 5416d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian Type *BaseType = Member->getBaseClass(); 5426d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian CXXRecordDecl *BaseClassDecl = 5436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 5446d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 5456d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian BaseClassDecl); 546742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 547742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Ctor_Complete, V, 548742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_begin(), 549742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_end()); 550b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 551e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian // non-static data member initilaizers. 552e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian FieldDecl *Field = Member->getMember(); 553e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian QualType FieldType = getContext().getCanonicalType((Field)->getType()); 554e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian assert(!getContext().getAsArrayType(FieldType) 555e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian && "FIXME. Field arrays initialization unsupported"); 55650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian 557f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 558e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); 5596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (FieldType->getAs<RecordType>()) { 56050b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian 56150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian assert(Member->getConstructor() && 56250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian "EmitCtorPrologue - no constructor to initialize member"); 56350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 56450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Ctor_Complete, LHS.getAddress(), 56550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Member->const_arg_begin(), 56650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Member->const_arg_end()); 56750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian continue; 56850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian } 569e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 570e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only"); 57150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Expr *RhsExpr = *Member->arg_begin(); 572e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian llvm::Value *RHS = EmitScalarExpr(RhsExpr, true); 573e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian if (LHS.isBitfield()) 574e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0); 575e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian else 576e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType); 577e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 578e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 579f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 580f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // Initialize the vtable pointer 581f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (ClassDecl->isPolymorphic() || ClassDecl->getNumVBases()) { 582f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (!LoadOfThis) 583f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 584f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *VtableField; 585f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Type *Ptr8Ty, *PtrPtr8Ty; 586f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 587f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0); 588f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty); 589f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *vtable = GenerateVtable(ClassDecl); 590f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Builder.CreateStore(vtable, VtableField); 591f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump } 592e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian} 593426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 594426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's 595426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes 596426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction. 597426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { 598426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext()); 599426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian assert(!ClassDecl->isPolymorphic() && 600426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian "FIXME. polymorphic destruction not supported"); 601426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian (void)ClassDecl; // prevent warning. 602426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 603426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(), 604426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian *E = DD->destr_end(); B != E; ++B) { 605426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian uintptr_t BaseOrMember = (*B); 606426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (DD->isMemberToDestroy(BaseOrMember)) { 607426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember); 608426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian QualType FieldType = getContext().getCanonicalType((FD)->getType()); 609426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian assert(!getContext().getAsArrayType(FieldType) 610426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian && "FIXME. Field arrays destruction unsupported"); 611426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = FieldType->getAs<RecordType>(); 612426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 613426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (FieldClassDecl->hasTrivialDestructor()) 614426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 615426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *LoadOfThis = LoadCXXThis(); 616426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0); 617426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 618426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian Dtor_Complete, LHS.getAddress()); 619b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 620426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = 621426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>(); 622426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 623426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (BaseClassDecl->hasTrivialDestructor()) 624426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 625426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 626426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian ClassDecl,BaseClassDecl); 627426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), 628426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian Dtor_Complete, V); 629426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 630426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 631426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian} 632