예제 #1
0
파일: sideeffect.c 프로젝트: gcc-mirror/gcc
/**************************************************
 * Front-end expression rewriting should create temporary variables for
 * non trivial sub-expressions in order to:
 *  1. save evaluation order
 *  2. prevent sharing of sub-expression in AST
 */
bool isTrivialExp(Expression *e)
{
    class IsTrivialExp : public StoppableVisitor
    {
    public:
        IsTrivialExp() {}

        void visit(Expression *e)
        {
            /* Bugzilla 11201: CallExp is always non trivial expression,
             * especially for inlining.
             */
            if (e->op == TOKcall)
            {
                stop = true;
                return;
            }

            // stop walking if we determine this expression has side effects
            stop = lambdaHasSideEffect(e);
        }
    };

    IsTrivialExp v;
    return walkPostorder(e, &v) == false;
}
예제 #2
0
파일: inlinecost.c 프로젝트: quickfur/GDC
    void expressionInlineCost(Expression *e)
    {
        //printf("expressionInlineCost()\n");
        //e->print();
        if (e)
        {
            class LambdaInlineCost : public StoppableVisitor
            {
                InlineCostVisitor *icv;
            public:
                LambdaInlineCost(InlineCostVisitor *icv) : icv(icv) {}

                void visit(Expression *e)
                {
                    e->accept(icv);
                    stop = icv->cost >= COST_MAX;
                }
            };

            InlineCostVisitor icv(this);
            LambdaInlineCost lic(&icv);
            walkPostorder(e, &lic);
            cost += icv.cost;
        }
    }
예제 #3
0
파일: nogc.c 프로젝트: SungSingSong/dmd
Expression *checkGC(Scope *sc, Expression *e)
{
    FuncDeclaration *f = sc->func;
    if (e && e->op != TOKerror &&
        f && sc->intypeof != 1 && !(sc->flags & SCOPEctfe) &&
        (f->type->ty == Tfunction && ((TypeFunction *)f->type)->isnogc ||
         (f->flags & FUNCFLAGnogcInprocess) ||
         global.params.vgc))
    {
        NOGCVisitor gcv(f);
        walkPostorder(e, &gcv);
        if (gcv.err)
            return new ErrorExp();
    }
    return e;
}
예제 #4
0
파일: sideeffect.c 프로젝트: gcc-mirror/gcc
bool hasSideEffect(Expression *e)
{
    class LambdaHasSideEffect : public StoppableVisitor
    {
    public:
        LambdaHasSideEffect() {}

        void visit(Expression *e)
        {
            // stop walking if we determine this expression has side effects
            stop = lambdaHasSideEffect(e);
        }
    };

    LambdaHasSideEffect v;
    return walkPostorder(e, &v);
}
예제 #5
0
파일: delegatize.c 프로젝트: Lucretia/gcc
/******************************************
 * Patch the parent of declarations to be the new function literal.
 */
void lambdaSetParent(Expression *e, Scope *sc)
{
    class LambdaSetParent : public StoppableVisitor
    {
        Scope *sc;
    public:
        LambdaSetParent(Scope *sc) : sc(sc) {}

        void visit(Expression *)
        {
        }

        void visit(DeclarationExp *e)
        {
            e->declaration->parent = sc->parent;
        }

        void visit(IndexExp *e)
        {
            if (e->lengthVar)
            {
                //printf("lengthVar\n");
                e->lengthVar->parent = sc->parent;
            }
        }

        void visit(SliceExp *e)
        {
            if (e->lengthVar)
            {
                //printf("lengthVar\n");
                e->lengthVar->parent = sc->parent;
            }
        }
    };

    LambdaSetParent lsp(sc);
    walkPostorder(e, &lsp);
}
예제 #6
0
파일: delegatize.c 프로젝트: Lucretia/gcc
/*******************************************
 * Look for references to variables in a scope enclosing the new function literal.
 * Returns true if error occurs.
 */
bool lambdaCheckForNestedRef(Expression *e, Scope *sc)
{
    class LambdaCheckForNestedRef : public StoppableVisitor
    {
    public:
        Scope *sc;
        bool result;

        LambdaCheckForNestedRef(Scope *sc)
            : sc(sc), result(false)
        {
        }

        void visit(Expression *)
        {
        }

        void visit(SymOffExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                result = v->checkNestedReference(sc, Loc());
        }

        void visit(VarExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                result = v->checkNestedReference(sc, Loc());
        }

        void visit(ThisExp *e)
        {
            if (e->var)
                result = e->var->checkNestedReference(sc, Loc());
        }

        void visit(DeclarationExp *e)
        {
            VarDeclaration *v = e->declaration->isVarDeclaration();
            if (v)
            {
                result = v->checkNestedReference(sc, Loc());
                if (result)
                    return;

                /* Some expressions cause the frontend to create a temporary.
                 * For example, structs with cpctors replace the original
                 * expression e with:
                 *  __cpcttmp = __cpcttmp.cpctor(e);
                 *
                 * In this instance, we need to ensure that the original
                 * expression e does not have any nested references by
                 * checking the declaration initializer too.
                 */
                if (v->_init && v->_init->isExpInitializer())
                {
                    Expression *ie = initializerToExpression(v->_init);
                    result = lambdaCheckForNestedRef(ie, sc);
                }
            }
        }
    };

    LambdaCheckForNestedRef v(sc);
    walkPostorder(e, &v);
    return v.result;
}
예제 #7
0
파일: nogc.c 프로젝트: SungSingSong/dmd
 void doCond(Expression *exp)
 {
     if (exp)
         walkPostorder(exp, this);
 }
예제 #8
0
파일: sideeffect.c 프로젝트: Krox/dmd
bool hasSideEffect(Expression *e)
{
    class LambdaHasSideEffect : public StoppableVisitor
    {
    public:
        LambdaHasSideEffect() {}

        void visit(Expression *e)
        {
            switch (e->op)
            {
            // Sort the cases by most frequently used first
            case TOKassign:
            case TOKplusplus:
            case TOKminusminus:
            case TOKdeclaration:
            case TOKconstruct:
            case TOKblit:
            case TOKaddass:
            case TOKminass:
            case TOKcatass:
            case TOKmulass:
            case TOKdivass:
            case TOKmodass:
            case TOKshlass:
            case TOKshrass:
            case TOKushrass:
            case TOKandass:
            case TOKorass:
            case TOKxorass:
            case TOKpowass:
            case TOKin:
            case TOKremove:
            case TOKassert:
            case TOKhalt:
            case TOKdelete:
            case TOKnew:
            case TOKnewanonclass:
                // stop walking if we determine this expression has side effects
                stop = true;
                break;

            case TOKcall:
            {
                CallExp *ce = (CallExp *)e;
                /* Calling a function or delegate that is pure nothrow
                 * has no side effects.
                 */
                if (ce->e1->type)
                {
                    Type *t = ce->e1->type->toBasetype();
                    if ((t->ty == Tfunction && ((TypeFunction *)t)->purity > PUREweak &&
                                               ((TypeFunction *)t)->isnothrow)
                        ||
                        (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->purity > PUREweak &&
                                               ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
                       )
                    {
                    }
                    else
                        stop = true;
                }
                break;
            }

            case TOKcast:
            {
                CastExp *ce = (CastExp *)e;
                /* if:
                 *  cast(classtype)func()  // because it may throw
                 */
                if (ce->to->ty == Tclass && ce->e1->op == TOKcall && ce->e1->type->ty == Tclass)
                    stop = true;
                break;
            }

            default:
                break;
            }
        }
    };

    LambdaHasSideEffect v;
    return walkPostorder(e, &v);
}