6 # include <ctype.h> /* for isdigit */
7 # include "lclintMacros.nf"
10 # include "cgrammar_tokens.h"
12 # include "exprChecks.h"
13 # include "aliasChecks.h"
14 # include "exprNodeSList.h"
15 # include "exprData.i"
17 #include "constraintExpr.h"
19 constraintList reflectChanges (constraintList pre2, constraintList post1);
20 constraint substitute (constraint c, constraintList p);
21 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new);
22 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2);
23 bool satifies (constraint pre, constraint post);
24 bool resolve (constraint c, constraintList p);
25 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1);
26 constraint constraint_simplify (constraint c);
28 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
31 TPRINTF( (message ("magically merging constraint into parent:%s for children: %s and %s", exprNode_unparse (parent), exprNode_unparse (child1), exprNode_unparse(child2) )
33 if (exprNode_isError (child1) || exprNode_isError(child2) )
35 if (exprNode_isError (child1) && !exprNode_isError(child2) )
37 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
38 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
39 TPRINTF((message ("Copied child constraints: pre: %s and post: %s",
40 constraintList_print( child2->requiresConstraints),
41 constraintList_print (child2->ensuresConstraints)
48 llassert(exprNode_isError(child2) );
49 parent->requiresConstraints = constraintList_new();
50 parent->ensuresConstraints = constraintList_new();
55 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
57 TPRINTF( (message ("Child constraints are %s %s and %s %s",
58 constraintList_print (child1->requiresConstraints),
59 constraintList_print (child1->ensuresConstraints),
60 constraintList_print (child2->requiresConstraints),
61 constraintList_print (child2->ensuresConstraints)
64 parent->requiresConstraints = constraintList_new();
65 parent->ensuresConstraints = constraintList_new();
67 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
69 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
70 parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
73 temp = reflectChangesEnsures (child1->ensuresConstraints, child2->ensuresConstraints);
74 // temp = constraintList_copy (child1->ensuresConstraints);
76 temp = constraintList_fixConflicts (temp, child2->ensuresConstraints);
78 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
79 parent->ensuresConstraints = constraintList_addList (parent->ensuresConstraints, temp);
81 TPRINTF( (message ("Parent constraints are %s and %s ",
82 constraintList_print (parent->requiresConstraints),
83 constraintList_print (parent->ensuresConstraints)
90 constraintList reflectChanges (constraintList pre2, constraintList post1)
95 ret = constraintList_new();
96 constraintList_elements (pre2, el)
98 if (!resolve (el, post1) )
100 temp = substitute (el, post1);
101 ret = constraintList_add (ret, temp);
103 } end_constraintList_elements;
110 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
114 ret = constraintList_new();
115 constraintList_elements (pre2, el)
117 if (!resolve (el, post1) )
119 temp = substitute (el, post1);
121 ret = constraintList_add (ret, temp);
123 } end_constraintList_elements;
129 bool constraint_conflict (constraint c1, constraint c2)
132 if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
134 if (c1->ar == c2->ar)
136 TPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
141 TPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
147 void constraint_fixConflict (constraint good, constraint conflicting)
150 if (conflicting->ar ==EQ )
152 good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
153 temp = constraint_simplify (good);
154 constraint_overWrite (good, temp);
160 bool conflict (constraint c, constraintList list)
163 constraintList_elements (list, el)
165 if ( constraint_conflict(el, c) )
167 constraint_fixConflict (el, c);
170 } end_constraintList_elements;
177 //check if constraint in list1 and conflict with constraints in List2. If so we
178 //remove form list1 and (optionally) change list2.
179 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
182 ret = constraintList_new();
183 constraintList_elements (list1, el)
185 if (! conflict (el, list2) )
187 ret = constraintList_add (ret, el);
189 } end_constraintList_elements;
196 bool resolve (constraint c, constraintList p)
198 constraintList_elements (p, el)
200 if ( satifies (c, el) )
202 TPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
206 end_constraintList_elements;
207 TPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
212 /*returns true if cosntraint post satifies cosntriant pre */
213 bool satifies (constraint pre, constraint post)
215 if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
219 if (post->expr == NULL)
225 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
229 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
232 TPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
237 /*irst constraint is > only > => or == cosntraint can satify it */
238 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
240 if (! constraintExpr_canGetValue (expr1) )
242 TPRINTF( ("Can't Get value"));
245 if (! constraintExpr_canGetValue (expr2) )
247 TPRINTF( ("Can't Get value"));
251 if (constraintExpr_compare (expr2, expr1) >= 0)
258 TPRINTF(("case not handled"));
263 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new)
265 TPRINTF (("Doing replace for lexpr") );
266 c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, new);
267 TPRINTF (("Doing replace for expr") );
268 c->expr = constraintExpr_searchandreplace (c->expr, old, new);
273 constraint constraint_adjust (constraint substitute, constraint old)
275 fileloc loc1, loc2, loc3;
277 loc1 = constraint_getFileloc (old);
279 loc2 = constraintExpr_getFileloc (substitute->lexpr);
281 loc3 = constraintExpr_getFileloc (substitute->expr);
283 if (fileloc_closer (loc1, loc3, loc2))
286 temp = substitute->lexpr;
287 substitute->lexpr = substitute->expr;
288 substitute->expr = temp;
289 substitute = constraint_simplify(substitute);
296 constraint substitute (constraint c, constraintList p)
298 constraintList_elements (p, el)
301 if (!constraint_conflict (c, el) )
306 temp = constraint_copy(el);
308 temp = constraint_adjust(temp, c);
310 c = constraint_searchandreplace (c, el->lexpr, el->expr);
313 end_constraintList_elements;
315 c = constraint_simplify(c);
320 constraint constraint_solve (constraint c)
322 TPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
323 c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
324 TPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
330 constraint constraint_simplify (constraint c)
332 c->lexpr = constraintExpr_simplify (c->lexpr);
333 c->expr = constraintExpr_simplify (c->expr);
335 c = constraint_solve (c);
337 c->lexpr = constraintExpr_simplify (c->lexpr);
338 c->expr = constraintExpr_simplify (c->expr);
346 /* returns true if fileloc for term1 is closer to file for term2 than term3*/
348 bool fileloc_closer (fileloc loc1, fileloc loc2, fileloc loc3)
350 if ( fileloc_lessthan (loc1, loc2) )
352 if (fileloc_lessthan (loc2, loc3) )
354 llassert (fileloc_lessthan (loc1, loc3) );
363 if ( !fileloc_lessthan (loc1, loc2) )
365 if (!fileloc_lessthan (loc2, loc3) )
367 llassert (!fileloc_lessthan (loc1, loc3) );