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
|
// set the context for nested classes
|
||||||
else if (tc->sym->isNested() && tc->sym->vthis)
|
else if (tc->sym->isNested() && tc->sym->vthis)
|
||||||
{
|
{
|
||||||
Logger::println("Resolving nested context");
|
DtoResolveNestedContext(loc, tc->sym, mem);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// call constructor
|
// call constructor
|
||||||
|
|
|
@ -364,10 +364,16 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
||||||
if (!t->equals(t2)) {
|
if (!t->equals(t2)) {
|
||||||
// FIXME: use 'rhs' for something !?!
|
// FIXME: use 'rhs' for something !?!
|
||||||
DtoAggrZeroInit(lhs->getLVal());
|
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 {
|
else {
|
||||||
DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
|
DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (t->ty == Tarray) {
|
else if (t->ty == Tarray) {
|
||||||
// lhs is slice
|
// 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)
|
LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
||||||
{
|
{
|
||||||
Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
|
Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
|
||||||
|
@ -234,11 +252,16 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
||||||
// or just have a this argument
|
// or just have a this argument
|
||||||
else if (irfunc->thisArg)
|
else if (irfunc->thisArg)
|
||||||
{
|
{
|
||||||
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
|
#if DMDV2
|
||||||
if (!cd || !cd->vthis)
|
AggregateDeclaration* ad = irfunc->decl->isMember2();
|
||||||
return llvm::UndefValue::get(getVoidPtrType());
|
val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg;
|
||||||
|
#else
|
||||||
|
ClassDeclaration* ad = irfunc->decl->isMember2()->isClassDeclaration();
|
||||||
val = DtoLoad(irfunc->thisArg);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -477,10 +500,19 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
||||||
assert(irfunction->thisArg);
|
assert(irfunction->thisArg);
|
||||||
assert(fd->isMember2());
|
assert(fd->isMember2());
|
||||||
LLValue* thisval = DtoLoad(irfunction->thisArg);
|
LLValue* thisval = DtoLoad(irfunction->thisArg);
|
||||||
|
#if DMDV2
|
||||||
|
AggregateDeclaration* cd = fd->isMember2();
|
||||||
|
#else
|
||||||
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
|
ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
|
||||||
|
#endif
|
||||||
assert(cd);
|
assert(cd);
|
||||||
assert(cd->vthis);
|
assert(cd->vthis);
|
||||||
Logger::println("Indexing to 'this'");
|
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"));
|
src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
|
||||||
}
|
}
|
||||||
if (depth > 1) {
|
if (depth > 1) {
|
||||||
|
|
12
gen/nested.h
12
gen/nested.h
|
@ -4,6 +4,7 @@
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "gen/dvalue.h"
|
#include "gen/dvalue.h"
|
||||||
|
#include "gen/llvm.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Nested variable and context helpers
|
// Nested variable and context helpers
|
||||||
|
@ -15,8 +16,15 @@ void DtoCreateNestedContext(FuncDeclaration* fd);
|
||||||
/// Allocate space for variable accessed from nested function.
|
/// Allocate space for variable accessed from nested function.
|
||||||
void DtoNestedInit(VarDeclaration* vd);
|
void DtoNestedInit(VarDeclaration* vd);
|
||||||
|
|
||||||
/// Gets the context value for a call to a nested function or newing a nested
|
/// Resolves the nested context for classes and structs with arbitrary nesting.
|
||||||
/// class 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);
|
llvm::Value* DtoNestedContext(Loc loc, Dsymbol* sym);
|
||||||
|
|
||||||
/// Gets the DValue of a nested variable with arbitrary nesting.
|
/// Gets the DValue of a nested variable with arbitrary nesting.
|
||||||
|
|
|
@ -1694,6 +1694,10 @@ DValue* NewExp::toElem(IRState* p)
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
DtoAggrCopy(mem, ts->sym->ir.irStruct->getInitSymbol());
|
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);
|
return new DImValue(type, mem);
|
||||||
}
|
}
|
||||||
// new basic type
|
// 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);
|
void DtoAlignedStore(LLValue* src, LLValue* dst);
|
||||||
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
|
||||||
LLConstant* DtoBitCast(LLConstant* v, const LLType* t);
|
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=0);
|
||||||
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx);
|
LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name=0);
|
||||||
|
|
||||||
// llvm::dyn_cast wrappers
|
// llvm::dyn_cast wrappers
|
||||||
const LLPointerType* isaPointer(LLValue* v);
|
const LLPointerType* isaPointer(LLValue* v);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue