mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 11:56:12 +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");
|
||||
}
|
||||
|
||||
void DtoDeleteMemory(Loc& loc, LLValue* ptr)
|
||||
void DtoDeleteMemory(Loc& loc, DValue* ptr)
|
||||
{
|
||||
// get runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delmemory");
|
||||
// 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
|
||||
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");
|
||||
// druntime wants a pointer to object
|
||||
LLValue *ptr = DtoRawAlloca(inst->getType(), 0, "objectPtr");
|
||||
DtoStore(inst, ptr);
|
||||
inst = ptr;
|
||||
// build args
|
||||
LLValue* arg[] = {
|
||||
DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")
|
||||
};
|
||||
// call
|
||||
LLValue* lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst));
|
||||
LLValue* arg[] = { DtoBitCast(lval, fn->getFunctionType()->getParamType(0)) };
|
||||
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");
|
||||
// build args
|
||||
LLValue* arg[] = {
|
||||
DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")
|
||||
};
|
||||
// call
|
||||
LLValue* lval = (inst->isLVal() ? inst->getLVal() : makeLValue(loc, inst));
|
||||
LLValue* arg[] = { DtoBitCast(lval, fn->getFunctionType()->getParamType(0)) };
|
||||
gIR->CreateCallOrInvoke(fn, arg);
|
||||
}
|
||||
|
||||
void DtoDeleteArray(Loc& loc, DValue* arr)
|
||||
{
|
||||
// get runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(loc, gIR->module, "_d_delarray_t");
|
||||
|
||||
// build args
|
||||
llvm::FunctionType* fty = fn->getFunctionType();
|
||||
LLValue* arg[] = {
|
||||
DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(0)),
|
||||
DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fn->getFunctionType()->getParamType(1))
|
||||
DtoBitCast(arr->getLVal(), fty->getParamType(0)),
|
||||
DtoBitCast(DtoTypeInfoOf(arr->type->nextOf()), fty->getParamType(1))
|
||||
};
|
||||
|
||||
// call
|
||||
gIR->CreateCallOrInvoke(fn, arg);
|
||||
}
|
||||
|
||||
|
@ -132,7 +128,6 @@ void DtoDeleteArray(Loc& loc, DValue* arr)
|
|||
// ALLOCA HELPERS
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
|
||||
{
|
||||
LLType* lltype = i1ToI8(DtoType(type));
|
||||
|
|
|
@ -34,9 +34,10 @@ struct EnclosingTryFinally
|
|||
|
||||
// dynamic memory helpers
|
||||
LLValue* DtoNew(Loc& loc, Type* newtype);
|
||||
void DtoDeleteMemory(Loc& loc, LLValue* ptr);
|
||||
void DtoDeleteClass(Loc& loc, LLValue* inst);
|
||||
void DtoDeleteInterface(Loc& loc, LLValue* inst);
|
||||
void DtoDeleteMemory(Loc& loc, DValue* ptr);
|
||||
void DtoDeleteStruct(Loc& loc, DValue* ptr);
|
||||
void DtoDeleteClass(Loc& loc, DValue* inst);
|
||||
void DtoDeleteInterface(Loc& loc, DValue* inst);
|
||||
void DtoDeleteArray(Loc& loc, DValue* arr);
|
||||
|
||||
// emit an alloca
|
||||
|
|
|
@ -82,6 +82,7 @@ static void checkForImplicitGCCall(const Loc &loc, const char *name)
|
|||
"_d_callfinalizer",
|
||||
"_d_delarray_t",
|
||||
"_d_delclass",
|
||||
"_d_delstruct",
|
||||
"_d_delinterface",
|
||||
"_d_delmemory",
|
||||
"_d_newarrayT",
|
||||
|
@ -539,6 +540,14 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
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);
|
||||
Type* et = e->e1->type->toBasetype();
|
||||
|
||||
// simple pointer
|
||||
// pointer
|
||||
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
|
||||
else if (et->ty == Tclass)
|
||||
|
@ -2003,8 +2007,7 @@ public:
|
|||
TypeClass* tc = static_cast<TypeClass*>(et);
|
||||
if (tc->sym->isInterfaceDeclaration())
|
||||
{
|
||||
LLValue *val = dval->getLVal();
|
||||
DtoDeleteInterface(e->loc, val);
|
||||
DtoDeleteInterface(e->loc, dval);
|
||||
onstack = true;
|
||||
}
|
||||
else if (DVarValue* vv = dval->isVar()) {
|
||||
|
@ -2013,11 +2016,10 @@ public:
|
|||
onstack = true;
|
||||
}
|
||||
}
|
||||
if (!onstack) {
|
||||
LLValue* rval = dval->getRVal();
|
||||
DtoDeleteClass(e->loc, rval);
|
||||
}
|
||||
if (dval->isVar()) {
|
||||
|
||||
if (!onstack)
|
||||
DtoDeleteClass(e->loc, dval); // sets dval to null
|
||||
else if (dval->isVar()) {
|
||||
LLValue* lval = dval->getLVal();
|
||||
DtoStore(LLConstant::getNullValue(lval->getType()->getContainedType(0)), lval);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue