Resolving nested context for structs.

* * *
Another fix for nested structs
* * *
Yet another fix for nested structs
This commit is contained in:
Alexey Prokhin 2010-11-02 13:21:36 +03:00
parent e3afcf8a8d
commit 360a99caa9
7 changed files with 63 additions and 22 deletions

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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.

View file

@ -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

View file

@ -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);
}
//////////////////////////////////////////////////////////////////////////////////////////

View file

@ -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);