Beispiel #1
0
void SLintVisitor::visit(const ast::AssignExp & e)
{
    context.setLHSExp(&e.getLeftExp());
    auto range = preCheck(e);
    e.getRightExp().accept(*this);
    e.getLeftExp().accept(*this);
    postCheck(e, range);
    context.setLHSExp(nullptr);
}
Beispiel #2
0
 void GlobalsCollector::visit(ast::AssignExp & e)
 {
     if (e.getLeftExp().isSimpleVar())
     {
         const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(e.getLeftExp()).getSymbol();
         locals.emplace(Lsym);
     }
     else if (e.getLeftExp().isCallExp())
     {
         ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
         if (ce.getName().isSimpleVar())
         {
             const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
             locals.emplace(Lsym);
         }
         for (auto arg : ce.getArgs())
         {
             arg->accept(*this);
         }
     }
     else if (e.getLeftExp().isAssignListExp())
     {
         ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
         for (const auto re : ale.getExps())
         {
             if (re->isSimpleVar())
             {
                 const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar *>(re)->getSymbol();
                 locals.emplace(Lsym);
             }
         }
     }
     else
     {
         e.getLeftExp().accept(*this);
     }
     e.getRightExp().accept(*this);
 }
void AnalysisVisitor::visit(ast::AssignExp & e)
{
    logger.log(L"AssignExp", e.getLocation());
    if (e.getLeftExp().isSimpleVar()) // A = ...
    {
        ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getLeftExp());
        const symbol::Symbol & sym = var.getSymbol();

        if (e.getRightExp().isSimpleVar())
        {
            // We have A = B (so the data associated to b is shared with a)
            const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
            Info & info = getSymInfo(symR);
            const TIType & Rtype = info.getType();
            Result & resL = e.getLeftExp().getDecorator().setResult(Rtype);
            resL.setConstant(info.getConstant());
            resL.setRange(info.getRange());
            Result & resR = e.getRightExp().getDecorator().setResult(Rtype);
            resR.setConstant(info.getConstant());
            resR.setRange(info.getRange());
            getDM().share(sym, symR, Rtype, resR.isAnInt(), &e);
        }
        else
        {
            // apply the ConstantVisitor
            cv.setLHS(1);
            e.getRightExp().accept(cv);

            if (e.getRightExp().isCallExp()) // A = foo(...)
            {
                if (e.getRightExp().isCallExp())
                {
                    visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
                }
                else
                {
                    e.getRightExp().accept(*this);
                }
            }
            else // A = 1 + 2
            {
                e.getRightExp().accept(*this);
            }

            Result & RR = getResult();
            var.getDecorator().res = RR;
            Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
            info.getConstant() = RR.getConstant();
            e.getDecorator().safe = true;

            // Don't remove temp: because the value is transfered to LHS
            getDM().releaseTmp(RR.getTempId(), nullptr);//&e.getRightExp());
        }
    }
    else if (e.getLeftExp().isCallExp()) // A(12) = ...
    {
        // apply the ConstantVisitor
        cv.setLHS(1);
        e.getRightExp().accept(cv);

        ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
        if (ce.getName().isSimpleVar())
        {
            const symbol::Symbol & symL = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
            e.getRightExp().accept(*this);
            Result & RR = e.getRightExp().getDecorator().getResult();
            ce.getDecorator().res = RR;
            Info & info = getDM().write(symL, RR.getType(), &ce.getName());
            ce.getName().getDecorator().setResult(info.type);
            if (analyzeIndices(info.type, ce))
            {
                e.getDecorator().safe = (RR.getType() == getResult().getType());
            }
            getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
        }
    }
    else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
    {
        ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
        if (e.getRightExp().isCallExp())
        {
            const ast::exps_t & exps = ale.getExps();
            visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ exps.size());
            std::vector<Result>::iterator j = multipleLHS.begin();
            for (const auto exp : exps)
            {
                // TODO: handle fields...
                if (exp->isSimpleVar() && j != multipleLHS.end())
                {
                    ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
                    const symbol::Symbol & sym = var.getSymbol();
                    Info & info = getDM().define(sym, j->getType(), j->isAnInt(), exp);
                    info.setConstant(j->getConstant());
                    var.getDecorator().res = *j;
                    ++j;
                }
            }
        }
    }
}