[mcs] Reset also all partial parts current-type
[mono-project.git] / mcs / class / Mono.CodeContracts / Mono.CodeContracts.Static.Analysis.Numerical / ValueExpressionDecoder.cs
blob83a4a93484b75240939d4f2c8edfba7928488b08
1 //
2 // ValueExpressionDecoder.cs
3 //
4 // Authors:
5 // Alexander Chebaturkin (chebaturkin@gmail.com)
6 //
7 // Copyright (C) 2012 Alexander Chebaturkin
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
31 using Mono.CodeContracts.Static.AST;
32 using Mono.CodeContracts.Static.AST.Visitors;
33 using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Decoding;
34 using Mono.CodeContracts.Static.DataStructures;
35 using Mono.CodeContracts.Static.Lattices;
36 using Mono.CodeContracts.Static.Providers;
38 namespace Mono.CodeContracts.Static.Analysis.Numerical {
39 class ValueExpressionDecoder<TVar, TExpr> : FullExpressionDecoder<TVar, TExpr>, IExpressionDecoder<TVar, TExpr>
40 where TVar : IEquatable<TVar>
41 where TExpr : IEquatable<TExpr> {
42 readonly VisitorForOperatorFor operator_for;
43 readonly VisitorForTypeOf type_of;
45 public ValueExpressionDecoder (IMetaDataProvider metaDataProvider, IExpressionContextProvider<TExpr, TVar> contextProvider)
46 : base (metaDataProvider, contextProvider)
48 operator_for = new VisitorForOperatorFor ();
49 type_of = new VisitorForTypeOf ();
52 IExpressionContext<TExpr, TVar> ExpressionContext { get { return ContextProvider.ExpressionContext; } }
54 #region IExpressionDecoder<TVar,TExpr> Members
56 public ExpressionOperator OperatorFor (TExpr expr)
58 return ExpressionContext.Decode<TExpr, ExpressionOperator, VisitorForOperatorFor> (expr, operator_for, expr);
61 public TExpr LeftExpressionFor (TExpr expr)
63 UnaryOperator op;
64 BinaryOperator bop;
65 TExpr left;
66 TExpr right;
68 if (IsUnaryExpression (expr, out op, out left) || IsBinaryExpression (expr, out bop, out left, out right))
69 return left;
71 throw new InvalidOperationException ();
74 public TExpr RightExpressionFor (TExpr expr)
76 BinaryOperator bop;
77 TExpr left;
78 TExpr right;
79 if (IsBinaryExpression (expr, out bop, out left, out right))
80 return right;
82 throw new InvalidOperationException ();
85 public bool IsConstant (TExpr expr)
87 return OperatorFor (expr) == ExpressionOperator.Constant;
90 public bool IsVariable (TExpr expr)
92 object variable;
93 return base.IsVariable (expr, out variable);
96 public bool TryValueOf<T> (TExpr e, ExpressionType expectedType, out T result)
98 object value;
99 TypeNode actualType;
100 if (base.IsConstant (e, out value, out actualType)) {
101 if (value is T)
102 return true.With ((T) value, out result);
103 if (value is int && expectedType == ExpressionType.Bool) {
104 result = (T) (object) ((int) value != 0);
105 return true;
108 return false.Without (out result);
111 public bool TrySizeOf (TExpr expr, out int size)
113 TypeNode type;
114 if (VisitorForSizeOf<TVar, TExpr>.IsSizeOf (expr, out type, this)) {
115 size = MetaDataProvider.TypeSize (type);
116 return size != -1;
119 return false.Without (out size);
122 public ExpressionType TypeOf (TExpr expr)
124 if (IsConstant (expr))
125 return ExpressionContext.Decode<Dummy, ExpressionType, VisitorForTypeOf> (expr, type_of, Dummy.Value);
127 var abstractType = ExpressionContext.GetType (expr);
129 if (abstractType.IsNormal ()) {
130 var type = abstractType.Value;
132 if (MetaDataProvider.IsPrimitive (type)) {
133 if (MetaDataProvider.Equal (type, MetaDataProvider.System_Int32))
134 return ExpressionType.Int32;
135 if (MetaDataProvider.Equal (type, MetaDataProvider.System_Single))
136 return ExpressionType.Float32;
137 if (MetaDataProvider.Equal (type, MetaDataProvider.System_Double))
138 return ExpressionType.Float64;
139 if (MetaDataProvider.Equal (type, MetaDataProvider.System_Boolean))
140 return ExpressionType.Bool;
144 return ExpressionType.Unknown;
147 public bool IsConstantInt (TExpr expr, out int value)
149 TypeNode type;
150 object objValue;
151 if (IsConstant (expr, out objValue, out type))
152 return true.With ((int) objValue, out value);
154 return false.Without (out value);
157 public string NameOf (TVar variable)
159 return variable.ToString ();
162 public bool IsBinaryExpression (TExpr expr)
164 BinaryOperator op;
165 TExpr left;
166 TExpr right;
167 return IsBinaryExpression (expr, out op, out left, out right);
170 #endregion
172 #region Nested type: VisitorForOperatorFor
174 class VisitorForOperatorFor : ISymbolicExpressionVisitor<TExpr, TExpr, TVar, TExpr, ExpressionOperator> {
175 #region ISymbolicExpressionVisitor<TExpr,TExpr,TVar,TExpr,ExpressionOperator> Members
177 public ExpressionOperator Binary (TExpr pc, BinaryOperator bop, TVar dest, TExpr src1, TExpr src2, TExpr data)
179 switch (bop) {
180 case BinaryOperator.Add:
181 case BinaryOperator.Add_Ovf:
182 case BinaryOperator.Add_Ovf_Un:
183 return ExpressionOperator.Add;
184 case BinaryOperator.And:
185 return ExpressionOperator.And;
186 case BinaryOperator.Ceq:
187 return ExpressionOperator.Equal;
188 case BinaryOperator.Cobjeq:
189 return ExpressionOperator.Equal_Obj;
190 case BinaryOperator.Cne_Un:
191 return ExpressionOperator.NotEqual;
192 case BinaryOperator.Cge:
193 case BinaryOperator.Cge_Un:
194 return ExpressionOperator.GreaterEqualThan;
195 case BinaryOperator.Cgt:
196 case BinaryOperator.Cgt_Un:
197 return ExpressionOperator.GreaterThan;
198 case BinaryOperator.Cle:
199 case BinaryOperator.Cle_Un:
200 return ExpressionOperator.LessEqualThan;
201 case BinaryOperator.Clt:
202 case BinaryOperator.Clt_Un:
203 return ExpressionOperator.LessThan;
204 case BinaryOperator.Div:
205 case BinaryOperator.Div_Un:
206 return ExpressionOperator.Div;
207 case BinaryOperator.LogicalAnd:
208 return ExpressionOperator.LogicalAnd;
209 case BinaryOperator.LogicalOr:
210 return ExpressionOperator.LogicalOr;
211 case BinaryOperator.Mul:
212 case BinaryOperator.Mul_Ovf:
213 case BinaryOperator.Mul_Ovf_Un:
214 return ExpressionOperator.Mult;
215 case BinaryOperator.Or:
216 return ExpressionOperator.Or;
217 case BinaryOperator.Rem:
218 case BinaryOperator.Rem_Un:
219 return ExpressionOperator.Mod;
220 case BinaryOperator.Sub:
221 case BinaryOperator.Sub_Ovf:
222 case BinaryOperator.Sub_Ovf_Un:
223 return ExpressionOperator.Sub;
224 case BinaryOperator.Xor:
225 return ExpressionOperator.Xor;
226 default:
227 return ExpressionOperator.Unknown;
231 public ExpressionOperator Unary (TExpr pc, UnaryOperator uop, bool unsigned, TVar dest, TExpr source, TExpr data)
233 switch (uop) {
234 case UnaryOperator.Conv_i:
235 case UnaryOperator.Conv_i1:
236 case UnaryOperator.Conv_i2:
237 case UnaryOperator.Conv_i4:
238 case UnaryOperator.Conv_i8:
239 return ExpressionOperator.ConvertToInt32;
240 case UnaryOperator.Neg:
241 return ExpressionOperator.Not;
242 case UnaryOperator.Not:
243 return ExpressionOperator.Not;
244 default:
245 return ExpressionOperator.Unknown;
249 public ExpressionOperator LoadNull (TExpr pc, TVar dest, TExpr polarity)
251 return ExpressionOperator.Constant;
254 public ExpressionOperator LoadConst (TExpr pc, TypeNode type, object constant, TVar dest, TExpr data)
256 return ExpressionOperator.Constant;
259 public ExpressionOperator Sizeof (TExpr pc, TypeNode type, TVar dest, TExpr data)
261 return ExpressionOperator.SizeOf;
264 public ExpressionOperator Isinst (TExpr pc, TypeNode type, TVar dest, TExpr obj, TExpr data)
266 return ExpressionOperator.Unknown;
269 public ExpressionOperator SymbolicConstant (TExpr pc, TVar variable, TExpr data)
271 return ExpressionOperator.Variable;
274 #endregion
277 #endregion
279 #region Nested type: VisitorForTypeOf
281 class VisitorForTypeOf : ISymbolicExpressionVisitor<TExpr, TExpr, TVar, Dummy, ExpressionType> {
282 #region ISymbolicExpressionVisitor<TExpr,TExpr,TVar,Dummy,ExpressionType> Members
284 public ExpressionType Binary (TExpr pc, BinaryOperator bop, TVar dest, TExpr src1, TExpr src2, Dummy data)
286 return ExpressionType.Unknown;
289 public ExpressionType Unary (TExpr pc, UnaryOperator uop, bool unsigned, TVar dest, TExpr source, Dummy data)
291 return ExpressionType.Unknown;
294 public ExpressionType LoadNull (TExpr pc, TVar dest, Dummy polarity)
296 return ExpressionType.Unknown;
299 public ExpressionType LoadConst (TExpr pc, TypeNode type, object constant, TVar dest, Dummy data)
301 if (constant is int)
302 return ExpressionType.Int32;
303 if (constant is float)
304 return ExpressionType.Float32;
305 if (constant is double)
306 return ExpressionType.Float64;
307 if (constant is bool)
308 return ExpressionType.Bool;
310 return ExpressionType.Unknown;
313 public ExpressionType Sizeof (TExpr pc, TypeNode type, TVar dest, Dummy data)
315 return ExpressionType.Int32;
318 public ExpressionType Isinst (TExpr pc, TypeNode type, TVar dest, TExpr obj, Dummy data)
320 return ExpressionType.Unknown;
323 public ExpressionType SymbolicConstant (TExpr pc, TVar variable, Dummy data)
325 return ExpressionType.Unknown;
328 #endregion
331 #endregion