mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 07:30:43 +03:00
Resolving nested context for structs.
* * * Another fix for nested structs * * * Yet another fix for nested structs
This commit is contained in:
parent
e3afcf8a8d
commit
360a99caa9
7 changed files with 63 additions and 22 deletions
|
@ -170,16 +170,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
|
|||
// set the context for nested classes
|
||||
else if (tc->sym->isNested() && tc->sym->vthis)
|
||||
{
|
||||
Logger::println("Resolving nested context");
|
||||
LOG_SCOPE;
|
||||
|
||||
// get context
|
||||
LLValue* nest = DtoNestedContext(loc, tc->sym);
|
||||
|
||||
// store into right location
|
||||
size_t idx = tc->sym->vthis->ir.irField->index;
|
||||
LLValue* gep = DtoGEPi(mem,0,idx,"tmp");
|
||||
DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
|
||||
DtoResolveNestedContext(loc, tc->sym, mem);
|
||||
}
|
||||
|
||||
// call constructor
|
||||
|
|
|
@ -364,10 +364,16 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
|||
if (!t->equals(t2)) {
|
||||
// FIXME: use 'rhs' for something !?!
|
||||
DtoAggrZeroInit(lhs->getLVal());
|
||||
#if DMDV2
|
||||
TypeStruct *ts = (TypeStruct*) lhs->getType();
|
||||
if (ts->sym->isNested() && ts->sym->vthis)
|
||||
DtoResolveNestedContext(loc, ts->sym, lhs->getLVal());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
|
||||
}
|
||||
|
||||
}
|
||||
else if (t->ty == Tarray) {
|
||||
// lhs is slice
|
||||
|
|
|
@ -213,6 +213,24 @@ void DtoNestedInit(VarDeclaration* vd)
|
|||
}
|
||||
}
|
||||
|
||||
#if DMDV2
|
||||
LLValue* DtoResolveNestedContext(Loc loc, AggregateDeclaration *decl, LLValue *value)
|
||||
#else
|
||||
LLValue* DtoResolveNestedContext(Loc loc, ClassDeclaration *decl, LLValue *value)
|
||||
#endif
|
||||
{
|
||||
Logger::println("Resolving nested context");
|
||||
LOG_SCOPE;
|
||||
|
||||
// get context
|
||||
LLValue* nest = DtoNestedContext(loc, decl);
|
||||
|
||||
// store into right location
|
||||
size_t idx = decl->vthis->ir.irField->index;
|
||||
LLValue* gep = DtoGEPi(value,0,idx,"tmp");
|
||||
DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
|
||||
}
|
||||
|
||||
LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
||||
{
|
||||
Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
|
||||
|
@ -234,11 +252,16 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
|||
// or just have a this argument
|
||||
else if (irfunc->thisArg)
|
||||
{
|
||||
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
|
||||
if (!cd || !cd->vthis)
|
||||
return llvm::UndefValue::get(getVoidPtrType());
|
||||
#if DMDV2
|
||||
AggregateDeclaration* ad = irfunc->decl->isMember2();
|
||||
val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg;
|
||||
#else
|
||||
ClassDeclaration* ad = irfunc->decl->isMember2()->isClassDeclaration();
|
||||
val = DtoLoad(irfunc->thisArg);
|
||||
val = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
|
||||
#endif
|
||||
if (!ad || !ad->vthis)
|
||||
return llvm::UndefValue::get(getVoidPtrType());
|
||||
val = DtoLoad(DtoGEPi(val, 0,ad->vthis->ir.irField->index, ".vthis"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -477,10 +500,19 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
assert(irfunction->thisArg);
|
||||
assert(fd->isMember2());
|
||||
LLValue* thisval = DtoLoad(irfunction->thisArg);
|
||||
#if DMDV2
|
||||
AggregateDeclaration* cd = fd->isMember2();
|
||||
#else
|
||||
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
|
||||
#endif
|
||||
assert(cd);
|
||||
assert(cd->vthis);
|
||||
Logger::println("Indexing to 'this'");
|
||||
#if DMDV2
|
||||
if (cd->isStructDeclaration())
|
||||
src = DtoExtractValue(thisval, cd->vthis->ir.irField->index, ".vthis");
|
||||
else
|
||||
#endif
|
||||
src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
|
||||
}
|
||||
if (depth > 1) {
|
||||
|
|
12
gen/nested.h
12
gen/nested.h
|
@ -4,6 +4,7 @@
|
|||
#include "declaration.h"
|
||||
#include "mtype.h"
|
||||
#include "gen/dvalue.h"
|
||||
#include "gen/llvm.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Nested variable and context helpers
|
||||
|
@ -15,8 +16,15 @@ void DtoCreateNestedContext(FuncDeclaration* fd);
|
|||
/// Allocate space for variable accessed from nested function.
|
||||
void DtoNestedInit(VarDeclaration* vd);
|
||||
|
||||
/// Gets the context value for a call to a nested function or newing a nested
|
||||
/// class with arbitrary nesting.
|
||||
/// Resolves the nested context for classes and structs with arbitrary nesting.
|
||||
#if DMDV2
|
||||
LLValue* DtoResolveNestedContext(Loc loc, AggregateDeclaration *decl, LLValue *value);
|
||||
#else
|
||||
LLValue* DtoResolveNestedContext(Loc loc, ClassDeclaration *decl, LLValue *value);
|
||||
#endif
|
||||
|
||||
/// Gets the context value for a call to a nested function or creating a nested
|
||||
/// class or struct with arbitrary nesting.
|
||||
llvm::Value* DtoNestedContext(Loc loc, Dsymbol* sym);
|
||||
|
||||
/// Gets the DValue of a nested variable with arbitrary nesting.
|
||||
|
|
|
@ -1694,6 +1694,10 @@ DValue* NewExp::toElem(IRState* p)
|
|||
ts->sym->codegen(Type::sir);
|
||||
DtoAggrCopy(mem, ts->sym->ir.irStruct->getInitSymbol());
|
||||
}
|
||||
#if DMDV2
|
||||
if (ts->sym->isNested() && ts->sym->vthis)
|
||||
DtoResolveNestedContext(loc, ts->sym, mem);
|
||||
#endif
|
||||
return new DImValue(type, mem);
|
||||
}
|
||||
// new basic type
|
||||
|
|
|
@ -657,14 +657,14 @@ LLConstant* DtoBitCast(LLConstant* v, const LLType* t)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx)
|
||||
LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx, const char* name)
|
||||
{
|
||||
return gIR->ir->CreateInsertValue(aggr, v, idx);
|
||||
return gIR->ir->CreateInsertValue(aggr, v, idx, name);
|
||||
}
|
||||
|
||||
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx)
|
||||
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name)
|
||||
{
|
||||
return gIR->ir->CreateExtractValue(aggr, idx);
|
||||
return gIR->ir->CreateExtractValue(aggr, idx, name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -68,8 +68,8 @@ void DtoStore(LLValue* src, LLValue* dst);
|
|||
void DtoAlignedStore(LLValue* src, LLValue* dst);
|
||||
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
||||
LLConstant* DtoBitCast(LLConstant* v, const LLType* t);
|
||||
LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx);
|
||||
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx);
|
||||
LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx, const char* name=0);
|
||||
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name=0);
|
||||
|
||||
// llvm::dyn_cast wrappers
|
||||
const LLPointerType* isaPointer(LLValue* v);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue