Example #1
0
File: optimize.c Project: jkm/dmd
Expression *EqualExp::optimize(int result, bool keepLvalue)
{
    //printf("EqualExp::optimize(result = %x) %s\n", result, toChars());
    e1 = e1->optimize(WANTvalue | (result & WANTinterpret));
    e2 = e2->optimize(WANTvalue | (result & WANTinterpret));

    Expression *e1 = fromConstInitializer(result, this->e1);
    Expression *e2 = fromConstInitializer(result, this->e2);

    Expression *e = Equal(op, type, e1, e2);
    if (e == EXP_CANT_INTERPRET)
        e = this;
    return e;
}
Example #2
0
Expression *CmpExp::optimize(int result)
{   Expression *e;

    //printf("CmpExp::optimize() %s\n", toChars());
    e1 = e1->optimize(WANTvalue | (result & WANTinterpret));
    e2 = e2->optimize(WANTvalue | (result & WANTinterpret));

    Expression *e1 = fromConstInitializer(result, this->e1);
    Expression *e2 = fromConstInitializer(result, this->e2);

    e = Cmp(op, type, e1, e2);
    if (e == EXP_CANT_INTERPRET)
	e = this;
    return e;
}
Example #3
0
Expression *SliceExp::optimize(int result)
{   Expression *e;

    //printf("SliceExp::optimize(result = %d) %s\n", result, toChars());
    e = this;
    e1 = e1->optimize(WANTvalue | (result & (WANTinterpret|WANTexpand)));
    if (!lwr)
    {   if (e1->op == TOKstring)
        {   // Convert slice of string literal into dynamic array
            Type *t = e1->type->toBasetype();
            if (t->nextOf())
                e = e1->castTo(NULL, t->nextOf()->arrayOf());
        }
        return e;
    }
    e1 = fromConstInitializer(result, e1);
    // We might know $ now
    setLengthVarIfKnown(lengthVar, e1);
    lwr = lwr->optimize(WANTvalue | (result & WANTinterpret));
    upr = upr->optimize(WANTvalue | (result & WANTinterpret));
    e = Slice(type, e1, lwr, upr);
    if (e == EXP_CANT_INTERPRET)
        e = this;
    //printf("-SliceExp::optimize() %s\n", e->toChars());
    return e;
}
Example #4
0
Expression *IndexExp::optimize(int result)
{   Expression *e;

    //printf("IndexExp::optimize(result = %d) %s\n", result, toChars());
    Expression *e1 = this->e1->optimize(
        WANTvalue | (result & (WANTinterpret| WANTexpand)));
    e1 = fromConstInitializer(result, e1);
    if (this->e1->op == TOKvar)
    {   VarExp *ve = (VarExp *)this->e1;
        if (ve->var->storage_class & STCmanifest)
        {   /* We generally don't want to have more than one copy of an
             * array literal, but if it's an enum we have to because the
             * enum isn't stored elsewhere. See Bugzilla 2559
             */
            this->e1 = e1;
        }
    }
    // We might know $ now
    setLengthVarIfKnown(lengthVar, e1);
    e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
    e = Index(type, e1, e2);
    if (e == EXP_CANT_INTERPRET)
        e = this;
    return e;
}
Example #5
0
Expression *VarExp::optimize(int result)
{
    if (result & WANTinterpret)
    {
        return fromConstInitializer(this);
    }
    return this;
}
Example #6
0
Expression *IndexExp::optimize(int result)
{   Expression *e;

    //printf("IndexExp::optimize(result = %d) %s\n", result, toChars());
    Expression *e1 = this->e1->optimize(WANTvalue | (result & WANTinterpret));
    e1 = fromConstInitializer(result, e1);
    e2 = e2->optimize(WANTvalue | (result & WANTinterpret));
    e = Index(type, e1, e2);
    if (e == EXP_CANT_INTERPRET)
	e = this;
    return e;
}
Example #7
0
Expression *CastExp::optimize(int result)
{
    //printf("CastExp::optimize(result = %d) %s\n", result, toChars());
    //printf("from %s to %s\n", type->toChars(), to->toChars());
    //printf("from %s\n", type->toChars());
    //printf("e1->type %s\n", e1->type->toChars());
    //printf("type = %p\n", type);
    assert(type);
    enum TOK op1 = e1->op;
#define X 0

    e1 = e1->optimize(result);
    e1 = fromConstInitializer(result, e1);

    if ((e1->op == TOKstring || e1->op == TOKarrayliteral) &&
	(type->ty == Tpointer || type->ty == Tarray) &&
	e1->type->nextOf()->size() == type->nextOf()->size()
       )
    {
	e1 = e1->castTo(NULL, type);
	if (X) printf(" returning1 %s\n", e1->toChars());
	return e1;
    }

    if (e1->op == TOKstructliteral &&
	e1->type->implicitConvTo(type) >= MATCHconst)
    {
	e1->type = type;
	if (X) printf(" returning2 %s\n", e1->toChars());
	return e1;
    }

    /* The first test here is to prevent infinite loops
     */
    if (op1 != TOKarrayliteral && e1->op == TOKarrayliteral)
	return e1->castTo(NULL, to);
    if (e1->op == TOKnull &&
	(type->ty == Tpointer || type->ty == Tclass || type->ty == Tarray))
    {
	e1->type = type;
	if (X) printf(" returning3 %s\n", e1->toChars());
	return e1;
    }

    if (result & WANTflags && type->ty == Tclass && e1->type->ty == Tclass)
    {
	// See if we can remove an unnecessary cast
	ClassDeclaration *cdfrom;
	ClassDeclaration *cdto;
	int offset;

	cdfrom = e1->type->isClassHandle();
	cdto   = type->isClassHandle();
	if (cdto->isBaseOf(cdfrom, &offset) && offset == 0)
	{
	    e1->type = type;
	    if (X) printf(" returning4 %s\n", e1->toChars());
	    return e1;
	}
    }

    // We can convert 'head const' to mutable
    if (to->constOf()->equals(e1->type->constOf()))
//    if (to->constConv(e1->type) >= MATCHconst)
    {
	e1->type = type;
	if (X) printf(" returning5 %s\n", e1->toChars());
	return e1;
    }

    Expression *e;

    if (e1->isConst())
    {
	if (e1->op == TOKsymoff)
	{
	    if (type->size() == e1->type->size() &&
		type->toBasetype()->ty != Tsarray)
	    {
		e1->type = type;
		return e1;
	    }
	    return this;
	}
	if (to->toBasetype()->ty == Tvoid)
	    e = this;
	else
	    e = Cast(type, to, e1);
    }
    else
	e = this;
    if (X) printf(" returning6 %s\n", e->toChars());
    return e;
#undef X
}
Example #8
0
Expression *VarExp::optimize(int result)
{
    return fromConstInitializer(result, this);
}
Example #9
0
Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
{
    //printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident->toChars(), flags);
    if (ident == Id::length || ident == Id::dollar)
    {   VarDeclaration **pvar;
        Expression *ce;

L1:

        if (td)
        {
            VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
            Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t);
            v->init = new ExpInitializer(0, e);
            v->storage_class |= STCstatic | STCconst;
            v->semantic(sc);
            return v;
        }

        if (type)
        {
            VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
            Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t);
            v->init = new ExpInitializer(0, e);
            v->storage_class |= STCstatic | STCconst;
            v->semantic(sc);
            return v;
        }

        if (exp->op == TOKindex)
        {
            IndexExp *ie = (IndexExp *)exp;

            pvar = &ie->lengthVar;
            ce = ie->e1;
        }
        else if (exp->op == TOKslice)
        {
            SliceExp *se = (SliceExp *)exp;

            pvar = &se->lengthVar;
            ce = se->e1;
        }
        else
            return NULL;

        if (ce->op == TOKtype)
        {
            Type *t = ((TypeExp *)ce)->type;
            if (t->ty == Ttuple)
            {   type = (TypeTuple *)t;
                goto L1;
            }
        }

        if (!*pvar)
        {
            VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);

            if (ce->op == TOKvar)
            {   // if ce is const, get its initializer
                ce = fromConstInitializer(WANTvalue | WANTinterpret, ce);
            }

            if (ce->op == TOKstring)
            {   /* It is for a string literal, so the
                * length will be a const.
                 */
                Expression *e = new IntegerExp(0, ((StringExp *)ce)->len, Type::tsize_t);
                v->init = new ExpInitializer(0, e);
                v->storage_class |= STCstatic | STCconst;
            }
            else if (ce->op == TOKarrayliteral)
            {   /* It is for an array literal, so the
                * length will be a const.
                 */
                Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t);
                v->init = new ExpInitializer(0, e);
                v->storage_class |= STCstatic | STCconst;
            }
            else if (ce->op == TOKtuple)
            {   /* It is for an expression tuple, so the
                * length will be a const.
                 */
                Expression *e = new IntegerExp(0, ((TupleExp *)ce)->exps->dim, Type::tsize_t);
                v->init = new ExpInitializer(0, e);
                v->storage_class |= STCstatic | STCconst;
            }
            *pvar = v;
        }
        (*pvar)->semantic(sc);
        return (*pvar);
    }
    return NULL;
}
Example #10
0
Expression *CastExp::optimize(int result)
{
    //printf("CastExp::optimize(result = %d) %s\n", result, toChars());
    //printf("from %s to %s\n", type->toChars(), to->toChars());
    //printf("from %s\n", type->toChars());
    //printf("e1->type %s\n", e1->type->toChars());
    //printf("type = %p\n", type);
    assert(type);
    enum TOK op1 = e1->op;

    e1 = e1->optimize(result);
    if (result & WANTinterpret)
        e1 = fromConstInitializer(e1);

    if ((e1->op == TOKstring || e1->op == TOKarrayliteral) &&
        (type->ty == Tpointer || type->ty == Tarray) &&
        type->next->equals(e1->type->next)
       )
    {
        // make a copy before adjusting type to avoid
        // messing up the type of an existing initializer
        e1 = e1->syntaxCopy();
        e1->type = type;
        return e1;
    }
    /* The first test here is to prevent infinite loops
     */
    if (op1 != TOKarrayliteral && e1->op == TOKarrayliteral)
        return e1->castTo(NULL, to);
    if (e1->op == TOKnull &&
        (type->ty == Tpointer || type->ty == Tclass))
    {
        e1->type = type;
        return e1;
    }

    if (result & WANTflags && type->ty == Tclass && e1->type->ty == Tclass)
    {
        // See if we can remove an unnecessary cast
        ClassDeclaration *cdfrom;
        ClassDeclaration *cdto;
        int offset;

        cdfrom = e1->type->isClassHandle();
        cdto   = type->isClassHandle();
        if (cdto->isBaseOf(cdfrom, &offset) && offset == 0)
        {
            e1->type = type;
            return e1;
        }
    }

    Expression *e;

    if (e1->isConst())
    {
        if (e1->op == TOKsymoff)
        {
            if (type->size() == e1->type->size() &&
                type->toBasetype()->ty != Tsarray)
            {
                e1->type = type;
                return e1;
            }
            return this;
        }
        if (to->toBasetype()->ty == Tvoid)
            e = this;
        else
            e = Cast(type, to, e1);
    }
    else
        e = this;
    return e;
}
Example #11
0
File: optimize.c Project: jkm/dmd
Expression *VarExp::optimize(int result, bool keepLvalue)
{
    return keepLvalue ? this : fromConstInitializer(result, this);
}