Exemple #1
0
Expression *scanVar(Dsymbol *s, InlineScanState *iss)
{
    //printf("scanVar(%s %s)\n", s->kind(), s->toPrettyChars());
    VarDeclaration *vd = s->isVarDeclaration();
    if (vd)
    {
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
            for (size_t i = 0; i < td->objects->dim; i++)
            {
                DsymbolExp *se = (DsymbolExp *)(*td->objects)[i];
                assert(se->op == TOKdsymbol);
                scanVar(se->s, iss);    // TODO
            }
        }
        else if (vd->init)
        {
            if (ExpInitializer *ie = vd->init->isExpInitializer())
            {
                Expression *e = ie->exp->inlineScan(iss);
                if (vd->init != ie)     // DeclareExp with vd appears in e
                    return e;
                ie->exp = e;
            }
        }
    }
    else
    {
        s->inlineScan();
    }
    return NULL;
}
Exemple #2
0
Expression *DeclarationExp::interpret(InterState *istate)
{
#if LOG
    printf("DeclarationExp::interpret() %s\n", toChars());
#endif
    Expression *e;
    VarDeclaration *v = declaration->isVarDeclaration();
    if (v)
    {
	Dsymbol *s = v->toAlias();
	if (s == v && !v->isStatic() && v->init)
	{
	    ExpInitializer *ie = v->init->isExpInitializer();
	    if (ie)
		e = ie->exp->interpret(istate);
	    else if (v->init->isVoidInitializer())
		e = NULL;
	}
#if V2
	else if (s == v && (v->isConst() || v->isInvariant()) && v->init)
#else
	else if (s == v && v->isConst() && v->init)
#endif
	{   e = v->init->toExpression();
	    if (!e)
		e = EXP_CANT_INTERPRET;
	    else if (!e->type)
		e->type = v->type;
	}
    }
    else if (declaration->isAttribDeclaration() ||
Exemple #3
0
void scanVar(Dsymbol *s, InlineScanState *iss)
{
    VarDeclaration *vd = s->isVarDeclaration();
    if (vd)
    {
	TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
	if (td)
	{
	    for (size_t i = 0; i < td->objects->dim; i++)
	    {   DsymbolExp *se = (DsymbolExp *)td->objects->data[i];
		assert(se->op == TOKdsymbol);
		scanVar(se->s, iss);
	    }
	}
	else
	{
	    // Scan initializer (vd->init)
	    if (vd->init)
	    {
		ExpInitializer *ie = vd->init->isExpInitializer();

		if (ie)
		{
		    ie->exp = ie->exp->inlineScan(iss);
		}
	    }
	}
    }
}
Exemple #4
0
int DeclarationExp::inlineCost3(InlineCostState *ics)
{   int cost = 0;
    VarDeclaration *vd;

    //printf("DeclarationExp::inlineCost3()\n");
    vd = declaration->isVarDeclaration();
    if (vd)
    {
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
#if 1
            return COST_MAX;    // finish DeclarationExp::doInline
#else
            for (size_t i = 0; i < td->objects->dim; i++)
            {   Object *o = (*td->objects)[i];
                if (o->dyncast() != DYNCAST_EXPRESSION)
                    return COST_MAX;
                Expression *eo = (Expression *)o;
                if (eo->op != TOKdsymbol)
                    return COST_MAX;
            }
            return td->objects->dim;
#endif
        }
        if (!ics->hdrscan && vd->isDataseg())
            return COST_MAX;
        cost += 1;

#if DMDV2
        if (vd->edtor)                  // if destructor required
            return COST_MAX;            // needs work to make this work
#endif
        // Scan initializer (vd->init)
        if (vd->init)
        {
            ExpInitializer *ie = vd->init->isExpInitializer();

            if (ie)
            {
                cost += expressionInlineCost(ie->exp, ics);
            }
        }
    }

    // These can contain functions, which when copied, get output twice.
    if (declaration->isStructDeclaration() ||
        declaration->isClassDeclaration() ||
        declaration->isFuncDeclaration() ||
        declaration->isTypedefDeclaration() ||
#if DMDV2
        declaration->isAttribDeclaration() ||
#endif
        declaration->isTemplateMixin())
        return COST_MAX;

    //printf("DeclarationExp::inlineCost3('%s')\n", toChars());
    return cost;
}
Exemple #5
0
Expression *DeclarationExp::doInline(InlineDoState *ids)
{   DeclarationExp *de = (DeclarationExp *)copy();
    VarDeclaration *vd;

    //printf("DeclarationExp::doInline(%s)\n", toChars());
    vd = declaration->isVarDeclaration();
    if (vd)
    {
#if 0
        // Need to figure this out before inlining can work for tuples
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
            for (size_t i = 0; i < td->objects->dim; i++)
            {   DsymbolExp *se = (DsymbolExp *)td->objects->data[i];
                assert(se->op == TOKdsymbol);
                se->s;
            }
            return st->objects->dim;
        }
#endif
        if (vd->isStatic() || vd->isConst())
            ;
        else
        {
            VarDeclaration *vto;

            vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init);
            *vto = *vd;
            vto->parent = ids->parent;
#if IN_DMD
            vto->csym = NULL;
            vto->isym = NULL;
#endif

            ids->from.push(vd);
            ids->to.push(vto);

            if (vd->init)
            {
                if (vd->init->isVoidInitializer())
                {
                    vto->init = new VoidInitializer(vd->init->loc);
                }
                else
                {
                    ExpInitializer *ie = vd->init->isExpInitializer();
                    assert(ie);
                    vto->init = new ExpInitializer(ie->loc, ie->exp->doInline(ids));
                }
            }
            de->declaration = (Dsymbol *) (void *)vto;
        }
    }
    /* This needs work, like DeclarationExp::toElem(), if we are
     * to handle TemplateMixin's. For now, we just don't inline them.
     */
    return de;
}
Exemple #6
0
int DeclarationExp::inlineCost(InlineCostState *ics)
{   int cost = 0;
    VarDeclaration *vd;

    //printf("DeclarationExp::inlineCost()\n");
    vd = declaration->isVarDeclaration();
    if (vd)
    {
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
#if 1
            return COST_MAX;    // finish DeclarationExp::doInline
#else
            for (size_t i = 0; i < td->objects->dim; i++)
            {   Object *o = (*td->objects)[i];
                if (o->dyncast() != DYNCAST_EXPRESSION)
                    return COST_MAX;
                Expression *eo = (Expression *)o;
                if (eo->op != TOKdsymbol)
                    return COST_MAX;
            }
            return td->objects->dim;
#endif
        }
        // This breaks on LDC too, since nested static variables have internal
        // linkage and thus can't be referenced from other objects.
        if (!ics->hdrscan && vd->isDataseg())
            return COST_MAX;
        cost += 1;

        // Scan initializer (vd->init)
        if (vd->init)
        {
            ExpInitializer *ie = vd->init->isExpInitializer();

            if (ie)
            {
                cost += ie->exp->inlineCost(ics);
            }
        }
    }

    // These can contain functions, which when copied, get output twice.
    // These break on LDC too, since nested static variables and functions have
    // internal linkage and thus can't be referenced from other objects.
    if (declaration->isStructDeclaration() ||
            declaration->isClassDeclaration() ||
            declaration->isFuncDeclaration() ||
            declaration->isTypedefDeclaration() ||
            declaration->isTemplateMixin())
        return COST_MAX;

    //printf("DeclarationExp::inlineCost('%s')\n", toChars());
    return cost;
}
Exemple #7
0
void scanVar(Dsymbol *s, InlineScanState *iss)
{
    VarDeclaration *vd = s->isVarDeclaration();
    if (vd)
    {
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
            for (size_t i = 0; i < td->objects->dim; i++)
            {   DsymbolExp *se = (DsymbolExp *)td->objects->tdata()[i];
                assert(se->op == TOKdsymbol);
                scanVar(se->s, iss);
            }
        }
        else
        {
            // Scan initializer (vd->init)
            if (vd->init)
            {
                ExpInitializer *ie = vd->init->isExpInitializer();

                if (ie)
                {
#if DMDV2
                    if (vd->type)
                    {   Type *tb = vd->type->toBasetype();
                        if (tb->ty == Tstruct)
                        {   StructDeclaration *sd = ((TypeStruct *)tb)->sym;
                            if (sd->cpctor)
                            {   /* The problem here is that if the initializer is a
                                 * function call that returns a struct S with a cpctor:
                                 *   S s = foo();
                                 * the postblit is done by the return statement in foo()
                                 * in s2ir.c, the intermediate code generator.
                                 * But, if foo() is inlined and now the code looks like:
                                 *   S s = x;
                                 * the postblit is not there, because such assignments
                                 * are rewritten as s.cpctor(&x) by the front end.
                                 * So, the inlining won't get the postblit called.
                                 * Work around by not inlining these cases.
                                 * A proper fix would be to move all the postblit
                                 * additions to the front end.
                                 */
                                return;
                            }
                        }
                    }
#endif
                    ie->exp = ie->exp->inlineScan(iss);
                }
            }
        }
    }
}
Exemple #8
0
    void visit(DeclarationExp *e)
    {
        //printf("DeclarationExp::inlineCost3()\n");
        VarDeclaration *vd = e->declaration->isVarDeclaration();
        if (vd)
        {
            TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
            if (td)
            {
                cost = COST_MAX;    // finish DeclarationExp::doInline
                return;
            }
            if (!hdrscan && vd->isDataseg())
            {
                cost = COST_MAX;
                return;
            }

            if (vd->edtor)
            {
                // if destructor required
                // needs work to make this work
                cost = COST_MAX;
                return;
            }
            // Scan initializer (vd->init)
            if (vd->_init)
            {
                ExpInitializer *ie = vd->_init->isExpInitializer();

                if (ie)
                {
                    expressionInlineCost(ie->exp);
                }
            }
            cost += 1;
        }

        // These can contain functions, which when copied, get output twice.
        if (e->declaration->isStructDeclaration() ||
            e->declaration->isClassDeclaration() ||
            e->declaration->isFuncDeclaration() ||
            e->declaration->isAttribDeclaration() ||
            e->declaration->isTemplateMixin())
        {
            cost = COST_MAX;
            return;
        }

        //printf("DeclarationExp::inlineCost3('%s')\n", toChars());
    }
Exemple #9
0
Expression *DeclarationExp::doInline(InlineDoState *ids)
{
    //printf("DeclarationExp::doInline(%s)\n", toChars());
    VarDeclaration *vd = declaration->isVarDeclaration();
    if (vd)
    {
#if 0
        // Need to figure this out before inlining can work for tuples
        TupleDeclaration *td = vd->toAlias()->isTupleDeclaration();
        if (td)
        {
            for (size_t i = 0; i < td->objects->dim; i++)
            {   DsymbolExp *se = (*td->objects)[i];
                assert(se->op == TOKdsymbol);
                se->s;
            }
            return st->objects->dim;
        }
#endif
        if (vd->isStatic())
            ;
        else
        {
            VarDeclaration *vto;
            if (ids->fd && vd == ids->fd->nrvo_var)
            {
                for (size_t i = 0; i < ids->from.dim; i++)
                {
                    if (vd == ids->from[i])
                    {
                        vto = (VarDeclaration *)ids->to[i];
                        Expression *e;
                        if (vd->init && !vd->init->isVoidInitializer())
                        {
                            e = vd->init->toExpression();
                            assert(e);
                            e = e->doInline(ids);
                        }
                        else
                            e = new IntegerExp(vd->init->loc, 0, Type::tint32);
                        return e;
                    }
                }
            }
            vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init);
            memcpy((void *)vto, (void *)vd, sizeof(VarDeclaration));
            vto->parent = ids->parent;
            vto->csym = NULL;
            vto->isym = NULL;

            ids->from.push(vd);
            ids->to.push(vto);

        L1:
            if (vd->init)
            {
                if (vd->init->isVoidInitializer())
                {
                    vto->init = new VoidInitializer(vd->init->loc);
                }
                else
                {
                    Expression *e = vd->init->toExpression();
                    assert(e);
                    vto->init = new ExpInitializer(e->loc, e->doInline(ids));
                }
            }
            DeclarationExp *de = (DeclarationExp *)copy();
            de->declaration = (Dsymbol *) (void *)vto;
            return de;
        }
    }
    /* This needs work, like DeclarationExp::toElem(), if we are
     * to handle TemplateMixin's. For now, we just don't inline them.
     */
    return Expression::doInline(ids);
}