Beispiel #1
0
Expression *expandVar(int result, VarDeclaration *v)
{
    //printf("expandVar(result = %d, v = %p, %s)\n", result, v, v ? v->toChars() : "null");

    Expression *e = NULL;
    if (!v)
        return e;
    if (!v->originalType && v->scope)   // semantic() not yet run
        v->semantic (v->scope);

    if (v->isConst() || v->isImmutable() || v->storage_class & STCmanifest)
    {
        if (!v->type)
        {
            //error("ICE");
            return e;
        }
        Type *tb = v->type->toBasetype();
        if (result & WANTinterpret ||
            v->storage_class & STCmanifest ||
            v->type->toBasetype()->isscalar() ||
            ((result & WANTexpand) && (tb->ty != Tsarray && tb->ty != Tstruct))
           )
        {
            if (v->init)
            {
                if (v->inuse)
                {   if (v->storage_class & STCmanifest)
                        v->error("recursive initialization of constant");
                    goto L1;
                }
                Expression *ei = v->init->toExpression();
                if (!ei)
                {   if (v->storage_class & STCmanifest)
                        v->error("enum cannot be initialized with %s", v->init->toChars());
                    goto L1;
                }
                if (ei->op == TOKconstruct || ei->op == TOKblit)
                {   AssignExp *ae = (AssignExp *)ei;
                    ei = ae->e2;
                    if (result & WANTinterpret)
                    {
                        v->inuse++;
                        ei = ei->optimize(result);
                        v->inuse--;
                    }
                    else if (ei->isConst() != 1 && ei->op != TOKstring)
                        goto L1;

                    if (ei->type == v->type)
                    {   // const variable initialized with const expression
                    }
                    else if (ei->implicitConvTo(v->type) >= MATCHconst)
                    {   // const var initialized with non-const expression
                        ei = ei->implicitCastTo(0, v->type);
                        ei = ei->semantic(0);
                    }
                    else
                        goto L1;
                }
                if (v->scope)
                {
                    v->inuse++;
                    e = ei->syntaxCopy();
                    e = e->semantic(v->scope);
                    e = e->implicitCastTo(v->scope, v->type);
                    // enabling this line causes test22 in test suite to fail
                    //ei->type = e->type;
                    v->scope = NULL;
                    v->inuse--;
                }
                else if (!ei->type)
                {
                    goto L1;
                }
                else
                    // Should remove the copy() operation by
                    // making all mods to expressions copy-on-write
                    e = ei->copy();
            }
            else
            {
#if 1
                goto L1;
#else
                // BUG: what if const is initialized in constructor?
                e = v->type->defaultInit();
                e->loc = e1->loc;
#endif
            }
            if (e->type != v->type)
            {
                e = e->castTo(NULL, v->type);
            }
            v->inuse++;
            e = e->optimize(result);
            v->inuse--;
        }
    }
L1:
    //if (e) printf("\te = %p, %s, e->type = %d, %s\n", e, e->toChars(), e->type->ty, e->type->toChars());
    return e;
}
Beispiel #2
0
Expression *AddrExp::optimize(int result)
{   Expression *e;

    //printf("AddrExp::optimize(result = %d) %s\n", result, toChars());

    /* Rewrite &(a,b) as (a,&b)
     */
    if (e1->op == TOKcomma)
    {   CommaExp *ce = (CommaExp *)e1;
        AddrExp *ae = new AddrExp(loc, ce->e2);
        ae->type = type;
        e = new CommaExp(ce->loc, ce->e1, ae);
        e->type = type;
        return e->optimize(result);
    }

    if (e1->op == TOKvar)
    {   VarExp *ve = (VarExp *)e1;
        if (ve->var->storage_class & STCmanifest)
            e1 = e1->optimize(result);
    }
    else
        e1 = e1->optimize(result);

    // Convert &*ex to ex
    if (e1->op == TOKstar)
    {   Expression *ex;

        ex = ((PtrExp *)e1)->e1;
        if (type->equals(ex->type))
            e = ex;
        else
        {
            e = ex->copy();
            e->type = type;
        }
        return e;
    }
    if (e1->op == TOKvar)
    {   VarExp *ve = (VarExp *)e1;
        if (!ve->var->isOut() && !ve->var->isRef() &&
            !ve->var->isImportedSymbol())
        {
            SymOffExp *se = new SymOffExp(loc, ve->var, 0, ve->hasOverloads);
            se->type = type;
            return se;
        }
    }
    if (e1->op == TOKindex)
    {   // Convert &array[n] to &array+n
        IndexExp *ae = (IndexExp *)e1;

        if (ae->e2->op == TOKint64 && ae->e1->op == TOKvar)
        {
            dinteger_t index = ae->e2->toInteger();
            VarExp *ve = (VarExp *)ae->e1;
            if (ve->type->ty == Tsarray
                && !ve->var->isImportedSymbol())
            {
                TypeSArray *ts = (TypeSArray *)ve->type;
                dinteger_t dim = ts->dim->toInteger();
                if (index < 0 || index >= dim)
                    error("array index %jd is out of bounds [0..%jd]", index, dim);
                e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size());
                e->type = type;
                return e;
            }
        }
    }
    return this;
}