elem *setEthis(Loc loc, IRState *irs, elem *ey, AggregateDeclaration *ad) { elem *ethis; FuncDeclaration *thisfd = irs->getFunc(); int offset = 0; Dsymbol *cdp = ad->toParent2(); // class/func we're nested in //printf("setEthis(ad = %s, cdp = %s, thisfd = %s)\n", ad->toChars(), cdp->toChars(), thisfd->toChars()); if (cdp == thisfd) { /* Class we're new'ing is a local class in this function: * void thisfd() { class ad { } } */ if (irs->sclosure) ethis = el_var(irs->sclosure); else if (irs->sthis) { if (thisfd->hasNestedFrameRefs()) { ethis = el_ptr(irs->sthis); } else ethis = el_var(irs->sthis); } else { ethis = el_long(TYnptr, 0); if (thisfd->hasNestedFrameRefs()) { ethis->Eoper = OPframeptr; } } } else if (thisfd->vthis && (cdp == thisfd->toParent2() || (cdp->isClassDeclaration() && cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) ) ) ) { /* Class we're new'ing is at the same level as thisfd */ assert(offset == 0); // BUG: should handle this case ethis = el_var(irs->sthis); } else { ethis = getEthis(loc, irs, ad->toParent2()); ethis = el_una(OPaddr, TYnptr, ethis); } ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, ad->vthis->offset)); ey = el_una(OPind, TYnptr, ey); ey = el_bin(OPeq, TYnptr, ey, ethis); return ey; }
/************************* * Initialize the hidden aggregate member, vthis, with * the context pointer. * Returns: * *(ey + ad.vthis.offset) = this; */ elem *setEthis(Loc loc, IRState *irs, elem *ey, AggregateDeclaration *ad) { elem *ethis; FuncDeclaration *thisfd = irs->getFunc(); int offset = 0; Dsymbol *adp = ad->toParent2(); // class/func we're nested in //printf("[%s] setEthis(ad = %s, adp = %s, thisfd = %s)\n", loc.toChars(), ad->toChars(), adp->toChars(), thisfd->toChars()); if (adp == thisfd) { ethis = getEthis(loc, irs, ad); } else if (thisfd->vthis && (adp == thisfd->toParent2() || (adp->isClassDeclaration() && adp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) ) ) ) { /* Class we're new'ing is at the same level as thisfd */ assert(offset == 0); // BUG: should handle this case ethis = el_var(irs->sthis); } else { ethis = getEthis(loc, irs, adp); FuncDeclaration *fdp = adp->isFuncDeclaration(); if (fdp && fdp->hasNestedFrameRefs()) ethis = el_una(OPaddr, TYnptr, ethis); } ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, ad->vthis->offset)); ey = el_una(OPind, TYnptr, ey); ey = el_bin(OPeq, TYnptr, ey, ethis); return ey; }