diff --git a/gen/functions.cpp b/gen/functions.cpp index 19a627d6..82bb67e7 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -725,13 +725,6 @@ void DtoDefineFunction(FuncDeclaration* fd) fd->vthis->ir.irParam->isVthis = true; DtoDwarfLocalVariable(thismem, fd->vthis); - - #if DMDV1 - if (fd->vthis->nestedref) - { - fd->nestedVars.insert(fd->vthis); - } - #endif } // give the 'nestArg' storage @@ -790,12 +783,18 @@ void DtoDefineFunction(FuncDeclaration* fd) } } -// need result variable? (nested) + #if DMDV1 + // need result variable? (nested) if (fd->vresult && fd->vresult->nestedref) { Logger::println("nested vresult value: %s", fd->vresult->toChars()); fd->nestedVars.insert(fd->vresult); } + + if (fd->vthis && fd->vthis->nestedref && !fd->nestedVars.empty()) { + Logger::println("nested vthis value: %s", fd->vthis->toChars()); + fd->nestedVars.insert(fd->vthis); + } #endif FuncGen fg; diff --git a/gen/nested.cpp b/gen/nested.cpp index 7d544875..9d713698 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -134,11 +134,22 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd, bool byref) LLValue* val = irfunc->thisArg; if (cd->isClassDeclaration()) val = DtoLoad(val); + ctx = DtoLoad(DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis")); #else ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); LLValue* val = DtoLoad(irfunc->thisArg); + ctx = DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis"); + + if (!irfunc->frameType && vd->isThisDeclaration()) + { + // If the only "nested" variable is the outer this pointer, we don't + // emit a normal context, but just store the this pointer - see + // GitHub #127. + return new DVarValue(astype, vd, ctx); + } + + ctx = DtoLoad(ctx); #endif - ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis")); } else if (irfunc->nestedVar) { ctx = irfunc->nestedVar; @@ -311,12 +322,14 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym) #if DMDV2 AggregateDeclaration* ad = irfunc->decl->isMember2(); val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg; + if (!ad || !ad->vthis) + return llvm::UndefValue::get(getVoidPtrType()); #else ClassDeclaration* ad = irfunc->decl->isMember2()->isClassDeclaration(); val = DtoLoad(irfunc->thisArg); -#endif if (!ad || !ad->vthis) - return llvm::UndefValue::get(getVoidPtrType()); + return val; +#endif val = DtoLoad(DtoGEPi(val, 0,ad->vthis->ir.irField->index, ".vthis")); } else