Analysis: replace constant in Result by a C++ union
[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 "ConstantValue.hxx"
22
23 namespace analysis
24 {
25
26 struct Info
27 {
28     enum Local
29     {
30         INFO_TRUE, INFO_FALSE, INFO_UNKNOWN
31     };
32
33     bool R;
34     bool W;
35     bool O;
36     bool isint;
37     Local local;
38     bool cleared;
39     bool exists;
40     TIType type;
41     Data * data;
42     ast::Exp * exp;
43     ConstantValue constant;
44
45     Info(Data * _data = nullptr) : R(false), W(false), O(false), isint(false), local(Local::INFO_TRUE), cleared(false), exists(true), data(_data), exp(nullptr) { }
46     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), type(i.type), data(i.data ? new Data(*i.data) : nullptr), exp(i.exp) { }
47
48     inline void merge(Info & info)
49     {
50         R = R || info.R;
51         W = W || info.W;
52         O = O || info.O;
53         isint = isint && info.isint;
54         if (local != info.local)
55         {
56             local = Local::INFO_UNKNOWN;
57         }
58         cleared = cleared && info.cleared;
59         exists = exists || info.exists;
60         constant.merge(info.constant);
61         //knownValue = knownValue && info.knownValue && value == info.value;
62         type.merge(info.type);
63         data->valid = data->same(info.data);
64     }
65
66     inline void addData(const bool known, const symbol::Symbol & sym)
67     {
68         data = new Data(known, sym);
69     }
70     inline void addData(Data * _data, const symbol::Symbol & sym)
71     {
72         data = _data;
73         data->add(sym);
74     }
75
76     inline ConstantValue & getConstant()
77     {
78         return constant;
79     }
80
81     inline const ConstantValue & getConstant() const
82     {
83         return constant;
84     }
85
86     inline ConstantValue & setConstant(ConstantValue & val)
87     {
88         constant = val;
89         return constant;
90     }
91
92     inline bool isknown() const
93     {
94         return local == Local::INFO_TRUE;
95     }
96
97     inline static const symbol::Symbol & getRightSym(ast::Exp * exp)
98     {
99         return static_cast<const ast::SimpleVar &>(static_cast<const ast::AssignExp *>(exp)->getRightExp()).getSymbol();
100     }
101
102     inline const TIType & getType() const
103     {
104         return type;
105     }
106
107     friend std::wostream & operator<<(std::wostream & out, const Info & info)
108     {
109         out << L"Type: " << info.type << L" - RWO:"
110             << (info.R ? L"T" : L"F")
111             << (info.W ? L"T" : L"F")
112             << (info.O ? L"T" : L"F")
113             << L" - int:" << (info.isint ? L"T" : L"F")
114             << L" - local:" << (info.local == Local::INFO_TRUE ? L"T" : (info.local == Local::INFO_FALSE ? L"F" : L"U"))
115             << L" - cleared:" << (info.cleared ? L"T" : L"F")
116             << L" - exists:" << (info.exists ? L"T" : L"F")
117             << L" - constant:" << info.constant;
118
119         out << L" - data:";
120         if (info.data)
121         {
122             out << *info.data;
123         }
124         else
125         {
126             out << L"null";
127         }
128
129         return out;
130     }
131 };
132
133 } // namespace analysis
134
135 #endif // __INFO_HXX__