Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 640

Show
Ignore:
Timestamp:
08/28/10 19:24:44 (14 years ago)
Author:
walter
Message:

Issue 4278 - allow inlining of super calls (undo limitations of bug3500's fix)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/e2ir.c

    r621 r640  
    30513051    elem *ec; 
    30523052    int directcall; 
    30533053    FuncDeclaration *fd; 
    30543054    Type *t1 = e1->type->toBasetype(); 
    30553055    Type *ectype = t1; 
    30563056 
    30573057    elem *ehidden = irs->ehidden; 
    30583058    irs->ehidden = NULL; 
    30593059 
    30603060    directcall = 0; 
    30613061    fd = NULL; 
    30623062    if (e1->op == TOKdotvar && t1->ty != Tdelegate) 
    30633063    {   DotVarExp *dve = (DotVarExp *)e1; 
    30643064 
    30653065        fd = dve->var->isFuncDeclaration(); 
    30663066        Expression *ex = dve->e1; 
    30673067        while (1) 
    30683068        { 
    30693069            switch (ex->op) 
    30703070            { 
    3071                 case TOKsuper:          // super.member() calls directly 
     3071                case TOKsuper:          // super(args) ctor calls 
    30723072                case TOKdottype:        // type.member() calls directly 
    30733073                    directcall = 1; 
    30743074                    break; 
    30753075 
    30763076                case TOKcast: 
    30773077                    ex = ((CastExp *)ex)->e1; 
    30783078                    continue; 
    30793079 
    30803080                default: 
    30813081                    //ex->dump(0); 
    30823082                    break; 
    30833083            } 
    30843084            break; 
    30853085        } 
    30863086        ec = dve->e1->toElem(irs); 
    30873087        ectype = dve->e1->type->toBasetype(); 
    30883088    } 
    30893089    else if (e1->op == TOKvar) 
    30903090    { 
    30913091        fd = ((VarExp *)e1)->var->isFuncDeclaration(); 
  • branches/dmd-1.x/src/expression.c

    r639 r640  
    61676167        return this;            // semantic() already run 
    61686168#if 0 
    61696169    if (arguments && arguments->dim) 
    61706170    { 
    61716171        Expression *earg = (Expression *)arguments->data[0]; 
    61726172        earg->print(); 
    61736173        if (earg->type) earg->type->print(); 
    61746174    } 
    61756175#endif 
    61766176 
    61776177    if (e1->op == TOKdelegate) 
    61786178    {   DelegateExp *de = (DelegateExp *)e1; 
    61796179 
    61806180        e1 = new DotVarExp(de->loc, de->e1, de->func); 
    61816181        return semantic(sc); 
    61826182    } 
    61836183 
    61846184    /* Transform: 
    61856185     *  array.id(args) into id(array,args) 
    61866186     *  aa.remove(arg) into delete aa[arg] 
     6187     *  super.id(args) into parent.id(args) 
    61876188     */ 
    61886189    if (e1->op == TOKdot) 
    61896190    { 
    61906191        // BUG: we should handle array.a.b.c.e(args) too 
    61916192 
    61926193        DotIdExp *dotid = (DotIdExp *)(e1); 
    61936194        dotid->e1 = dotid->e1->semantic(sc); 
    61946195        assert(dotid->e1); 
    61956196        if (dotid->e1->type) 
    61966197        { 
    61976198            TY e1ty = dotid->e1->type->toBasetype()->ty; 
    61986199            if (e1ty == Taarray && dotid->ident == Id::remove) 
    61996200            { 
    62006201                if (!arguments || arguments->dim != 1) 
    62016202                {   error("expected key as argument to aa.remove()"); 
    62026203                    goto Lagain; 
    62036204                } 
    62046205                Expression *key = (Expression *)arguments->data[0]; 
    62056206                key = key->semantic(sc); 
    62066207                key = resolveProperties(sc, key); 
    62076208                key->rvalue(); 
    62086209 
    62096210                TypeAArray *taa = (TypeAArray *)dotid->e1->type->toBasetype(); 
    62106211                key = key->implicitCastTo(sc, taa->index); 
    62116212                key = key->implicitCastTo(sc, taa->key); 
    62126213 
    62136214                return new RemoveExp(loc, dotid->e1, key); 
    62146215            } 
    62156216            else if (e1ty == Tarray || e1ty == Tsarray || e1ty == Taarray) 
    62166217            { 
    62176218                if (!arguments) 
    62186219                    arguments = new Expressions(); 
    62196220                arguments->shift(dotid->e1); 
    62206221#if DMDV2 
    62216222                e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident); 
    62226223#else 
    62236224                e1 = new IdentifierExp(dotid->loc, dotid->ident); 
    62246225#endif 
     6226            } 
     6227            else if (e1ty == Tclass && dotid->e1->op == TOKsuper) 
     6228            { 
     6229                // rewrite super.id into this.baseclass.id 
     6230 
     6231                FuncDeclaration *fd = hasThis(sc); 
     6232 
     6233                Dsymbol *s = fd->toParent(); 
     6234                while (s && s->isTemplateInstance()) 
     6235                    s = s->toParent(); 
     6236 
     6237                ClassDeclaration *cd = s->isClassDeclaration(); 
     6238                Expression *dte = new DotTypeExp(dotid->loc, new ThisExp(dotid->loc), cd->baseClass); 
     6239                e1 = new DotIdExp(dotid->loc, dte, dotid->ident); 
    62256240            } 
    62266241        } 
    62276242    } 
    62286243 
    62296244#if 1 
    62306245    /* This recognizes: 
    62316246     *  foo!(tiargs)(funcargs) 
    62326247     */ 
    62336248    if (e1->op == TOKimport && !e1->type) 
    62346249    {   ScopeExp *se = (ScopeExp *)e1; 
    62356250        TemplateInstance *ti = se->sds->isTemplateInstance(); 
    62366251        if (ti && !ti->semanticRun) 
    62376252        { 
    62386253            /* Attempt to instantiate ti. If that works, go with it. 
    62396254             * If not, go with partial explicit specialization. 
    62406255             */ 
    62416256            ti->semanticTiargs(sc); 
    62426257            unsigned errors = global.errors; 
    62436258            global.gag++; 
    62446259            ti->semantic(sc); 
     
    64786493            if (e1->op == TOKdotvar) 
    64796494                dve->var = f; 
    64806495            else 
    64816496                e1 = new DotVarExp(loc, dte->e1, f); 
    64826497            e1->type = f->type; 
    64836498 
    64846499            // See if we need to adjust the 'this' pointer 
    64856500            AggregateDeclaration *ad = f->isThis(); 
    64866501            ClassDeclaration *cd = ue->e1->type->isClassHandle(); 
    64876502            if (ad && cd && ad->isClassDeclaration() && ad != cd && 
    64886503                ue->e1->op != TOKsuper) 
    64896504            { 
    64906505                ue->e1 = ue->e1->castTo(sc, ad->type); //new CastExp(loc, ue->e1, ad->type); 
    64916506                ue->e1 = ue->e1->semantic(sc); 
    64926507            } 
    64936508        } 
    64946509        t1 = e1->type; 
    64956510    } 
    64966511    else if (e1->op == TOKsuper) 
    64976512    { 
     6513        // TODO: rewrite this to lower super(...) to baseclass(...) ? 
    64986514        // Base class constructor call 
    64996515        ClassDeclaration *cd = NULL; 
    65006516 
    65016517        if (sc->func) 
    65026518            cd = sc->func->toParent()->isClassDeclaration(); 
    65036519        if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration()) 
    65046520        { 
    65056521            error("super class constructor call must be in a constructor"); 
    65066522            type = Type::terror; 
    65076523            return this; 
    65086524        } 
    65096525        else 
    65106526        { 
    65116527            f = cd->baseClass->ctor; 
    65126528            if (!f) 
    65136529            {   error("no super class constructor for %s", cd->baseClass->toChars()); 
    65146530                type = Type::terror; 
    65156531                return this; 
    65166532            } 
    65176533            else 
  • branches/dmd-1.x/src/inline.c

    r505 r640  
    264264    return cost; 
    265265} 
    266266 
    267267int UnaExp::inlineCost(InlineCostState *ics) 
    268268{ 
    269269    return 1 + e1->inlineCost(ics); 
    270270} 
    271271 
    272272int AssertExp::inlineCost(InlineCostState *ics) 
    273273{ 
    274274    return 1 + e1->inlineCost(ics) + (msg ? msg->inlineCost(ics) : 0); 
    275275} 
    276276 
    277277int BinExp::inlineCost(InlineCostState *ics) 
    278278{ 
    279279    return 1 + e1->inlineCost(ics) + e2->inlineCost(ics); 
    280280} 
    281281 
    282282int CallExp::inlineCost(InlineCostState *ics) 
    283283{ 
    284     // Bugzilla 3500: super.func() calls must be devirtualized, and the inliner 
    285     // can't handle that at present. 
    286     if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKsuper) 
    287         return COST_MAX; 
    288  
    289284    return 1 + e1->inlineCost(ics) + arrayInlineCost(ics, arguments); 
    290285} 
    291286 
    292287int SliceExp::inlineCost(InlineCostState *ics) 
    293288{   int cost; 
    294289 
    295290    cost = 1 + e1->inlineCost(ics); 
    296291    if (lwr) 
    297292        cost += lwr->inlineCost(ics); 
    298293    if (upr) 
    299294        cost += upr->inlineCost(ics); 
    300295    return cost; 
    301296} 
    302297 
    303298int ArrayExp::inlineCost(InlineCostState *ics) 
    304299{ 
    305300    return 1 + e1->inlineCost(ics) + arrayInlineCost(ics, arguments); 
    306301} 
    307302 
    308303 
  • trunk/src/e2ir.c

    r621 r640  
    33453345    int directcall; 
    33463346    FuncDeclaration *fd; 
    33473347    Type *t1 = e1->type->toBasetype(); 
    33483348    Type *ectype = t1; 
    33493349    elem *eeq = NULL; 
    33503350 
    33513351    elem *ehidden = irs->ehidden; 
    33523352    irs->ehidden = NULL; 
    33533353 
    33543354    directcall = 0; 
    33553355    fd = NULL; 
    33563356    if (e1->op == TOKdotvar && t1->ty != Tdelegate) 
    33573357    {   DotVarExp *dve = (DotVarExp *)e1; 
    33583358 
    33593359        fd = dve->var->isFuncDeclaration(); 
    33603360        Expression *ex = dve->e1; 
    33613361        while (1) 
    33623362        { 
    33633363            switch (ex->op) 
    33643364            { 
    3365                 case TOKsuper:          // super.member() calls directly 
     3365                case TOKsuper:          // super(args) ctor calls 
    33663366                case TOKdottype:        // type.member() calls directly 
    33673367                    directcall = 1; 
    33683368                    break; 
    33693369 
    33703370                case TOKcast: 
    33713371                    ex = ((CastExp *)ex)->e1; 
    33723372                    continue; 
    33733373 
    33743374                default: 
    33753375                    //ex->dump(0); 
    33763376                    break; 
    33773377            } 
    33783378            break; 
    33793379        } 
    33803380        ec = dve->e1->toElem(irs); 
    33813381        ectype = dve->e1->type->toBasetype(); 
    33823382    } 
    33833383    else if (e1->op == TOKvar) 
    33843384    { 
    33853385        fd = ((VarExp *)e1)->var->isFuncDeclaration(); 
  • trunk/src/expression.c

    r639 r640  
    65086508        return this;            // semantic() already run 
    65096509#if 0 
    65106510    if (arguments && arguments->dim) 
    65116511    { 
    65126512        Expression *earg = (Expression *)arguments->data[0]; 
    65136513        earg->print(); 
    65146514        if (earg->type) earg->type->print(); 
    65156515    } 
    65166516#endif 
    65176517 
    65186518    if (e1->op == TOKdelegate) 
    65196519    {   DelegateExp *de = (DelegateExp *)e1; 
    65206520 
    65216521        e1 = new DotVarExp(de->loc, de->e1, de->func); 
    65226522        return semantic(sc); 
    65236523    } 
    65246524 
    65256525    /* Transform: 
    65266526     *  array.id(args) into .id(array,args) 
    65276527     *  aa.remove(arg) into delete aa[arg] 
     6528     *  super.id(args) into parent.id(args) 
    65286529     */ 
    65296530    if (e1->op == TOKdot) 
    65306531    { 
    65316532        // BUG: we should handle array.a.b.c.e(args) too 
    65326533 
    65336534        DotIdExp *dotid = (DotIdExp *)(e1); 
    65346535        dotid->e1 = dotid->e1->semantic(sc); 
    65356536        assert(dotid->e1); 
    65366537        if (dotid->e1->type) 
    65376538        { 
    65386539            TY e1ty = dotid->e1->type->toBasetype()->ty; 
    65396540            if (e1ty == Taarray && dotid->ident == Id::remove) 
    65406541            { 
    65416542                if (!arguments || arguments->dim != 1) 
    65426543                {   error("expected key as argument to aa.remove()"); 
    65436544                    return new ErrorExp(); 
    65446545                } 
    65456546                Expression *key = (Expression *)arguments->data[0]; 
    65466547                key = key->semantic(sc); 
    65476548                key = resolveProperties(sc, key); 
     
    65556556            else if (e1ty == Tarray || e1ty == Tsarray || 
    65566557                     (e1ty == Taarray && dotid->ident != Id::apply && dotid->ident != Id::applyReverse)) 
    65576558            { 
    65586559                if (e1ty == Taarray) 
    65596560                {   TypeAArray *taa = (TypeAArray *)dotid->e1->type->toBasetype(); 
    65606561                    assert(taa->ty == Taarray); 
    65616562                    StructDeclaration *sd = taa->getImpl(); 
    65626563                    Dsymbol *s = sd->search(0, dotid->ident, 2); 
    65636564                    if (s) 
    65646565                        goto L2; 
    65656566                } 
    65666567                if (!arguments) 
    65676568                    arguments = new Expressions(); 
    65686569                arguments->shift(dotid->e1); 
    65696570#if DMDV2 
    65706571                e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident); 
    65716572#else 
    65726573                e1 = new IdentifierExp(dotid->loc, dotid->ident); 
    65736574#endif 
    65746575            } 
     6576            else if (e1ty == Tclass && dotid->e1->op == TOKsuper) 
     6577            { 
     6578                // rewrite super.id into this.baseclass.id 
     6579 
     6580                FuncDeclaration *fd = hasThis(sc); 
     6581 
     6582                Dsymbol *s = fd->toParent(); 
     6583                while (s && s->isTemplateInstance()) 
     6584                    s = s->toParent(); 
     6585 
     6586                ClassDeclaration *cd = s->isClassDeclaration(); 
     6587                Expression *dte = new DotTypeExp(dotid->loc, new ThisExp(dotid->loc), cd->baseClass); 
     6588                e1 = new DotIdExp(dotid->loc, dte, dotid->ident); 
     6589            } 
     6590 
    65756591         L2: 
    65766592            ; 
    65776593        } 
    65786594    } 
    65796595 
    65806596#if 1 
    65816597    /* This recognizes: 
    65826598     *  foo!(tiargs)(funcargs) 
    65836599     */ 
    65846600    if (e1->op == TOKimport && !e1->type) 
    65856601    {   ScopeExp *se = (ScopeExp *)e1; 
    65866602        TemplateInstance *ti = se->sds->isTemplateInstance(); 
    65876603        if (ti && !ti->semanticRun) 
    65886604        { 
    65896605            /* Attempt to instantiate ti. If that works, go with it. 
    65906606             * If not, go with partial explicit specialization. 
    65916607             */ 
    65926608            ti->semanticTiargs(sc); 
    65936609            if (ti->needsTypeInference(sc)) 
    65946610            { 
     
    69226938                {   VarExp *v = (VarExp *)ue->e1; 
    69236939                    if (v->var->storage_class & STCfinal) 
    69246940                        error("cannot call mutable method on final struct"); 
    69256941                } 
    69266942            } 
    69276943 
    69286944            // See if we need to adjust the 'this' pointer 
    69296945            AggregateDeclaration *ad = f->isThis(); 
    69306946            ClassDeclaration *cd = ue->e1->type->isClassHandle(); 
    69316947            if (ad && cd && ad->isClassDeclaration() && ad != cd && 
    69326948                ue->e1->op != TOKsuper) 
    69336949            { 
    69346950                ue->e1 = ue->e1->castTo(sc, ad->type); //new CastExp(loc, ue->e1, ad->type); 
    69356951                ue->e1 = ue->e1->semantic(sc); 
    69366952            } 
    69376953        } 
    69386954        t1 = e1->type; 
    69396955    } 
    69406956    else if (e1->op == TOKsuper) 
    69416957    { 
     6958        // TODO: rewrite this to lower super(...) to baseclass(...) ? 
    69426959        // Base class constructor call 
    69436960        ClassDeclaration *cd = NULL; 
    69446961 
    69456962        if (sc->func) 
    69466963            cd = sc->func->toParent()->isClassDeclaration(); 
    69476964        if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration()) 
    69486965        { 
    69496966            error("super class constructor call must be in a constructor"); 
    69506967            return new ErrorExp(); 
    69516968        } 
    69526969        else 
    69536970        { 
    69546971            if (!cd->baseClass->ctor) 
    69556972            {   error("no super class constructor for %s", cd->baseClass->toChars()); 
    69566973                return new ErrorExp(); 
    69576974            } 
    69586975            else 
    69596976            { 
    69606977                if (!sc->intypeof) 
    69616978                { 
  • trunk/src/inline.c

    r520 r640  
    265265    return cost; 
    266266} 
    267267 
    268268int UnaExp::inlineCost(InlineCostState *ics) 
    269269{ 
    270270    return 1 + e1->inlineCost(ics); 
    271271} 
    272272 
    273273int AssertExp::inlineCost(InlineCostState *ics) 
    274274{ 
    275275    return 1 + e1->inlineCost(ics) + (msg ? msg->inlineCost(ics) : 0); 
    276276} 
    277277 
    278278int BinExp::inlineCost(InlineCostState *ics) 
    279279{ 
    280280    return 1 + e1->inlineCost(ics) + e2->inlineCost(ics); 
    281281} 
    282282 
    283283int CallExp::inlineCost(InlineCostState *ics) 
    284284{ 
    285     // Bugzilla 3500: super.func() calls must be devirtualized, and the inliner 
    286     // can't handle that at present. 
    287     if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKsuper) 
    288         return COST_MAX; 
    289  
    290285    return 1 + e1->inlineCost(ics) + arrayInlineCost(ics, arguments); 
    291286} 
    292287 
    293288int SliceExp::inlineCost(InlineCostState *ics) 
    294289{   int cost; 
    295290 
    296291    cost = 1 + e1->inlineCost(ics); 
    297292    if (lwr) 
    298293        cost += lwr->inlineCost(ics); 
    299294    if (upr) 
    300295        cost += upr->inlineCost(ics); 
    301296    return cost; 
    302297} 
    303298 
    304299int ArrayExp::inlineCost(InlineCostState *ics) 
    305300{ 
    306301    return 1 + e1->inlineCost(ics) + arrayInlineCost(ics, arguments); 
    307302} 
    308303 
    309304