CGCXX.cpp revision cb1b5d32fd227cd791fbd0614f75b32f291a5cca
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(), 44c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::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. 53c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Value *nullValue = llvm::Constant::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 for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 168c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 169c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 170c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 171c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 172c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 173c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (Base == BaseClassDecl) { 174c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(BaseClassDecl); 175c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 176c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 177c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 178c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian // BaseClassDecl not an immediate base of ClassDecl. 179c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (CXXRecordDecl::base_class_const_iterator i = ClassDecl->bases_begin(), 180c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian e = ClassDecl->bases_end(); i != e; ++i) { 181c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (i->isVirtual()) 182c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian continue; 183c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *Base = 184c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 185c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian if (GetNestedPaths(NestedBasePaths, Base, BaseClassDecl)) { 186c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(Base); 187c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return true; 188c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 189c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 190c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian return false; 191c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian} 192c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 1939e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanianllvm::Value *CodeGenFunction::AddressCXXOfBaseClass(llvm::Value *BaseValue, 1946d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *ClassDecl, 1956d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian const CXXRecordDecl *BaseClassDecl) { 1969e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian if (ClassDecl == BaseClassDecl) 1979e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 1989e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 199c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 200c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian llvm::SmallVector<const CXXRecordDecl *, 16> NestedBasePaths; 201c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian GetNestedPaths(NestedBasePaths, ClassDecl, BaseClassDecl); 202c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian assert(NestedBasePaths.size() > 0 && 203c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian "AddressCXXOfBaseClass - inheritence path failed"); 204c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian NestedBasePaths.push_back(ClassDecl); 205c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian uint64_t Offset = 0; 206c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian 2079e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // Accessing a member of the base class. Must add delata to 2089e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian // the load of 'this'. 209c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian for (unsigned i = NestedBasePaths.size()-1; i > 0; i--) { 210c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *DerivedClass = NestedBasePaths[i]; 211c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const CXXRecordDecl *BaseClass = NestedBasePaths[i-1]; 212c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian const ASTRecordLayout &Layout = 213c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian getContext().getASTRecordLayout(DerivedClass); 214c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian Offset += Layout.getBaseClassOffset(BaseClass) / 8; 215c238a79a97ad35227a28acf16028ab63127c2fb7Fariborz Jahanian } 2165a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::Value *OffsetVal = 2175a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian llvm::ConstantInt::get( 2185a8503b333f50acd6012859853612229f38cb420Fariborz Jahanian CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset); 2199e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, I8Ptr); 2209e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateGEP(BaseValue, OffsetVal, "add.ptr"); 2219e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian QualType BTy = 2229e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian getContext().getCanonicalType( 2236d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl))); 2249e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian const llvm::Type *BasePtr = ConvertType(BTy); 22596e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson BasePtr = llvm::PointerType::getUnqual(BasePtr); 2269e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian BaseValue = Builder.CreateBitCast(BaseValue, BasePtr); 2279e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian return BaseValue; 2289e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian} 2299e809e7da2448c08aa11f15be4680226754678ceFariborz Jahanian 230b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 231b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 232b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CXXCtorType Type, 233b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson llvm::Value *This, 234b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgBeg, 235b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgEnd) { 236b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 237b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 238b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 239b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 240b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 2417267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 2427267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson CXXDtorType Type, 2437267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *This) { 2447267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 2457267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 2467267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson EmitCXXMemberCall(D, Callee, This, 0, 0); 2477267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson} 2487267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 249b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 25031ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 25131ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson const CXXConstructExpr *E) { 252b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson assert(Dest && "Must have a destination!"); 253b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 254b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson const CXXRecordDecl *RD = 2556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); 256b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson if (RD->hasTrivialConstructor()) 257b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson return; 258b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 259b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson // Call the constructor. 260b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 261b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson E->arg_begin(), E->arg_end()); 262b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 263b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 264a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 265ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson if (E->isArray()) { 266ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ErrorUnsupported(E, "new[] expression"); 26703e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return llvm::UndefValue::get(ConvertType(E->getType())); 268ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 269ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 270ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType AllocType = E->getAllocatedType(); 271ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson FunctionDecl *NewFD = E->getOperatorNew(); 272ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 273ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 274ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CallArgList NewArgs; 275ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 276ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // The allocation size is the first argument. 277ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType SizeTy = getContext().getSizeType(); 278ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson llvm::Value *AllocSize = 2794a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ConvertType(SizeTy), 280ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getTypeSize(AllocType) / 8); 281ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 282ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 283ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 284ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the rest of the arguments. 285ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // FIXME: Ideally, this should just use EmitCallArgs. 286ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 287ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 288ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // First, use the types from the function type. 289ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // We start at 1 here because the first argument (the allocation size) 290ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // has already been emitted. 291ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 292ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewFTy->getArgType(i); 293ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 294ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 295ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getTypePtr() == 296ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 297ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "type mismatch in call argument!"); 298ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 299ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 300ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 301ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 302ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 303ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 304ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Either we've emitted all the call args, or we have a call to a 305ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // variadic function. 306ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 307ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "Extra arguments in non-variadic function!"); 308ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 309ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // If we still have any arguments, emit them using the type of the argument. 310ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 311ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArg != NewArgEnd; ++NewArg) { 312ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewArg->getType(); 313ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 314ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 315ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 316ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 317ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the call to new. 318ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson RValue RV = 319ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 320ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 321ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs, NewFD); 322ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 323d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // If an allocation function is declared with an empty exception specification 324d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // it returns null to indicate failure to allocate storage. [expr.new]p13. 325d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // (We don't need to check for null when there's no new initializer and 326d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // we're allocating a POD type). 327d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 328d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson !(AllocType->isPODType() && !E->hasInitializer()); 329ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 330f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNull = 0; 331f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewNotNull = 0; 332f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::BasicBlock *NewEnd = 0; 333f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 334f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *NewPtr = RV.getScalarVal(); 335f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 336d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson if (NullCheckResult) { 337f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNull = createBasicBlock("new.null"); 338f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewNotNull = createBasicBlock("new.notnull"); 339f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewEnd = createBasicBlock("new.end"); 340f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 341f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::Value *IsNull = 342f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateICmpEQ(NewPtr, 343c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(NewPtr->getType()), 344f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson "isnull"); 345f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 346f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateCondBr(IsNull, NewNull, NewNotNull); 347f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNotNull); 348d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } 349d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 350f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType())); 351d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 3526d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson if (AllocType->isPODType()) { 353215bd208d6eeff397bc4316d046ea8b4633efedfAnders Carlsson if (E->getNumConstructorArgs() > 0) { 3546d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson assert(E->getNumConstructorArgs() == 1 && 3556d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson "Can only have one argument to initializer of POD type."); 3566d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3576d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson const Expr *Init = E->getConstructorArg(0); 3586d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3593923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson if (!hasAggregateLLVMType(AllocType)) 3606d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 3613923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson else if (AllocType->isAnyComplexType()) 3623923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 363627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson else 364627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 3656d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson } 366d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } else { 367d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // Call the constructor. 368d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson CXXConstructorDecl *Ctor = E->getConstructor(); 3696d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 370d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 371d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_begin(), 372d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_end()); 373ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 374d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 375f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson if (NullCheckResult) { 376f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 377f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewNull); 378f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson Builder.CreateBr(NewEnd); 379f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson EmitBlock(NewEnd); 380f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 381f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType()); 382f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->reserveOperandSpace(2); 383f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson PHI->addIncoming(NewPtr, NewNotNull); 384c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull); 385f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 386f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson NewPtr = PHI; 387f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson } 388f11085398dc27c0010663c711d4a10113e41d70fAnders Carlsson 389d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson return NewPtr; 390a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson} 391a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson 39227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD, 39327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ASTContext &Context) { 39459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // The class has base classes - we don't support that right now. 39559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (RD->getNumBases() > 0) 39659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 39759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 39817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 39917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis I != E; ++I) { 40059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // We don't support ctors for fields that aren't POD. 40159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (!I->getType()->isPODType()) 40259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 40359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 40459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 40559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return true; 40659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson} 40759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 40895d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 40927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 41059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson ErrorUnsupported(D, "C++ constructor", true); 41159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return; 41259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 41395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 4142a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Complete)); 4152a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Base)); 41695d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson} 417363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 41827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 41927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 42027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 42227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 42427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 42627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 42727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 42827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 429363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function * 430363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 431363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson CXXCtorType Type) { 432363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const llvm::FunctionType *FTy = 433363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 434363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 435363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const char *Name = getMangledCXXCtorName(D, Type); 436b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 437b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 438363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson} 43927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 44027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 44127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 44227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 44327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 44427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXCtor(D, Type, Context, Out); 44527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 44627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 44727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 44827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 44927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 45027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 45127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 45227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ErrorUnsupported(D, "C++ destructor", true); 45327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return; 45427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson } 45527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 45627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Complete); 45727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Base); 45827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 45927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 46127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 46227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 46327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 46527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 46627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 46727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 46827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 46927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 47027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function * 47127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 47227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 47327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const llvm::FunctionType *FTy = 47427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 47527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 47627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const char *Name = getMangledCXXDtorName(D, Type); 477b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 478b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 47927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 48027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 48127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 48227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 48327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 48427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 48527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXDtor(D, Type, Context, Out); 48627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 48727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 48827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 48927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 490e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 491738f8c278da5950d0d4607de2debe0bdfad64185Mike Stumpllvm::Constant *CodeGenFunction::GenerateRtti(const CXXRecordDecl *RD) { 492738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::Type *Ptr8Ty; 493738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 494cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump llvm::Constant *Rtti = llvm::Constant::getNullValue(Ptr8Ty); 495738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 496738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump if (!getContext().getLangOptions().Rtti) 497cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump return Rtti; 498738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 499738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::SmallString<256> OutName; 500738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::raw_svector_ostream Out(OutName); 501738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump QualType ClassTy; 502738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // FIXME: What is the design on getTagDeclType when it requires casting 503738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // away const? mutable? 504738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); 505738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump mangleCXXRtti(ClassTy, getContext(), Out); 506738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump const char *Name = OutName.c_str(); 507738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::GlobalVariable::LinkageTypes linktype; 508738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump linktype = llvm::GlobalValue::WeakAnyLinkage; 509738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump std::vector<llvm::Constant *> info; 510738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump assert (0 && "FIXME: implement rtti descriptor"); 511738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // FIXME: descriptor 512738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 513738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump assert (0 && "FIXME: implement rtti ts"); 514738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump // FIXME: TS 515738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump info.push_back(llvm::Constant::getNullValue(Ptr8Ty)); 516738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 517738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::Constant *C; 518738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, info.size()); 519738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump C = llvm::ConstantArray::get(type, info); 520cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump Rtti = new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C, 521738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump Name); 522cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump Rtti = llvm::ConstantExpr::getBitCast(Rtti, Ptr8Ty); 523cb1b5d32fd227cd791fbd0614f75b32f291a5ccaMike Stump return Rtti; 524738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump} 525738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump 526f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stumpllvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { 527f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::SmallString<256> OutName; 528f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::raw_svector_ostream Out(OutName); 529f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump QualType ClassTy; 530f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // FIXME: What is the design on getTagDeclType when it requires casting 531f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // away const? mutable? 532f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump ClassTy = getContext().getTagDeclType(const_cast<CXXRecordDecl*>(RD)); 533f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump mangleCXXVtable(ClassTy, getContext(), Out); 534f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump const char *Name = OutName.c_str(); 53582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::GlobalVariable::LinkageTypes linktype; 53682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump linktype = llvm::GlobalValue::WeakAnyLinkage; 53782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump std::vector<llvm::Constant *> methods; 538f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump typedef CXXRecordDecl::method_iterator meth_iter; 53982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Constant *m; 54082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Type *Ptr8Ty; 54182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 54282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump m = llvm::Constant::getNullValue(Ptr8Ty); 54382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump int64_t offset = 0; 54482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump methods.push_back(m); offset += LLVMPointerWidth; 545738f8c278da5950d0d4607de2debe0bdfad64185Mike Stump methods.push_back(GenerateRtti(RD)); offset += LLVMPointerWidth; 546f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; 547f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump ++mi) { 54882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump if (mi->isVirtual()) { 54982b56961dcb813674dbda3c5f5aaee703d55741cMike Stump m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); 55082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); 55182b56961dcb813674dbda3c5f5aaee703d55741cMike Stump methods.push_back(m); 55282b56961dcb813674dbda3c5f5aaee703d55741cMike Stump } 553f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump } 55482b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Constant *C; 55582b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size()); 55682b56961dcb813674dbda3c5f5aaee703d55741cMike Stump C = llvm::ConstantArray::get(type, methods); 55782b56961dcb813674dbda3c5f5aaee703d55741cMike Stump llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true, 55882b56961dcb813674dbda3c5f5aaee703d55741cMike Stump linktype, C, Name); 559f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateBitCast(vtable, Ptr8Ty); 56082b56961dcb813674dbda3c5f5aaee703d55741cMike Stump // FIXME: finish layout for virtual bases 561f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump vtable = Builder.CreateGEP(vtable, 562f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::ConstantInt::get(llvm::Type::Int64Ty, 56382b56961dcb813674dbda3c5f5aaee703d55741cMike Stump offset/8)); 564f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump return vtable; 565f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump} 566f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 567e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// EmitCtorPrologue - This routine generates necessary code to initialize 568e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian/// base classes and non-static data members belonging to this constructor. 569e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanianvoid CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { 570742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); 5717116da1efe23f90eb22524ac9aa036153b74f482Mike Stump assert(ClassDecl->getNumVBases() == 0 5727116da1efe23f90eb22524ac9aa036153b74f482Mike Stump && "FIXME: virtual base initialization unsupported"); 573f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *LoadOfThis = 0; 574f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 5756d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian 576742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 577e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian E = CD->init_end(); 578e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian B != E; ++B) { 579e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian CXXBaseOrMemberInitializer *Member = (*B); 580e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian if (Member->isBaseInitializer()) { 581f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 5826d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian Type *BaseType = Member->getBaseClass(); 5836d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian CXXRecordDecl *BaseClassDecl = 5846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 5856d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 5866d0bdaa68989bee60c85274e82a8f9c982587f26Fariborz Jahanian BaseClassDecl); 587742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 588742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Ctor_Complete, V, 589742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_begin(), 590742cd1b7bb86b52b23b335d47abbd842dac0e1bfFariborz Jahanian Member->const_arg_end()); 591b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 592e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian // non-static data member initilaizers. 593e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian FieldDecl *Field = Member->getMember(); 594e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian QualType FieldType = getContext().getCanonicalType((Field)->getType()); 595e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian assert(!getContext().getAsArrayType(FieldType) 596e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian && "FIXME. Field arrays initialization unsupported"); 59750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian 598f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 599e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0); 6006217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (FieldType->getAs<RecordType>()) { 60150b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian 60250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian assert(Member->getConstructor() && 60350b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian "EmitCtorPrologue - no constructor to initialize member"); 60450b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian EmitCXXConstructorCall(Member->getConstructor(), 60550b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Ctor_Complete, LHS.getAddress(), 60650b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Member->const_arg_begin(), 60750b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Member->const_arg_end()); 60850b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian continue; 60950b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian } 610e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian 611e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only"); 61250b8eea3f36881a988a5757e0f6e15d45900324bFariborz Jahanian Expr *RhsExpr = *Member->arg_begin(); 613e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian llvm::Value *RHS = EmitScalarExpr(RhsExpr, true); 614e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian if (LHS.isBitfield()) 615e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, FieldType, 0); 616e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian else 617e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType); 618e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 619e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian } 620f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump 621f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump // Initialize the vtable pointer 622f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (ClassDecl->isPolymorphic() || ClassDecl->getNumVBases()) { 623f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump if (!LoadOfThis) 624f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump LoadOfThis = LoadCXXThis(); 625f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *VtableField; 626f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Type *Ptr8Ty, *PtrPtr8Ty; 627f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0); 628f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0); 629f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty); 630f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump llvm::Value *vtable = GenerateVtable(ClassDecl); 631f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump Builder.CreateStore(vtable, VtableField); 632f121677b6bbbf4e4a51ee7a1120b77adf187bad4Mike Stump } 633e7d346b6d5cee14b75e34928b3fd423f21d8d80dFariborz Jahanian} 634426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 635426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// EmitDtorEpilogue - Emit all code that comes at the end of class's 636426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// destructor. This is to call destructors on members and base classes 637426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian/// in reverse order of their construction. 638426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanianvoid CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { 639426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext()); 640426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian assert(!ClassDecl->isPolymorphic() && 641426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian "FIXME. polymorphic destruction not supported"); 642426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian (void)ClassDecl; // prevent warning. 643426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian 644426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(), 645426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian *E = DD->destr_end(); B != E; ++B) { 646426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian uintptr_t BaseOrMember = (*B); 647426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (DD->isMemberToDestroy(BaseOrMember)) { 648426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember); 649426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian QualType FieldType = getContext().getCanonicalType((FD)->getType()); 650426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian assert(!getContext().getAsArrayType(FieldType) 651426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian && "FIXME. Field arrays destruction unsupported"); 652426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = FieldType->getAs<RecordType>(); 653426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 654426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (FieldClassDecl->hasTrivialDestructor()) 655426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 656426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *LoadOfThis = LoadCXXThis(); 657426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0); 658426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()), 659426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian Dtor_Complete, LHS.getAddress()); 660b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump } else { 661426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian const RecordType *RT = 662426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>(); 663426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 664426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian if (BaseClassDecl->hasTrivialDestructor()) 665426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian continue; 666426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(), 667426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian ClassDecl,BaseClassDecl); 668426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), 669426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian Dtor_Complete, V); 670426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 671426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian } 672426cc3828ce07a2cff15c9837f5958e6fc4b7739Fariborz Jahanian} 673