diff --git a/gen/classes.cpp b/gen/classes.cpp index 7a0b5ab51e..8077f7235b 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -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 diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 0ac4e9c10a..1bc4a4c835 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -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 diff --git a/gen/nested.cpp b/gen/nested.cpp index 9b493e3f36..1bd252c1f8 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -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) { diff --git a/gen/nested.h b/gen/nested.h index 19d2b92d83..088bafa4d2 100644 --- a/gen/nested.h +++ b/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. diff --git a/gen/toir.cpp b/gen/toir.cpp index 519e2aab3e..a12021ff40 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -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 diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 4fe8cfd507..7a4b967c98 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -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); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/tollvm.h b/gen/tollvm.h index 6a6fc53801..575bb9812e 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -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);