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 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2);
30 constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2);
32 constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2);
35 /*********************************************/
38 constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2)
42 ret = constraintList_new();
44 ret = reflectChangesEnsures (list1, list2);
45 ret = constraintList_fixConflicts (ret, list2);
46 ret = constraintList_subsumeEnsures (ret, list2);
47 list2 = constraintList_subsumeEnsures (list2, ret);
48 temp = constraintList_copy(list2);
50 temp = constraintList_addList (temp, ret);
52 //ret = constraintList_addList (ret, list2);
56 constraintList checkCall (exprNode fcn, exprNodeList arglist)
58 constraintList preconditions;
60 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
62 temp = exprNode_getUentry (fcn);
64 preconditions = uentry_getFcnPreconditions (temp);
68 preconditions = constraintList_copy(preconditions);
69 preconditions = constraintList_doSRefFixBaseParam (preconditions, arglist);
73 preconditions = constraintList_new();
79 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
83 DPRINTF( (message ("magically merging constraint into parent:%s for", exprNode_unparse (parent) )));
85 DPRINTF( (message (" children: %s and %s", exprNode_unparse (child1), exprNode_unparse(child2) ) ) );
87 if (exprNode_isError (child1) || exprNode_isError(child2) )
89 if (exprNode_isError (child1) && !exprNode_isError(child2) )
91 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
92 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
93 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
94 constraintList_print( child2->requiresConstraints),
95 constraintList_print (child2->ensuresConstraints)
102 llassert(exprNode_isError(child2) );
103 parent->requiresConstraints = constraintList_new();
104 parent->ensuresConstraints = constraintList_new();
109 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
111 DPRINTF( (message ("Child constraints are %s %s and %s %s",
112 constraintList_print (child1->requiresConstraints),
113 constraintList_print (child1->ensuresConstraints),
114 constraintList_print (child2->requiresConstraints),
115 constraintList_print (child2->ensuresConstraints)
118 parent->requiresConstraints = constraintList_new();
119 parent->ensuresConstraints = constraintList_new();
121 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
123 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
124 parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
126 parent->ensuresConstraints = constraintList_mergeEnsures(child1->ensuresConstraints,
127 child2->ensuresConstraints);
129 DPRINTF( (message ("Parent constraints are %s and %s ",
130 constraintList_print (parent->requiresConstraints),
131 constraintList_print (parent->ensuresConstraints)
139 constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2)
142 ret = constraintList_new();
143 constraintList_elements (list1, el)
146 DPRINTF ((message ("Examining %s", constraint_print (el) ) ) );
147 if (!resolve (el, list2) )
149 ret = constraintList_add (ret, el);
153 DPRINTF ( (message ("Subsuming %s", constraint_print (el) ) ) );
155 } end_constraintList_elements;
161 constraintList reflectChanges (constraintList pre2, constraintList post1)
166 ret = constraintList_new();
167 constraintList_elements (pre2, el)
169 if (!resolve (el, post1) )
171 temp = substitute (el, post1);
172 if (!resolve (temp, post1) )
173 ret = constraintList_add (ret, temp);
175 } end_constraintList_elements;
182 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
186 ret = constraintList_new();
187 constraintList_elements (pre2, el)
189 if (!resolve (el, post1) )
191 temp = substitute (el, post1);
192 llassert (temp != NULL);
194 if (!resolve (temp, post1) )
195 ret = constraintList_add (ret, temp);
199 DPRINTF ( (message ("Resolved away %s ", constraint_print(el) ) ) );
201 } end_constraintList_elements;
207 bool constraint_conflict (constraint c1, constraint c2)
210 if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
213 if (c1->ar == c2->ar)
215 DPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
220 DPRINTF ( (message ("%s doesn't conflict with %s ", constraint_print (c1), constraint_print(c2) ) ) );
226 void constraint_fixConflict (constraint good, constraint conflicting)
229 if (conflicting->ar ==EQ )
231 good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
232 temp = constraint_simplify (good);
233 constraint_overWrite (good, temp);
239 bool conflict (constraint c, constraintList list)
242 constraintList_elements (list, el)
244 if ( constraint_conflict(el, c) )
246 constraint_fixConflict (el, c);
249 } end_constraintList_elements;
256 //check if constraint in list1 and conflict with constraints in List2. If so we
257 //remove form list1 and (optionally) change list2.
258 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
261 ret = constraintList_new();
262 constraintList_elements (list1, el)
264 if (! conflict (el, list2) )
266 ret = constraintList_add (ret, el);
268 } end_constraintList_elements;
275 bool resolve (constraint c, constraintList p)
277 constraintList_elements (p, el)
279 if ( satifies (c, el) )
281 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
285 end_constraintList_elements;
286 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
291 /*returns true if cosntraint post satifies cosntriant pre */
292 bool satifies (constraint pre, constraint post)
294 if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
298 if (post->expr == NULL)
304 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
307 bool arithType_canResolve (arithType ar1, arithType ar2)
313 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
327 if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
333 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
336 DPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
338 if (! arithType_canResolve (ar1, ar2) )
345 if (! (constraintExpr_canGetValue (expr1) &&
346 constraintExpr_canGetValue (expr2) ) )
348 DPRINTF( ("Can't Get value"));
352 if (constraintExpr_compare (expr2, expr1) >= 0)
357 if (constraintExpr_similar (expr1, expr2) )
363 DPRINTF(("case not handled"));
369 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new)
371 DPRINTF (("Doing replace for lexpr") );
372 c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, new);
373 DPRINTF (("Doing replace for expr") );
374 c->expr = constraintExpr_searchandreplace (c->expr, old, new);
378 bool constraint_search (constraint c, constraintExpr old)
383 ret = constraintExpr_search (c->lexpr, old);
384 ret = ret || constraintExpr_search (c->expr, old);
389 constraint constraint_adjust (constraint substitute, constraint old)
391 fileloc loc1, loc2, loc3;
393 DPRINTF ( (message("Start adjust on %s and %s", constraint_print(substitute),
394 constraint_print(old))
397 loc1 = constraint_getFileloc (old);
399 loc2 = constraintExpr_getFileloc (substitute->lexpr);
401 loc3 = constraintExpr_getFileloc (substitute->expr);
404 // special case of an equality that "contains itself"
405 if (constraintExpr_search (substitute->expr, substitute->lexpr) )
406 if (fileloc_closer (loc1, loc3, loc2))
409 DPRINTF ( (message("Doing adjust on %s", constraint_print(substitute) )
411 temp = substitute->lexpr;
412 substitute->lexpr = substitute->expr;
413 substitute->expr = temp;
414 substitute = constraint_simplify(substitute);
421 constraint substitute (constraint c, constraintList p)
423 constraintList_elements (p, el)
426 if (!constraint_conflict (c, el) )
430 temp = constraint_copy(el);
432 temp = constraint_adjust(temp, c);
434 DPRINTF((message ("Substituting %s for %s",
435 constraint_print (temp), constraint_print (c)
439 c = constraint_searchandreplace (c, temp->lexpr, temp->expr);
442 end_constraintList_elements;
444 c = constraint_simplify(c);
449 constraint constraint_solve (constraint c)
451 DPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
452 c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
453 DPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
459 constraint constraint_simplify (constraint c)
461 c->lexpr = constraintExpr_simplify (c->lexpr);
462 c->expr = constraintExpr_simplify (c->expr);
464 c = constraint_solve (c);
466 c->lexpr = constraintExpr_simplify (c->lexpr);
467 c->expr = constraintExpr_simplify (c->expr);
475 /* returns true if fileloc for term1 is closer to file for term2 than term3*/
477 bool fileloc_closer (fileloc loc1, fileloc loc2, fileloc loc3)
479 if ( fileloc_lessthan (loc1, loc2) )
481 if (fileloc_lessthan (loc2, loc3) )
483 llassert (fileloc_lessthan (loc1, loc3) );
492 if ( !fileloc_lessthan (loc1, loc2) )
494 if (!fileloc_lessthan (loc2, loc3) )
496 llassert (!fileloc_lessthan (loc1, loc3) );