Analysis: always a WIP but we would expect that the end is nearer than the begin
[scilab.git] / scilab / modules / ast / includes / analysis / data / Info.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef __INFO_HXX__
14 #define __INFO_HXX__
15
16 #include <iostream>
17
18 #include "TIType.hxx"
19 #include "Data.hxx"
20 #include "gvn/GVN.hxx"
21 #include "gvn/SymbolicRange.hxx"
22 #include "ConstantValue.hxx"
23
24 namespace analysis
25 {
26
27 struct Info
28 {
29     enum Local
30     {
31         INFO_TRUE, INFO_FALSE, INFO_UNKNOWN
32     };
33
34     bool R;
35     bool W;
36     bool O;
37     bool isint;
38     Local local;
39     bool cleared;
40     bool exists;
41     TIType type;
42     Data * data;
43     ast::Exp * exp;
44     ConstantValue constant;
45     SymbolicRange range;
46     SymbolicDimension maxIndex;
47
48     Info(Data * _data = nullptr) : R(false), W(false), O(false), isint(false), local(Local::INFO_TRUE), cleared(false), exists(true), data(_data), exp(nullptr) { }
49     Info(const Info & i) : R(i.R), W(i.W), O(i.O), isint(i.isint), local(i.local), cleared(i.cleared), exists(i.exists), constant(i.constant), range(i.range), maxIndex(i.maxIndex), type(i.type), data(i.data ? new Data(*i.data) : nullptr), exp(i.exp) { }
50
51     inline void merge(Info & info)
52     {
53         R = R || info.R;
54         W = W || info.W;
55         O = O || info.O;
56         isint = isint && info.isint;
57         if (local != info.local)
58         {
59             local = Local::INFO_UNKNOWN;
60         }
61         cleared = cleared && info.cleared;
62         exists = exists || info.exists;
63         constant.merge(info.constant);
64         maxIndex.mergeAsMax(info.maxIndex);
65         type.merge(info.type);
66         data->valid = data->same(info.data);
67         // No need to merge range since this info is just used in for loop
68     }
69
70     inline void addData(const bool known, const symbol::Symbol & sym)
71     {
72         data = new Data(known, sym);
73     }
74     inline void addData(Data * _data, const symbol::Symbol & sym)
75     {
76         data = _data;
77         data->add(sym);
78     }
79
80     inline SymbolicRange & getRange()
81     {
82         return range;
83     }
84
85     inline const SymbolicRange & getRange() const
86     {
87         return range;
88     }
89
90     inline SymbolicDimension & getMaxIndex()
91     {
92         return maxIndex;
93     }
94
95     inline const SymbolicDimension & getMaxIndex() const
96     {
97         return maxIndex;
98     }
99
100     inline SymbolicRange & setRange(SymbolicRange & _range)
101     {
102         range = _range;
103         return range;
104     }
105     
106     inline ConstantValue & getConstant()
107     {
108         return constant;
109     }
110
111     inline const ConstantValue & getConstant() const
112     {
113         return constant;
114     }
115
116     inline ConstantValue & setConstant(ConstantValue & val)
117     {
118         constant = val;
119         return constant;
120     }
121
122     inline bool isknown() const
123     {
124         return local == Local::INFO_TRUE;
125     }
126
127     inline static const symbol::Symbol & getRightSym(ast::Exp * exp)
128     {
129         return static_cast<const ast::SimpleVar &>(static_cast<const ast::AssignExp *>(exp)->getRightExp()).getSymbol();
130     }
131
132     inline const TIType & getType() const
133     {
134         return type;
135     }
136
137     friend std::wostream & operator<<(std::wostream & out, const Info & info)
138     {
139         out << L"Type: " << info.type << L" - RWO:"
140             << (info.R ? L"T" : L"F")
141             << (info.W ? L"T" : L"F")
142             << (info.O ? L"T" : L"F")
143             << L" - int:" << (info.isint ? L"T" : L"F")
144             << L" - local:" << (info.local == Local::INFO_TRUE ? L"T" : (info.local == Local::INFO_FALSE ? L"F" : L"U"))
145             << L" - cleared:" << (info.cleared ? L"T" : L"F")
146             << L" - exists:" << (info.exists ? L"T" : L"F")
147             << L" - constant:" << info.constant;
148
149         out << L" - data:";
150         if (info.data)
151         {
152             out << *info.data;
153         }
154         else
155         {
156             out << L"null";
157         }
158
159         return out;
160     }
161 };
162
163 } // namespace analysis
164
165 #endif // __INFO_HXX__