mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
Call _d_delstruct() runtime function when deleting struct pointers.
As long as the struct has a dtor, otherwise continue forwarding to _d_delmemory().
This commit is contained in:
parent
0178078af1
commit
7d0d2a1d26
4 changed files with 47 additions and 40 deletions
|
@ -74,56 +74,52 @@ LLValue* DtoNew(Loc& loc, Type* newtype)
|
||||||
return DtoBitCast(mem, getPtrToType(i1ToI8(DtoType(newtype))), ".gc_mem");
|
return DtoBitCast(mem, getPtrToType(i1ToI8(DtoType(newtype))), ".gc_mem");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoDeleteMemory(Loc& loc, LLValue* ptr)
|
void DtoDeleteMemory(Loc& loc, DValue* ptr)
|
||||||
{
|
{
|
||||||
// get runtime function
|
// get runtime function
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delmemory");
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delmemory");
|
||||||
// build args
|
// build args
|
||||||
LLValue* arg[] = { DtoBitCast(ptr, getPtrToType(getVoidPtrType()), ".tmp") };
|
LLValue* lval = (ptr->isLVal() ? ptr->getLVal() : makeLValue(loc, ptr));
|
||||||
|
LLValue* arg[] = { DtoBitCast(lval, fn->getFunctionType()->getParamType(0)) };
|
||||||
// call
|
// call
|
||||||
gIR->CreateCallOrInvoke(fn, arg);
|
gIR->CreateCallOrInvoke(fn, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoDeleteClass(Loc& loc, LLValue* inst)
|
void DtoDeleteStruct(Loc& loc, DValue* ptr)
|
||||||
|
{
|
||||||
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delstruct");
|
||||||
|
LLValue* lval = (ptr->isLVal() ? ptr->getLVal() : makeLValue(loc, ptr));
|
||||||
|
LLValue* arg[] = {
|
||||||
|
DtoBitCast(lval, fn->getFunctionType()->getParamType(0)),
|
||||||
|
DtoBitCast(DtoTypeInfoOf(ptr->type->nextOf()), fn->getFunctionType()->getParamType(1))
|
||||||
|
};
|
||||||
|
gIR->CreateCallOrInvoke(fn, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DtoDeleteClass(Loc& loc, DValue* inst)
|
||||||
{
|
{
|
||||||
// get runtime function
|
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delclass");
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delclass");
|
||||||
// druntime wants a pointer to object
|
LLValue* lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst));
|
||||||
LLValue *ptr = DtoRawAlloca(inst->getType(), 0, "objectPtr");
|
LLValue* arg[] = { DtoBitCast(lval, fn->getFunctionType()->getParamType(0)) };
|
||||||
DtoStore(inst, ptr);
|
|
||||||
inst = ptr;
|
|
||||||
// build args
|
|
||||||
LLValue* arg[] = {
|
|
||||||
DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")
|
|
||||||
};
|
|
||||||
// call
|
|
||||||
gIR->CreateCallOrInvoke(fn, arg);
|
gIR->CreateCallOrInvoke(fn, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoDeleteInterface(Loc& loc, LLValue* inst)
|
void DtoDeleteInterface(Loc& loc, DValue* inst)
|
||||||
{
|
{
|
||||||
// get runtime function
|
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delinterface");
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delinterface");
|
||||||
// build args
|
LLValue* lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst));
|
||||||
LLValue* arg[] = {
|
LLValue* arg[] = { DtoBitCast(lval, fn->getFunctionType()->getParamType(0)) };
|
||||||
DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")
|
|
||||||
};
|
|
||||||
// call
|
|
||||||
gIR->CreateCallOrInvoke(fn, arg);
|
gIR->CreateCallOrInvoke(fn, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtoDeleteArray(Loc& loc, DValue* arr)
|
void DtoDeleteArray(Loc& loc, DValue* arr)
|
||||||
{
|
{
|
||||||
// get runtime function
|
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delarray_t");
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delarray_t");
|
||||||
|
llvm::FunctionType* fty = fn->getFunctionType();
|
||||||
// build args
|
|
||||||
LLValue* arg[] = {
|
LLValue* arg[] = {
|
||||||
DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(0)),
|
DtoBitCast(arr->getLVal(), fty->getParamType(0)),
|
||||||
DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fn->getFunctionType()->getParamType(1))
|
DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fty->getParamType(1))
|
||||||
};
|
};
|
||||||
|
|
||||||
// call
|
|
||||||
gIR->CreateCallOrInvoke(fn, arg);
|
gIR->CreateCallOrInvoke(fn, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +128,6 @@ void DtoDeleteArray(Loc& loc, DValue* arr)
|
||||||
// ALLOCA HELPERS
|
// ALLOCA HELPERS
|
||||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
|
||||||
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
|
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
|
||||||
{
|
{
|
||||||
LLType* lltype = i1ToI8(DtoType(type));
|
LLType* lltype = i1ToI8(DtoType(type));
|
||||||
|
|
|
@ -34,9 +34,10 @@ struct EnclosingTryFinally
|
||||||
|
|
||||||
// dynamic memory helpers
|
// dynamic memory helpers
|
||||||
LLValue* DtoNew(Loc& loc, Type* newtype);
|
LLValue* DtoNew(Loc& loc, Type* newtype);
|
||||||
void DtoDeleteMemory(Loc& loc, LLValue* ptr);
|
void DtoDeleteMemory(Loc& loc, DValue* ptr);
|
||||||
void DtoDeleteClass(Loc& loc, LLValue* inst);
|
void DtoDeleteStruct(Loc& loc, DValue* ptr);
|
||||||
void DtoDeleteInterface(Loc& loc, LLValue* inst);
|
void DtoDeleteClass(Loc& loc, DValue* inst);
|
||||||
|
void DtoDeleteInterface(Loc& loc, DValue* inst);
|
||||||
void DtoDeleteArray(Loc& loc, DValue* arr);
|
void DtoDeleteArray(Loc& loc, DValue* arr);
|
||||||
|
|
||||||
// emit an alloca
|
// emit an alloca
|
||||||
|
|
|
@ -82,6 +82,7 @@ static void checkForImplicitGCCall(const Loc &loc, const char *name)
|
||||||
"_d_callfinalizer",
|
"_d_callfinalizer",
|
||||||
"_d_delarray_t",
|
"_d_delarray_t",
|
||||||
"_d_delclass",
|
"_d_delclass",
|
||||||
|
"_d_delstruct",
|
||||||
"_d_delinterface",
|
"_d_delinterface",
|
||||||
"_d_delmemory",
|
"_d_delmemory",
|
||||||
"_d_newarrayT",
|
"_d_newarrayT",
|
||||||
|
@ -539,6 +540,14 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void _d_delstruct(void** p, TypeInfo_Struct inf)
|
||||||
|
{
|
||||||
|
llvm::StringRef fname("_d_delstruct");
|
||||||
|
LLType *types[] = { rt_ptr(voidPtrTy), DtoType(Type::typeinfostruct->type) };
|
||||||
|
LLFunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
|
||||||
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
20
gen/toir.cpp
20
gen/toir.cpp
|
@ -1991,10 +1991,14 @@ public:
|
||||||
DValue* dval = toElem(e->e1);
|
DValue* dval = toElem(e->e1);
|
||||||
Type* et = e->e1->type->toBasetype();
|
Type* et = e->e1->type->toBasetype();
|
||||||
|
|
||||||
// simple pointer
|
// pointer
|
||||||
if (et->ty == Tpointer)
|
if (et->ty == Tpointer)
|
||||||
{
|
{
|
||||||
DtoDeleteMemory(e->loc, dval->isLVal() ? dval->getLVal() : makeLValue(e->loc, dval));
|
Type* elementType = et->nextOf()->toBasetype();
|
||||||
|
if (elementType->ty == Tstruct && static_cast<TypeStruct*>(elementType)->sym->dtor)
|
||||||
|
DtoDeleteStruct(e->loc, dval);
|
||||||
|
else
|
||||||
|
DtoDeleteMemory(e->loc, dval);
|
||||||
}
|
}
|
||||||
// class
|
// class
|
||||||
else if (et->ty == Tclass)
|
else if (et->ty == Tclass)
|
||||||
|
@ -2003,8 +2007,7 @@ public:
|
||||||
TypeClass* tc = static_cast<TypeClass*>(et);
|
TypeClass* tc = static_cast<TypeClass*>(et);
|
||||||
if (tc->sym->isInterfaceDeclaration())
|
if (tc->sym->isInterfaceDeclaration())
|
||||||
{
|
{
|
||||||
LLValue *val = dval->getLVal();
|
DtoDeleteInterface(e->loc, dval);
|
||||||
DtoDeleteInterface(e->loc, val);
|
|
||||||
onstack = true;
|
onstack = true;
|
||||||
}
|
}
|
||||||
else if (DVarValue* vv = dval->isVar()) {
|
else if (DVarValue* vv = dval->isVar()) {
|
||||||
|
@ -2013,11 +2016,10 @@ public:
|
||||||
onstack = true;
|
onstack = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!onstack) {
|
|
||||||
LLValue* rval = dval->getRVal();
|
if (!onstack)
|
||||||
DtoDeleteClass(e->loc, rval);
|
DtoDeleteClass(e->loc, dval); // sets dval to null
|
||||||
}
|
else if (dval->isVar()) {
|
||||||
if (dval->isVar()) {
|
|
||||||
LLValue* lval = dval->getLVal();
|
LLValue* lval = dval->getLVal();
|
||||||
DtoStore(LLConstant::getNullValue(lval->getType()->getContainedType(0)), lval);
|
DtoStore(LLConstant::getNullValue(lval->getType()->getContainedType(0)), lval);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue