1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
*
* Copyright (C) 2012 - 2016 - Scilab Enterprises
*
* This file is hereby licensed under the terms of the GNU GPL v2.0,
* pursuant to article 5.3.4 of the CeCILL v.2.1.
* This file was originally licensed under the terms of the CeCILL v2.1,
* and continues to be available under such terms.
* For more information, see the COPYING file which you should have received
* along with this program.
*
*/
#include "AnalysisVisitor.hxx"
namespace analysis
{
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(...)
{
visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
}
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();
// apply the ConstantVisitor
cv.setLHS(exps.size());
e.getRightExp().accept(cv);
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;
}
}
}
}
}
}
|