CGCXX.cpp revision d3fd6bad1249d3f34d71b73e2333fab0db51cce4
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" 20e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h" 21774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson#include "clang/AST/DeclCXX.h" 2286e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h" 23e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h" 24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang; 25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen; 26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 270096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbarvoid 280096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel DunbarCodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, 290096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar llvm::GlobalVariable *GV) { 300096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar // FIXME: This should use __cxa_guard_{acquire,release}? 310096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar 32e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson assert(!getContext().getLangOptions().ThreadsafeStatics && 33e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson "thread safe statics are currently not supported!"); 34e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 35283a062a633d6e868aa2be319da812341fe73728Anders Carlsson llvm::SmallString<256> GuardVName; 36283a062a633d6e868aa2be319da812341fe73728Anders Carlsson llvm::raw_svector_ostream GuardVOut(GuardVName); 37283a062a633d6e868aa2be319da812341fe73728Anders Carlsson mangleGuardVariable(&D, getContext(), GuardVOut); 38283a062a633d6e868aa2be319da812341fe73728Anders Carlsson 39e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // Create the guard variable. 40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::GlobalValue *GuardV = 41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson new llvm::GlobalVariable(llvm::Type::Int64Ty, false, 420096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar GV->getLinkage(), 43e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson llvm::Constant::getNullValue(llvm::Type::Int64Ty), 44283a062a633d6e868aa2be319da812341fe73728Anders Carlsson GuardVName.c_str(), 45e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson &CGM.getModule()); 46e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 47e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson // Load the first byte of the guard variable. 480096acf421c4609ce7f43e8b05f8c5ca866d4611Daniel Dunbar 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. 53e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 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 74e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson 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(); 109774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson const llvm::Type *Ty = 110e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 111e9918d2443ad524e0f488e8f15d9bce4e7373cd1Anders Carlsson FPT->isVariadic()); 112b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 113774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 114b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *This; 115774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 116774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson if (ME->isArrow()) 117b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = EmitScalarExpr(ME->getBase()); 118774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson else { 119774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson LValue BaseLV = EmitLValue(ME->getBase()); 120b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson This = BaseLV.getAddress(); 121774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson } 122774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson 123b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson return EmitCXXMemberCall(MD, Callee, This, 124b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson CE->arg_begin(), CE->arg_end()); 125774e7c6881ee6cb970cd42239d700dce87ed402aAnders Carlsson} 1265f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 1270f294632f36459174199b77699e339715244b5abAnders CarlssonRValue 1280f294632f36459174199b77699e339715244b5abAnders CarlssonCodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 1290f294632f36459174199b77699e339715244b5abAnders Carlsson const CXXMethodDecl *MD) { 1300f294632f36459174199b77699e339715244b5abAnders Carlsson assert(MD->isInstance() && 1310f294632f36459174199b77699e339715244b5abAnders Carlsson "Trying to emit a member call expr on a static method!"); 1320f294632f36459174199b77699e339715244b5abAnders Carlsson 1330f294632f36459174199b77699e339715244b5abAnders Carlsson 1340f294632f36459174199b77699e339715244b5abAnders Carlsson const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); 1350f294632f36459174199b77699e339715244b5abAnders Carlsson const llvm::Type *Ty = 1360f294632f36459174199b77699e339715244b5abAnders Carlsson CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 1370f294632f36459174199b77699e339715244b5abAnders Carlsson FPT->isVariadic()); 1380f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); 1390f294632f36459174199b77699e339715244b5abAnders Carlsson 1400f294632f36459174199b77699e339715244b5abAnders Carlsson llvm::Value *This = EmitLValue(E->getArg(0)).getAddress(); 1410f294632f36459174199b77699e339715244b5abAnders Carlsson 1420f294632f36459174199b77699e339715244b5abAnders Carlsson return EmitCXXMemberCall(MD, Callee, This, 1430f294632f36459174199b77699e339715244b5abAnders Carlsson E->arg_begin() + 1, E->arg_end()); 1440f294632f36459174199b77699e339715244b5abAnders Carlsson} 1450f294632f36459174199b77699e339715244b5abAnders Carlsson 1465f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlssonllvm::Value *CodeGenFunction::LoadCXXThis() { 1475f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(isa<CXXMethodDecl>(CurFuncDecl) && 1485f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 1495f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() && 1505f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson "Must be in a C++ member function decl to load 'this'"); 1515f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson 1525f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson // FIXME: What if we're inside a block? 153f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // ans: See how CodeGenFunction::LoadObjCSelf() uses 154f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump // CodeGenFunction::BlockForwardSelf() for how to do this. 1555f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 1565f4307b7ba164b03c853c8d3eb4674d33f8967a6Anders Carlsson} 15795d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 158b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 159b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders CarlssonCodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 160b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CXXCtorType Type, 161b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson llvm::Value *This, 162b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgBeg, 163b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson CallExpr::const_arg_iterator ArgEnd) { 164b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); 165b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson 166b9de2c55b2a33776e2bee8ee57df7599b374c8a5Anders Carlsson EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); 167b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 168b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 1697267c1693abe7875b0c57268be05005ae013c6c9Anders Carlssonvoid CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, 1707267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson CXXDtorType Type, 1717267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *This) { 1727267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); 1737267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 1747267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson EmitCXXMemberCall(D, Callee, This, 0, 0); 1757267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson} 1767267c1693abe7875b0c57268be05005ae013c6c9Anders Carlsson 177b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlssonvoid 17831ccf377f4a676eb6c205b47eef435de616d5e2dAnders CarlssonCodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, 17931ccf377f4a676eb6c205b47eef435de616d5e2dAnders Carlsson const CXXConstructExpr *E) { 180b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson assert(Dest && "Must have a destination!"); 181b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 182b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson const CXXRecordDecl *RD = 183b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson cast<CXXRecordDecl>(E->getType()->getAsRecordType()->getDecl()); 184b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson if (RD->hasTrivialConstructor()) 185b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson return; 186b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 187b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson // Call the constructor. 188b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, 189b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson E->arg_begin(), E->arg_end()); 190b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson} 191b14095aa98c6fedd3625920c4ce834bcaf24d9f7Anders Carlsson 192543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlssonvoid CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, 193543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson llvm::Value *Ptr) { 194543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson LiveTemporaries.push_back(Temporary); 195543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 196543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson // Make a cleanup scope and emit the destructor. 197543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson { 198543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson CleanupScope Scope(*this); 199543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 200543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr); 201543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson } 202543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson} 203543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 204b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders CarlssonRValue 205b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders CarlssonCodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, 206b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson llvm::Value *AggLoc, 207b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson bool isAggLocVolatile) { 208543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson // Keep track of the current cleanup stack depth. 209543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson size_t CleanupStackDepth = CleanupEntries.size(); 210543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 211543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson unsigned OldNumLiveTemporaries = LiveTemporaries.size(); 212543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 213b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); 214b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson 215543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson // Go through the temporaries backwards. 216543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson for (unsigned i = E->getNumTemporaries(); i != 0; --i) { 217543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson assert(LiveTemporaries.back() == E->getTemporary(i - 1)); 218543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson LiveTemporaries.pop_back(); 219543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson } 220543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 221543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson assert(OldNumLiveTemporaries == LiveTemporaries.size() && 222543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson "Live temporary stack mismatch!"); 223b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson 224543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson EmitCleanupBlocks(CleanupStackDepth); 225543ac0c4d24a81fb2b7b6e83370aa8e4cbc93054Anders Carlsson 226b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson return RV; 227b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson} 228b58d017f2b9eeed33f2ab3ede968b89cf5296bf2Anders Carlsson 229a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlssonllvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 230ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson if (E->isArray()) { 231ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ErrorUnsupported(E, "new[] expression"); 232ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson return llvm::UndefValue::get(ConvertType(E->getType())); 233ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 234ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 235ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType AllocType = E->getAllocatedType(); 236ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson FunctionDecl *NewFD = E->getOperatorNew(); 237ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson const FunctionProtoType *NewFTy = NewFD->getType()->getAsFunctionProtoType(); 238ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 239ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CallArgList NewArgs; 240ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 241ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // The allocation size is the first argument. 242ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType SizeTy = getContext().getSizeType(); 243ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson llvm::Value *AllocSize = 244ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson llvm::ConstantInt::get(ConvertType(SizeTy), 245ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getTypeSize(AllocType) / 8); 246ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 247ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy)); 248ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 249ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the rest of the arguments. 250ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // FIXME: Ideally, this should just use EmitCallArgs. 251ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin(); 252ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 253ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // First, use the types from the function type. 254ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // We start at 1 here because the first argument (the allocation size) 255ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // has already been emitted. 256ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) { 257ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewFTy->getArgType(i); 258ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 259ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert(getContext().getCanonicalType(ArgType.getNonReferenceType()). 260ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getTypePtr() == 261ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson getContext().getCanonicalType(NewArg->getType()).getTypePtr() && 262ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "type mismatch in call argument!"); 263ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 264ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 265ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 266ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 267ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 268ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 269ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Either we've emitted all the call args, or we have a call to a 270ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // variadic function. 271ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) && 272ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson "Extra arguments in non-variadic function!"); 273ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 274ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // If we still have any arguments, emit them using the type of the argument. 275ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end(); 276ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArg != NewArgEnd; ++NewArg) { 277ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson QualType ArgType = NewArg->getType(); 278ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType), 279ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson ArgType)); 280ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 281ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 282ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson // Emit the call to new. 283ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson RValue RV = 284ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs), 285ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson CGM.GetAddrOfFunction(GlobalDecl(NewFD)), 286ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson NewArgs, NewFD); 287ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 288d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // If an allocation function is declared with an empty exception specification 289d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // it returns null to indicate failure to allocate storage. [expr.new]p13. 290d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // (We don't need to check for null when there's no new initializer and 291d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // we're allocating a POD type). 292d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() && 293d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson !(AllocType->isPODType() && !E->hasInitializer()); 294ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson 295d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson if (NullCheckResult) { 296d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson ErrorUnsupported(E, "new expr that needs to be null checked"); 297d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson return llvm::UndefValue::get(ConvertType(E->getType())); 298d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } 299d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 300d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson llvm::Value *NewPtr = 301d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson Builder.CreateBitCast(RV.getScalarVal(), ConvertType(E->getType())); 302d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 3036d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson if (AllocType->isPODType()) { 304d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson if (E->hasInitializer()) { 3056d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson assert(E->getNumConstructorArgs() == 1 && 3066d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson "Can only have one argument to initializer of POD type."); 3076d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3086d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson const Expr *Init = E->getConstructorArg(0); 3096d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 3103923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson if (!hasAggregateLLVMType(AllocType)) 3116d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson Builder.CreateStore(EmitScalarExpr(Init), NewPtr); 3123923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson else if (AllocType->isAnyComplexType()) 3133923e95280210ef877153f0c3dbab12d6ed2ad43Anders Carlsson EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); 314627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson else 315627a3e573f1d9f0429d62c7ceb742a21cdabfce0Anders Carlsson EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified()); 3166d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson } 317d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson } else { 318d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson // Call the constructor. 319d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson CXXConstructorDecl *Ctor = E->getConstructor(); 3206d0ffad181215fc4ec0fca37c55eae82df6e0531Anders Carlsson 321d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 322d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_begin(), 323d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson E->constructor_arg_end()); 324ed4e367f8e27d2c700efdaff9412f2bf83ddba00Anders Carlsson } 325d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson 326d3fd6bad1249d3f34d71b73e2333fab0db51cce4Anders Carlsson return NewPtr; 327a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson} 328a00703dccbdc6cc4a293db38477dea7db5538c7eAnders Carlsson 32927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonstatic bool canGenerateCXXstructor(const CXXRecordDecl *RD, 33027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ASTContext &Context) { 33159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // The class has base classes - we don't support that right now. 33259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (RD->getNumBases() > 0) 33359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 33459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 33559d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(Context), 33659d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson E = RD->field_end(Context); I != E; ++I) { 33759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson // We don't support ctors for fields that aren't POD. 33859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson if (!I->getType()->isPODType()) 33959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return false; 34059d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 34159d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 34259d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return true; 34359d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson} 34459d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson 34595d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlssonvoid CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { 34627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 34759d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson ErrorUnsupported(D, "C++ constructor", true); 34859d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson return; 34959d8e0ff383274d992b3fa9ebee48b5e4a5ebdd1Anders Carlsson } 35095d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson 3512a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Complete)); 3522a131fbca2a51085dc083b8c56a2d4ced3cf1413Anders Carlsson EmitGlobal(GlobalDecl(D, Ctor_Base)); 35395d4e5d2f87a0f07fb143ccb824dfc4c5c595c78Anders Carlsson} 354363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 35527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 35627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 35727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 35827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); 35927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 36027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 36127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 36227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 36327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 36427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 36527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 366363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlssonllvm::Function * 367363c184139e26ea38223b477ad64ee67b22bb9a7Anders CarlssonCodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, 368363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson CXXCtorType Type) { 369363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const llvm::FunctionType *FTy = 370363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 371363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson 372363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson const char *Name = getMangledCXXCtorName(D, Type); 373b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 374b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 375363c184139e26ea38223b477ad64ee67b22bb9a7Anders Carlsson} 37627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 37727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 37827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXCtorType Type) { 37927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 38027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 38127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXCtor(D, Type, Context, Out); 38227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 38327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 38427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 38527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 38627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 38727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { 38827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson if (!canGenerateCXXstructor(D->getParent(), getContext())) { 38927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson ErrorUnsupported(D, "C++ destructor", true); 39027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return; 39127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson } 39227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 39327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Complete); 39427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson EmitCXXDestructor(D, Dtor_Base); 39527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 39627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 39727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonvoid CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, 39827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 39927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); 40027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 40127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CodeGenFunction(*this).GenerateCode(D, Fn); 40227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 40327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetFunctionDefinitionAttributes(D, Fn); 40427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson SetLLVMFunctionAttributesForDefinition(D, Fn); 40527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 40627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 40727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonllvm::Function * 40827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders CarlssonCodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, 40927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 41027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const llvm::FunctionType *FTy = 41127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); 41227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 41327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson const char *Name = getMangledCXXDtorName(D, Type); 414b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner return cast<llvm::Function>( 415b4880bab7fc1b61267cfd9a0ad52188e7a828cb3Chris Lattner GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); 41627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 41727ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 41827ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlssonconst char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 41927ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson CXXDtorType Type) { 42027ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::SmallString<256> Name; 42127ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson llvm::raw_svector_ostream Out(Name); 42227ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson mangleCXXDtor(D, Type, Context, Out); 42327ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson 42427ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson Name += '\0'; 42527ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson return UniqueMangledName(Name.begin(), Name.end()); 42627ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5Anders Carlsson} 427