]> andersk Git - splint.git/blob - src/constraintExpr.c
*** empty log message ***
[splint.git] / src / constraintExpr.c
1 /*
2 ** constraintExpr.c
3 */
4
5 //#define DEBUGPRINT 1
6
7 # include "lclintMacros.nf"
8 # include "basic.h"
9 # include "cgrammar.h"
10 # include "cgrammar_tokens.h"
11
12 # include "exprChecks.h"
13 # include "exprNodeSList.h"
14
15 //# include "constraintExpr.h"
16
17
18 /*@-czechfcns@*/
19
20
21
22 /*@access exprNode constraintExpr@*/
23
24
25 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr, int p_literal);
26
27
28 /*@only@*/ static constraintExpr 
29 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist) /*@modifies p_e@*/;
30
31 static /*@only@*/ constraintExpr 
32 doFixResultTerm (/*@only@*/ constraintExpr p_e, /*@exposed@*/ exprNode p_fcnCall)
33      /*@modifies p_e@*/;
34
35
36      /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void) ; /// @allocates result->data @ @sets result->kind @;
37
38 //constraintExpr constraintExpr_makeMaxSetConstraintExpr (constraintExpr c);
39
40 void constraintExpr_free (/*@only@*/ constraintExpr expr)
41 {
42   if (constraintExpr_isDefined(expr) )
43     {
44       switch (expr->kind)
45         {
46         case unaryExpr:
47           constraintExprData_freeUnaryExpr(expr->data);
48           break;
49         case binaryexpr:
50           constraintExprData_freeBinaryExpr(expr->data);
51           break;
52         case term:
53           constraintExprData_freeTerm(expr->data);
54           break;
55         default:
56           BADEXIT;
57         }
58
59       expr->data = NULL;
60       free (expr);
61     }
62   else
63     {
64       llcontbug(message("attempted to free null pointer in constraintExpr_free"));
65     }
66 }
67
68 bool constraintExpr_isLit (constraintExpr expr)
69 {
70   llassert (expr != NULL);
71   
72   if (expr->kind == term)
73     {
74       constraintTerm term = constraintExprData_termGetTerm (expr->data);
75       if (constraintTerm_isIntLiteral (term) )
76         {
77           return TRUE;
78         }
79
80     }
81   return FALSE;
82 }
83
84 static bool isZeroBinaryOp (constraintExpr expr)
85 {
86   constraintExpr e2;
87   
88   llassert (expr != NULL); /* evans 2001-07-18 */
89
90   if (!constraintExpr_isBinaryExpr (expr) )
91     {
92       return FALSE;
93     }
94
95   
96   e2 = constraintExprData_binaryExprGetExpr2(expr->data);
97
98   llassert (e2 != NULL); /* evans 2001-07-18 */
99
100   if (constraintExpr_isBinaryExpr (e2) )
101     {
102       constraintExpr e1;
103       constraintExprBinaryOpKind  op;
104
105       op = constraintExprData_binaryExprGetOp (e2->data);
106
107       e1 = constraintExprData_binaryExprGetExpr1(e2->data);
108
109         if (constraintExpr_isLit(e1) )
110           {
111             if (constraintExpr_getValue(e1) == 0 )
112               {
113                 return TRUE;
114               }
115           }
116     }
117   return FALSE;
118 }
119
120 /* change expr + (o - expr) to (expr -expr) */
121
122 /*@only@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
123 {
124   constraintExpr expr1, expr2;
125   
126   constraintExpr temp;
127
128   constraintExprBinaryOpKind  op;
129   
130   constraintExprBinaryOpKind  tempOp;
131
132   if (!isZeroBinaryOp(expr) )
133     return expr;
134
135   llassert (expr != NULL); /* evans 2001-07-18 */
136   
137   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
138   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
139   op = constraintExprData_binaryExprGetOp(expr->data);
140
141   llassert( constraintExpr_isBinaryExpr(expr2) );           
142
143   temp = constraintExprData_binaryExprGetExpr2 (expr2->data);
144   temp = constraintExpr_copy (temp);
145
146   tempOp = constraintExprData_binaryExprGetOp (expr2->data);
147
148   if (op == PLUS)
149     op = tempOp;
150   else if (op == MINUS)
151     {
152       if (tempOp == PLUS)
153         op = MINUS;
154       else if (tempOp == MINUS)
155         op = PLUS;
156       else
157         BADEXIT;
158     }
159   else
160     BADEXIT;
161
162   /*@i834@*/ constraintExpr_free(expr2);
163   
164   expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
165   expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
166
167   return expr;
168 }
169
170
171 /*@only@*/ constraintExpr constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr,
172                                                 /*@out@*/ bool * propagate,
173                                                   /*@out@*/ int *literal)
174 {
175   constraintExpr expr1;
176   constraintExpr expr2;
177   bool propagate1, propagate2;
178   int literal1, literal2;
179   constraintExprBinaryOpKind  op;
180   
181   propagate1 = FALSE;
182   propagate2 = FALSE;
183  
184   literal1 = 0;
185   literal2 = 0;
186   
187   *propagate = FALSE;
188   *literal = 0;
189
190   llassert (expr != NULL);
191   
192   // we simplify unaryExpr else where
193   if (expr->kind != binaryexpr)
194     return expr;
195
196   op = constraintExprData_binaryExprGetOp (expr->data);
197
198   DPRINTF( (message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
199
200   expr = removeZero(expr);
201   
202   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
203   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
204
205   expr1 = constraintExpr_copy(expr1);
206   expr2 = constraintExpr_copy(expr2);
207
208   expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
209   expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
210
211   *propagate = propagate1 || propagate2;
212
213   if (op == PLUS)
214     *literal    = literal1 +  literal2;
215   else   if (op == MINUS)
216     *literal    = literal1 -  literal2;
217   else
218     BADEXIT;
219     
220   if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
221     {
222       long t1, t2;
223       t1 = constraintExpr_getValue (expr1);
224       t2 = constraintExpr_getValue (expr2);
225       llassert(*propagate == FALSE);
226       *propagate = FALSE;
227
228       constraintExpr_free (expr);
229       constraintExpr_free (expr1);
230       constraintExpr_free (expr2);
231
232       if (op == PLUS )
233         return (constraintExpr_makeIntLiteral ( (t1+t2) ));
234       else if (op ==  MINUS)
235         return (constraintExpr_makeIntLiteral ( (t1-t2) ));
236       else
237         BADEXIT;
238     }
239
240   
241   if (constraintExpr_isLit (expr1) )
242     {
243       *propagate = TRUE;
244
245       *literal += constraintExpr_getValue (expr1);
246
247       if (op == PLUS)
248         {
249           constraintExpr_free(expr1);
250           constraintExpr_free(expr);
251           return expr2;
252         }
253       else if (op == MINUS)
254         {
255           constraintExpr temp;
256
257           /* this is an ugly kludge to deal with not
258              having a unary minus operation...*/
259           
260           temp = constraintExpr_makeIntLiteral (0);
261           temp = constraintExpr_makeSubtractExpr (temp, expr2);
262           
263           constraintExpr_free(expr1);
264           constraintExpr_free(expr);
265           
266           return temp;
267         }
268       else
269         {
270           BADBRANCH; /* evans 2001-07-18 */
271         }
272     }
273   
274   if (constraintExpr_isLit (expr2) )
275     {
276       *propagate = TRUE;
277           
278       if ( op == PLUS )
279         *literal += constraintExpr_getValue (expr2);
280       else if (op ==  MINUS)
281         *literal -= constraintExpr_getValue (expr2);
282       else
283         BADEXIT;
284
285
286       constraintExpr_free(expr2);
287       constraintExpr_free(expr);
288       return expr1;
289     }
290   
291   DPRINTF( (message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
292
293   expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
294   expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
295
296   expr = removeZero(expr);
297   return expr;
298 }
299
300 /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
301 {
302   bool propagate;
303   int literal;
304
305   DPRINTF ( (message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
306   expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
307  
308
309   if (propagate)
310     {
311       constraintExpr ret;
312
313       if (literal != 0)
314         {
315           ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
316           expr = ret;
317         }
318     }
319    DPRINTF ( (message ("After combine %s", constraintExpr_unparse(expr) ) ) );
320   return expr;
321 }
322
323 /*@special@*/
324 static constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
325 {
326   constraintExpr ret;
327   ret = dmalloc (sizeof (*ret) );
328   ret->kind = term;
329   ret->data = NULL;
330   return ret;
331 }
332
333 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
334 {
335   constraintExprData ret;
336   llassert(constraintExprData_isDefined(data));
337
338   switch (kind)
339     {
340     case binaryexpr:
341       ret = constraintExprData_copyBinaryExpr(data);
342       break;
343     case unaryExpr:
344       ret = constraintExprData_copyUnaryExpr(data);
345       break;
346     case term:
347       ret = constraintExprData_copyTerm(data);
348       break;
349     default:
350       BADEXIT;
351     }
352   return ret;
353 }
354
355 constraintExpr constraintExpr_copy (constraintExpr expr)
356 {
357   constraintExpr ret;
358   ret = constraintExpr_alloc();
359   ret->kind = expr->kind;
360   
361   ret->data = copyExprData (expr->data, expr->kind);
362   return ret;
363 }
364
365
366 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
367 {
368   constraintExpr ret;
369   constraintTerm t;
370   ret = constraintExpr_alloc();
371   ret->kind = term;
372   ret->data = dmalloc (sizeof *(ret->data) );
373   t = constraintTerm_makeExprNode (e);
374   ret->data = constraintExprData_termSetTerm (ret->data, t);
375   return ret;
376 }
377
378 constraintExpr constraintExpr_makeExprNode (exprNode e)
379 {
380  sRef s;
381  constraintExpr ret, ce1, ce2;
382  exprData data;
383  exprNode t, t1, t2;
384  lltok tok;
385  
386  
387  llassert (e != NULL);
388  
389  data = e->edata;
390
391  switch (e->kind)
392    {
393    case XPR_SIZEOF:
394      t = exprData_getSingle (data);
395      s = exprNode_getSref (t);
396      if (sRef_isFixedArray(s) )
397       {
398         int size;
399
400         size = (int) sRef_getArraySize(s);
401         ret = constraintExpr_makeIntLiteral (size);
402       }
403      else
404        {
405          DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
406          ret = oldconstraintExpr_makeTermExprNode (e);
407        }
408      break;
409      
410    case XPR_OP:
411       DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
412      t1 = exprData_getOpA (data);
413      t2 = exprData_getOpB (data);
414      tok = exprData_getOpTok (data);
415      
416      if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
417        {
418          ce1 = constraintExpr_makeExprNode (t1);
419          ce2 = constraintExpr_makeExprNode (t2);
420          ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);         
421        }
422      else
423        {
424         ret = oldconstraintExpr_makeTermExprNode (e);
425        }
426      break;
427    case XPR_PARENS: 
428      t = exprData_getUopNode (data);
429      ret = constraintExpr_makeExprNode (t);
430      break;
431      
432    case XPR_PREOP:
433       t = exprData_getUopNode (data);
434       tok =  exprData_getUopTok (data);
435       if (lltok_isInc_Op (tok) )
436         {
437           constraintExpr temp;
438           temp = constraintExpr_makeExprNode(t);
439           ret = constraintExpr_makeIncConstraintExpr(temp);
440         }
441       else if (lltok_isDec_Op (tok) )
442         {
443           constraintExpr temp;
444           temp = constraintExpr_makeExprNode(t);
445           ret = constraintExpr_makeDecConstraintExpr(temp);
446         }
447       else
448         ret =  oldconstraintExpr_makeTermExprNode (e);
449       break;
450       
451    case XPR_POSTOP:
452      t = exprData_getUopNode (data);
453           ret = constraintExpr_makeExprNode (t);
454      break;
455    case XPR_CAST:
456      t = exprData_getCastNode (data);
457      ret = constraintExpr_makeExprNode (t);
458      break;
459    case XPR_COMMA:
460      t = exprData_getPairA(data);
461      ret = constraintExpr_makeExprNode(t);
462      /*@i3434*/ /*I'm not sure if this is right.  I'm adding a break to quite LCLint*/
463      break;
464    default:
465      ret = oldconstraintExpr_makeTermExprNode (e);
466      
467    }
468   return ret;
469 }
470
471 /*@only@*/  constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
472 {
473   return  oldconstraintExpr_makeTermExprNode(e); //constraintExpr_makeExprNode (e);
474 }
475
476 static constraintExpr constraintExpr_makeTerm (/*@only@*/  constraintTerm t)
477 {
478   constraintExpr ret;
479
480   ret = constraintExpr_alloc();
481   ret->kind = term;
482   ret->data = dmalloc (sizeof *(ret->data) );
483   ret->data = constraintExprData_termSetTerm (ret->data, t);
484
485   return ret;
486 }
487
488 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
489 {
490   constraintExpr ret;
491   constraintTerm t;
492   ret = constraintExpr_alloc();
493   ret->kind = term;
494   ret->data = dmalloc (sizeof *(ret->data) );
495   t = constraintTerm_makesRef (s);
496   ret->data = constraintExprData_termSetTerm (ret->data, t);
497   return ret;
498 }
499
500 /*@special@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
501 {
502   constraintExpr ret;
503   ret = constraintExpr_alloc();
504   ret->kind = unaryExpr;
505   ret->data = dmalloc ( sizeof *(ret->data) );
506   return ret;
507 }
508
509 /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
510 {
511   constraintExpr ret;
512   ret = makeUnaryOpGeneric();
513
514   /*@-uniondef@*/ 
515   /*@-compdef@*/
516     ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
517     ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
518
519   return ret;
520
521   /*@=compdef@*/
522   /*@=uniondef@*/
523 }
524
525
526 /*@only@*/ static constraintExpr constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr,   constraintExprUnaryOpKind Op )
527 {
528   constraintExpr ret;
529   ret = makeUnaryOpGeneric();
530
531   ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
532   ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
533
534   return ret;
535 }
536
537 /*@only@*/
538 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
539 {
540   constraintExpr ret;
541   ret = constraintExpr_makeUnaryOp (c, MAXSET);
542   return ret;
543 }
544
545 /*@only@*/
546 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
547 {
548   constraintExpr ret;
549   constraintExpr sub;
550   sub = constraintExpr_makeExprNode (expr);
551   ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
552
553   return ret;
554 }
555
556
557
558 /*@only@*/
559 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s,  constraintExprUnaryOpKind op)
560 {
561   constraintExpr ret;
562   constraintExpr t;
563
564   t = constraintExpr_makeTermsRef (s);
565   ret = constraintExpr_makeUnaryOpConstraintExpr (t);
566   ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
567
568   return ret;
569 }
570
571 /*@only@*/
572 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
573 {
574   return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
575 }     
576
577 /*@only@*/
578 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
579 {
580   return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
581 }
582
583 /*@only@*/
584 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
585 {
586   constraintExpr ret;
587   ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
588
589   switch (op.tok)
590     {
591     case QMAXSET:
592       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
593       break;
594     case QMAXREAD:
595       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
596       break;
597     default:
598       llfatalbug(message("Unhandled Operation in Constraint") );
599     }
600   return ret;
601 }
602
603 /*@only@*/
604 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
605 {
606   constraintExpr ret;
607   ret = constraintExpr_makeExprNode (expr);
608
609   ret = constraintExpr_makeMaxSetConstraintExpr (ret);
610
611   llassert (ret != NULL);
612   return ret;
613 }
614
615 /*@only@*/
616 constraintExpr  constraintExpr_makeMaxReadExpr (exprNode expr)
617 {
618   constraintExpr ret;
619   ret = constraintExpr_makeUnaryOpExprNode(expr);
620   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
621   return ret; 
622 }
623
624 /*@only@*/
625 /*@unused@*/ static constraintExpr  constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
626 {
627   constraintExpr ret;
628   ret = constraintExpr_makeUnaryOpExprNode(expr);
629   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINSET);
630   return ret;
631 }
632
633 /*@only@*/
634 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
635 {
636   constraintExpr ret;
637   ret = constraintExpr_makeUnaryOpExprNode(expr);
638   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
639   return ret;
640 }
641
642
643 /*@only@*/
644 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
645 {
646   constraintExpr ret;
647   ret = constraintExpr_makeExprNode (expr);
648   return ret;
649 }
650
651 /*@only@*/
652 constraintExpr constraintExpr_makeIntLiteral (long i)
653 {
654   constraintExpr ret;
655   constraintTerm t;
656   ret = constraintExpr_alloc();
657   ret->kind = term;
658   ret->data = dmalloc (sizeof *(ret->data) );
659   t = constraintTerm_makeIntLiteral (i);
660   ret->data = constraintExprData_termSetTerm (ret->data, t);
661   return ret;
662 }
663
664 /*
665 constraintExpr constraintExpr_makeValueInt (int i)
666 {
667   return constraintExpr_makeIntLiteral (i);
668 }
669 */
670
671 /*@only@*/
672  /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
673       /*@allocates result->data @*/ /*@sets result->kind @*/
674 {
675   constraintExpr ret;
676   ret = constraintExpr_alloc();
677   ret->kind = binaryexpr;
678   ret->data = dmalloc ( sizeof *(ret->data) );
679   //  ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
680   return ret;
681 }
682
683
684 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
685      
686 {
687   constraintExpr ret;
688
689   ret = constraintExpr_makeBinaryOp();
690   ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
691   ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
692   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
693   return ret;
694 }
695
696 /*@only@*/
697 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
698 {
699   constraintExpr ret;
700   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
701   if (op.tok == TPLUS)
702     ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
703   else if (op.tok == TMINUS)
704     ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
705     else
706       {
707         llassert(FALSE);
708       }
709   return ret;
710 }
711
712 /*@only@*/
713 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
714 {
715   constraintExpr ret;
716   constraintExpr sub1, sub2;
717   sub1 = constraintExpr_makeTermExprNode (expr1);
718   sub2 = constraintExpr_makeTermExprNode (expr2);
719   ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
720   return ret;
721 }
722
723 static /*@only@*/
724 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
725 {
726   constraintExpr ret;
727   constraintExpr constExpr;
728
729   constExpr = constraintExpr_makeIntLiteral (literal);
730   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
731   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
732   return ret;
733 }
734
735 /*@only@*/
736 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
737 {
738   constraintExpr ret;
739   constraintExpr inc;
740
741   inc = constraintExpr_makeIntLiteral (1);
742   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
743   ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
744   return ret;
745 }
746
747
748 /*@only@*/  constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
749 {
750   constraintExpr  ret;
751   
752   DPRINTF ( (message ("Making  subtract expression") ) );
753
754   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
755   ret->data = constraintExprData_binaryExprSetOp (ret->data, MINUS);
756   return ret;
757 }
758
759 /*@only@*/
760 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
761 constraintExpr expr, /*@only@*/
762 constraintExpr addent)
763 {
764   constraintExpr  ret;
765   
766   DPRINTF ( (message ("Doing addTerm simplification") ) );
767
768   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
769   ret->data = constraintExprData_binaryExprSetOp (ret->data, PLUS);
770   return ret;
771 }
772
773
774 /*@only@*/
775 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
776 {
777   constraintExpr ret;
778   constraintExpr inc;
779
780   inc = constraintExpr_makeIntLiteral (1);
781   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
782   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
783   return ret;
784 }
785
786 /*@only@*/
787 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
788 {
789   switch (op)
790     {
791     case MAXSET:
792       return message("maxSet");
793     case MINSET:
794       return message("minSet");
795     case MAXREAD:
796       return message("maxRead");
797     case MINREAD:
798       return message("minRead");
799     default:
800       llassert(FALSE);
801       return message ("<(Unary OP OTHER>");
802     }
803 }
804
805
806 /*@only@*/
807 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
808 {
809   
810   switch (op)
811     {
812     case PLUS:
813       return message("+");
814     case MINUS:
815       return message("-");
816
817     default:
818       llassert(FALSE);
819       return message ("<binary OP Unknown>");
820     }
821 }
822
823 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
824 {
825   constraintExprKind kind;
826   
827   llassert (expr1 != NULL);
828   llassert (expr2 != NULL);
829   if (expr1->kind != expr2->kind)
830     return FALSE;
831   
832   kind = expr1->kind;
833   
834   switch (kind)
835     {
836     case term:
837       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
838                                   constraintExprData_termGetTerm(expr2->data) );
839       /*@notreached@*/ break;
840       
841     case unaryExpr:
842       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
843         return FALSE;
844       
845       return (constraintExpr_similar (
846               constraintExprData_unaryExprGetExpr (expr1->data),
847               constraintExprData_unaryExprGetExpr (expr2->data)
848               ));
849       
850     case binaryexpr:
851       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
852         return FALSE;
853       
854       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
855                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
856         return FALSE;
857       
858       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
859                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
860         return FALSE;
861       else
862         return TRUE;
863       /*@notreached@*/
864       break;
865       
866     default:
867       llassert(FALSE);
868       return FALSE;
869     }
870   /*@notreached@*/
871   return FALSE;
872 }
873
874 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
875 {
876   constraintExprKind kind;
877   
878   llassert (expr1 != NULL);
879   llassert (expr2 != NULL);
880   if (expr1->kind != expr2->kind)
881     return FALSE;
882   
883   kind = expr1->kind;
884   
885   switch (kind)
886     {
887     case term:
888       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
889                                   constraintExprData_termGetTerm(expr2->data) );
890       /*@notreached@*/ break;
891       
892     case unaryExpr:
893       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
894         return FALSE;
895
896       return (constraintExpr_same (
897               constraintExprData_unaryExprGetExpr (expr1->data),
898               constraintExprData_unaryExprGetExpr (expr2->data)
899               ));
900       
901             
902     case binaryexpr:
903       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
904         return FALSE;
905       
906       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
907                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
908         return FALSE;
909       
910       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
911                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
912         return FALSE;
913       else
914         return TRUE;
915       /*@notreached@*/ break;
916       
917     default:
918       llassert(FALSE);
919       return FALSE;
920     }
921
922   /*@notreached@*/
923   BADEXIT;
924 }
925
926 bool constraintExpr_search (/*@observer@*/ constraintExpr c, /*@observer@*/ constraintExpr old)
927 {
928   bool ret = FALSE;
929   constraintExprKind kind;
930   constraintExpr temp;
931   
932   if ( constraintExpr_similar (c, old) )
933     {
934       DPRINTF((message ("Found  %q",
935                         constraintExpr_unparse(old)
936                         )));
937       return TRUE;
938     }
939
940   kind = c->kind;
941   
942   switch (kind)
943     {
944     case term:
945       break;      
946     case unaryExpr:
947       temp = constraintExprData_unaryExprGetExpr (c->data);
948       ret = ret || constraintExpr_search (temp, old);
949       break;           
950     case binaryexpr:
951       
952       temp = constraintExprData_binaryExprGetExpr1 (c->data);
953       ret = ret || constraintExpr_search(temp, old);
954            
955       temp = constraintExprData_binaryExprGetExpr2 (c->data);
956       ret = ret || constraintExpr_search(temp, old);
957       break;
958     default:
959       llassert(FALSE);
960     }
961   return ret;
962   
963 }
964
965
966 /*@only@*/ constraintExpr constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old, /*@temp@*/ constraintExpr newExpr )
967 {
968   constraintExprKind kind;
969   constraintExpr temp;
970   
971   if ( constraintExpr_similar (c, old) )
972     {
973
974       DPRINTF((message ("Replacing %s with %s",
975                         constraintExpr_unparse(old), constraintExpr_unparse(newExpr)
976                         )));
977       constraintExpr_free(c);
978       return constraintExpr_copy (newExpr);
979     }
980
981   kind = c->kind;
982   
983   switch (kind)
984     {
985     case term:
986       break;      
987     case unaryExpr:
988       temp = constraintExprData_unaryExprGetExpr (c->data);
989       temp = constraintExpr_copy(temp);
990       temp = constraintExpr_searchandreplace (temp, old, newExpr);
991       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
992       break;           
993     case binaryexpr:
994       
995       temp = constraintExprData_binaryExprGetExpr1 (c->data);
996       temp = constraintExpr_copy(temp);
997       temp = constraintExpr_searchandreplace (temp, old, newExpr);
998       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
999        
1000       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1001       temp = constraintExpr_copy(temp);
1002       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1003       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1004       break;
1005     default:
1006       llassert(FALSE);
1007     }
1008   return c;
1009   
1010 }
1011
1012 static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ constraintExpr c)
1013 {
1014   constraintExprKind kind;
1015   constraintExpr temp;
1016
1017   kind = c->kind;
1018   
1019   switch (kind)
1020     {
1021     case term:
1022       break;      
1023     case unaryExpr:
1024       temp = constraintExprData_unaryExprGetExpr (c->data);
1025       temp = constraintExpr_copy(temp);
1026       temp = constraintExpr_simplify (temp);
1027       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1028       break;           
1029     case binaryexpr:
1030       DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1031       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1032       temp = constraintExpr_copy(temp);
1033       temp = constraintExpr_simplify (temp);
1034
1035       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1036        
1037       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1038       temp = constraintExpr_copy(temp);
1039       temp = constraintExpr_simplify (temp);
1040
1041       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1042       break;
1043     default:
1044       llassert(FALSE);
1045     }
1046   return c;
1047   
1048 }
1049
1050
1051 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1052 {
1053   constraintTerm t;
1054   constraintExpr temp;
1055
1056   llassert(c != NULL);
1057   
1058   switch (c->kind)
1059     {
1060     case term:
1061       t = constraintExprData_termGetTerm (c->data);
1062       t = constraintTerm_copy(t);
1063       t = constraintTerm_setFileloc (t, loc);
1064       c->data = constraintExprData_termSetTerm (c->data, t);
1065       break;
1066     case binaryexpr:
1067       
1068       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1069       temp = constraintExpr_copy(temp);
1070       temp = constraintExpr_setFileloc (temp, loc);
1071       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1072       
1073       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1074       temp = constraintExpr_copy(temp);
1075       temp = constraintExpr_setFileloc (temp, loc);
1076       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1077       break;
1078     case unaryExpr:
1079       temp = constraintExprData_unaryExprGetExpr (c->data);
1080       temp = constraintExpr_copy(temp);
1081       temp = constraintExpr_setFileloc (temp, loc);
1082       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1083       break;
1084     }
1085   return c;
1086 }
1087
1088 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/constraintExpr c)
1089 {
1090   constraintExpr e1, e2;
1091   constraintExprBinaryOpKind  op;
1092   
1093   e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1094   e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1095
1096   if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1097     {
1098       long i;
1099
1100       i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1101       constraintExpr_free(c);
1102       c = constraintExpr_makeIntLiteral (i);
1103     }
1104   else
1105     {
1106       op = constraintExprData_binaryExprGetOp (c->data);      
1107       if (op == MINUS)
1108         if (constraintExpr_similar(e1, e2) )
1109           {
1110             constraintExpr_free(c);
1111             c =  constraintExpr_makeIntLiteral (0);
1112           }
1113     }
1114   
1115   return c;
1116 }
1117
1118 /*
1119   this thing takes the lexpr and expr of a constraint and modifies lexpr
1120   and returns a (possiblly new) value for expr
1121 */
1122 /* if lexpr is a binary express say x + y, we set lexpr to x and return a value for expr such as expr_old - y */
1123
1124 /* the approach is a little Kludgy but seems to work.  I should probably use something cleaner at some point ... */
1125
1126
1127 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1128 {
1129   constraintExpr expr1, expr2;
1130   constraintExprBinaryOpKind op;
1131   
1132   if (lexpr->kind != binaryexpr)
1133     return expr;
1134
1135   expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1136   expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1137
1138   op    = constraintExprData_binaryExprGetOp (lexpr->data);
1139
1140   expr1 = constraintExpr_copy(expr1);
1141   expr2 = constraintExpr_copy(expr2);
1142
1143 //drl possible problem : warning make sure this works
1144     
1145     lexpr->kind = expr1->kind;
1146     free (lexpr->data);
1147
1148     lexpr->data = copyExprData (expr1->data, expr1->kind);
1149     constraintExpr_free(expr1);
1150     
1151     if (op == PLUS)
1152       expr = constraintExpr_makeSubtractExpr (expr, expr2);
1153     else if (op == MINUS)
1154       expr = constraintExpr_makeAddExpr (expr, expr2);
1155     else
1156       BADEXIT;
1157
1158     
1159     return expr;
1160
1161   /*
1162     #warning this needs to be checked
1163     expr = constraintExpr_solveBinaryExpr (expr1, expr);
1164     
1165     expr = constraintExpr_solveBinaryExpr (expr2, expr);
1166     return expr;
1167   */
1168 }
1169
1170 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1171 {
1172   constraintExpr exp;
1173   
1174   llassert (c->kind == unaryExpr);
1175
1176   DPRINTF ( (message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1177   
1178   if ( (constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1179        (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1180     {
1181       return c;
1182     }
1183   // pattern mxr ( var + const) = mxr(var) - const
1184   
1185   exp = constraintExprData_unaryExprGetExpr (c->data);
1186
1187   if (exp->kind == term)
1188     {
1189       constraintTerm cterm;
1190
1191       cterm = constraintExprData_termGetTerm (exp->data);
1192       
1193       if (constraintTerm_isStringLiteral(cterm) )
1194         {
1195           cstring val;
1196           val = constraintTerm_getStringLiteral (cterm);
1197           if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1198             {
1199               constraintExpr temp;
1200
1201               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1202               cstring_free(val);              
1203               constraintExpr_free(c);
1204               return temp;
1205             }
1206           if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1207             {
1208               constraintExpr temp;
1209
1210               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1211               cstring_free(val);              
1212               constraintExpr_free(c);
1213               return temp;
1214             }
1215           BADEXIT;
1216         }
1217       return c;
1218     }
1219   
1220   if (exp->kind != binaryexpr)
1221     return c;
1222
1223   if (constraintExprData_binaryExprGetOp (exp->data) == PLUS  )
1224     {
1225  
1226       //      if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) )
1227         {
1228         
1229           constraintExpr  temp, temp2;
1230
1231           DPRINTF ( (message ("Doing fancy simplification") ) );
1232
1233           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1234
1235           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1236
1237           temp2 = constraintExpr_copy(temp2);
1238           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1239           
1240           
1241           temp = constraintExpr_copy (temp);
1242
1243           c = constraintExpr_makeSubtractExpr (c, temp);
1244
1245           DPRINTF ( (message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1246         }
1247     }
1248   
1249   DPRINTF ( (message ("Done simplification:%s", constraintExpr_unparse (c) ) ) );
1250   return c;
1251 }
1252
1253
1254 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1255 {
1256   constraintExprKind kind;
1257   constraintExpr ret;
1258   constraintTerm t;
1259   
1260   DPRINTF ( (message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1261   
1262
1263   /*@i22*/
1264   
1265   /*I think this is an LCLint bug */
1266
1267   ret =  constraintExpr_copy(c);
1268
1269   constraintExpr_free(c);
1270
1271   ret = constraintExpr_simplifyChildren (ret);
1272
1273   ret = constraintExpr_combineConstants (ret);
1274   
1275   ret = constraintExpr_simplifyChildren (ret);
1276   
1277
1278   kind = ret->kind;
1279   
1280   switch (kind)
1281     {
1282     case term:
1283       t = constraintExprData_termGetTerm (ret->data);
1284       t = constraintTerm_copy(t);
1285       t = constraintTerm_simplify (t);
1286       ret->data = constraintExprData_termSetTerm (ret->data, t);
1287       break;      
1288     case unaryExpr:
1289       ret = constraintExpr_simplifyunaryExpr (ret);
1290       break;           
1291     case binaryexpr:
1292       ret = constraintExpr_simplifybinaryExpr (ret);      
1293       break;
1294     default:
1295       llassert(FALSE);
1296     }    
1297   
1298   DPRINTF ( (message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );  
1299   return ret;
1300   
1301 }
1302
1303 /*@only@*/
1304 cstring constraintExpr_unparse (/*@temp@*/ /*@observer@*/ constraintExpr ex) /*@*/
1305 {
1306   cstring st;
1307   constraintExprKind kind;
1308
1309   llassert (ex != NULL);
1310
1311   kind = ex->kind;
1312   
1313   switch (kind)
1314     {
1315     case term:
1316       st = message ("(%q) ", constraintTerm_print (constraintExprData_termGetTerm (ex->data)));
1317       break;
1318     case unaryExpr:
1319       st = message ("%q (%q)",
1320                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data)
1321                                                      ),
1322                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1323                     );
1324       break;
1325     case binaryexpr:
1326       st = message ("(%q) %q (%q)",
1327                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1328                     constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1329                                                      ),
1330                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1331                     );
1332       break;
1333     default:
1334       llassert(FALSE);
1335       st = message ("error");
1336       
1337     }
1338
1339   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1340   return st;
1341 }
1342
1343 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1344 {
1345   constraintTerm Term;
1346   constraintExprKind kind;
1347   constraintExpr expr1, expr2;
1348   constraintExprData data;
1349   llassert (expr != NULL);
1350
1351   data = expr->data;
1352   
1353   kind = expr->kind;
1354   
1355   switch (kind)
1356     {
1357     case term:
1358       Term = constraintExprData_termGetTerm(data);
1359       Term = constraintTerm_copy(Term);
1360
1361       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1362       data = constraintExprData_termSetTerm(data, Term);
1363       break;
1364     case unaryExpr:
1365       expr1 = constraintExprData_unaryExprGetExpr (data);
1366       expr1 = constraintExpr_copy(expr1);
1367
1368       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1369       data = constraintExprData_unaryExprSetExpr (data, expr1);
1370       break;
1371     case binaryexpr:
1372       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1373       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1374       
1375       expr1 = constraintExpr_copy(expr1);
1376       expr2 = constraintExpr_copy(expr2);
1377
1378       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1379       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1380       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1381       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1382       
1383       break;
1384     default:
1385       llassert(FALSE);
1386       data = NULL;
1387     }
1388   return expr;
1389 }
1390
1391 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1392 {
1393   constraintExprKind kind;
1394   constraintExpr expr1, expr2;
1395   constraintExprData data;
1396   llassert (expr != NULL);
1397
1398   data = expr->data;
1399   
1400   kind = expr->kind;
1401   
1402   switch (kind)
1403     {
1404     case term:
1405       expr = doSRefFixConstraintParamTerm (expr, arglist);
1406       break;
1407     case unaryExpr:
1408       expr1 = constraintExprData_unaryExprGetExpr (data);
1409       expr1 = constraintExpr_copy(expr1);
1410       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1411       data = constraintExprData_unaryExprSetExpr (data, expr1);
1412       break;
1413     case binaryexpr:
1414       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1415       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1416       
1417       expr1 = constraintExpr_copy(expr1);
1418       expr2 = constraintExpr_copy(expr2);
1419
1420       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1421       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1422       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1423       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1424       
1425       break;
1426     default:
1427       llassert(FALSE);
1428       data = NULL;
1429     }
1430   return expr;
1431 }
1432
1433 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/  constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1434 {
1435   constraintExprKind kind;
1436   constraintExpr expr1, expr2;
1437   constraintExprData data;
1438   llassert (expr != NULL);
1439
1440   data = expr->data;
1441   
1442   kind = expr->kind;
1443   
1444   switch (kind)
1445     {
1446     case term:
1447       expr = doFixResultTerm (expr, fcnCall);
1448       break;
1449     case unaryExpr:
1450       expr1 = constraintExprData_unaryExprGetExpr (data);
1451       expr1 = constraintExpr_copy(expr1);
1452
1453       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1454       data = constraintExprData_unaryExprSetExpr (data, expr1);
1455       break;
1456     case binaryexpr:
1457       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1458       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1459       
1460       expr1 = constraintExpr_copy(expr1);
1461       expr2 = constraintExpr_copy(expr2);
1462
1463       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1464       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1465       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1466       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1467       
1468       break;
1469     default:
1470       llassert(FALSE);
1471       data = NULL;
1472     }
1473   return expr;
1474 }
1475
1476 cstring constraintExpr_print (constraintExpr expr) /*@*/
1477 {
1478   return constraintExpr_unparse (expr);
1479 }
1480
1481 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1482 {
1483   cstring t;
1484
1485   t = constraintExpr_unparse(expr);
1486
1487   if (cstring_containsLit(t, "maxSet") != NULL )
1488     {
1489       cstring_free(t);
1490       return (TRUE);
1491     }
1492   else
1493     {
1494       cstring_free(t);
1495       return FALSE;
1496     }
1497 }
1498
1499
1500
1501       /*returns 1 0 -1 like strcmp
1502         1 => expr1 > expr2
1503         0 => expr1 == expr2
1504         -1 => expr1 < expr2
1505        */
1506
1507 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1508 {
1509   long value1, value2;
1510
1511   if (constraintExpr_similar (expr1, expr2) )
1512     {
1513       return 0;
1514     }
1515   
1516   value1 = constraintExpr_getValue(expr1);
1517   value2 = constraintExpr_getValue(expr2);
1518
1519   if (value1 > value2)
1520     return 1;
1521
1522   if (value1 == value2)
1523     return 0;
1524
1525   else
1526     return -1;
1527 }
1528
1529 long constraintExpr_getValue (constraintExpr expr)
1530 {
1531   llassert (expr->kind == term);
1532   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1533 }
1534
1535 bool constraintExpr_canGetValue (constraintExpr expr)
1536 {
1537   switch (expr->kind)
1538     {
1539     case term:
1540       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1541     default:
1542       return FALSE;
1543       
1544     }
1545
1546   BADEXIT;
1547 }
1548
1549 fileloc constraintExpr_getFileloc (constraintExpr expr)
1550 {
1551   constraintExpr e;
1552 constraintTerm t;
1553   constraintExprKind kind;
1554
1555  kind = expr->kind;
1556   
1557   switch (kind)
1558     {
1559     case term:
1560       t = constraintExprData_termGetTerm (expr->data);
1561       return (constraintTerm_getFileloc (t) );
1562       /*@notreached@*/
1563       break;      
1564     case unaryExpr:
1565       e = constraintExprData_unaryExprGetExpr (expr->data);
1566       return (constraintExpr_getFileloc (e) );
1567       /*@notreached@*/
1568       break;           
1569     case binaryexpr:
1570       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1571       return (constraintExpr_getFileloc (e) );
1572       /*@notreached@*/
1573       break;
1574     }
1575   llassert (FALSE);
1576   return (fileloc_undefined);
1577 }
1578
1579 /*drl moved from constriantTerm.c 5/20/001*/
1580 static /*@only@*/ constraintExpr 
1581 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1582 {
1583   constraintTerm t;
1584   sRef s;
1585   /*maybe this should move to cosntraintExpr.c -drl7x 5/18/01*/
1586   /*@i22*/ constraintExprData data = e->data;
1587   
1588   /*@i22*/constraintExprKind kind = e->kind;
1589   
1590   constraintExpr ret;
1591
1592   llassert(kind == term);
1593
1594   t = constraintExprData_termGetTerm (data);
1595   llassert (constraintTerm_isDefined(t) );
1596
1597   ret = e;
1598   switch (constraintTerm_getKind(t) )
1599     {
1600     case EXPRNODE:
1601       break;
1602     case INTLITERAL:
1603       break;
1604       
1605     case SREF:
1606       s = constraintTerm_getSRef(t);
1607       if (sRef_isResult (s))
1608         {
1609           ret = constraintExpr_makeExprNode(fcnCall);
1610           constraintExpr_free(e);
1611           e = NULL;
1612         }
1613       else
1614         {
1615           e = NULL;
1616         }
1617       break;
1618     default:
1619       BADEXIT;
1620     }
1621   
1622   return ret;
1623   
1624 }
1625
1626 /*drl moved from constriantTerm.c 5/20/001*/
1627 /*@only@*/ static constraintExpr 
1628 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
1629 {
1630   constraintTerm t;
1631
1632   constraintExprData data = e->data;
1633   
1634   constraintExprKind kind = e->kind;
1635   
1636   constraintExpr ret;
1637
1638   llassert(kind == term);
1639
1640   t = constraintExprData_termGetTerm (data);
1641   llassert (constraintTerm_isDefined(t) );
1642
1643   ret = e;
1644
1645   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1646
1647   switch (constraintTerm_getKind(t))
1648     {
1649     case EXPRNODE:
1650       DPRINTF((message ("%q @ %q ", constraintTerm_print(t),
1651                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1652       break;
1653     case INTLITERAL:
1654       DPRINTF((message (" %q ", constraintTerm_print (t)) ));
1655       break;
1656       
1657     case SREF:
1658       /* evans 2001-07-24: constants should use the original term */
1659       if (!constraintTerm_canGetValue (t))
1660         {
1661           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
1662                              constraintTerm_print (t) ) ));
1663           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
1664           
1665           constraintExpr_free (e);
1666           
1667           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
1668                              constraintExpr_print (ret) ) ));
1669           /*@-branchstate@*/
1670         } /*@=branchstate@*/
1671
1672       break;
1673     default:
1674       BADEXIT;
1675     }
1676
1677   return ret;
1678   
1679 }
1680
1681
1682 /* bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term) */
1683 /* { */
1684 /*   if (constraintTerm_hasTerm (expr->term, term) ) */
1685 /*     return TRUE; */
1686
1687 /*   if ( (expr->expr) != NULL) */
1688 /*     { */
1689 /*       return ( constraintExpr_includesTerm (expr->expr, term) ); */
1690 /*     } */
1691 /*   return FALSE; */
1692
1693 /* } */
1694
1695 /*drl added 6/11/01 */
1696 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
1697 {
1698   if (c->kind == binaryexpr)
1699     return TRUE;
1700
1701   else
1702     return FALSE;
1703 }
1704
1705 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
1706 {
1707   constraintExpr expr1;
1708   constraintExprBinaryOpKind binaryOp;
1709   constraintExpr expr2;
1710
1711
1712   binaryOp = constraintExprData_binaryExprGetOp (data);
1713
1714   fprintf(f, "%d\n", (int) binaryOp);
1715   
1716   expr1 = constraintExprData_binaryExprGetExpr1 (data);
1717   expr2 = constraintExprData_binaryExprGetExpr2 (data);
1718
1719   fprintf(f, "e1\n");
1720
1721   constraintExpr_dump(expr1, f);
1722
1723   fprintf(f, "e2\n");
1724   constraintExpr_dump(expr2, f);
1725 }
1726
1727
1728 static constraintExpr  binaryExpr_undump (FILE *f)
1729 {
1730   constraintExpr expr1;
1731   constraintExprBinaryOpKind binaryOp;
1732   constraintExpr expr2;
1733
1734   constraintExpr ret;
1735
1736   
1737
1738   char * str;
1739   char * os;
1740
1741   str = mstring_create (MAX_DUMP_LINE_LENGTH);
1742   os = str;
1743   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1744
1745   
1746   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
1747   
1748   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1749
1750   reader_checkChar (&str, 'e');
1751   reader_checkChar (&str, '1');
1752   
1753   expr1 = constraintExpr_undump (f);
1754
1755   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1756
1757   reader_checkChar (&str, 'e');
1758   reader_checkChar (&str, '2');  
1759
1760   expr2 = constraintExpr_undump (f);
1761
1762   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
1763   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
1764
1765   free(os);
1766   return ret;
1767 }
1768
1769
1770
1771 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
1772 {
1773
1774   constraintExpr expr;
1775   constraintExprUnaryOpKind unaryOp;
1776
1777   unaryOp = constraintExprData_unaryExprGetOp (data);
1778
1779   fprintf(f, "%d\n", (int) unaryOp);
1780   
1781   expr = constraintExprData_unaryExprGetExpr (data);
1782
1783   constraintExpr_dump(expr, f);  
1784 }
1785
1786 static  constraintExpr  unaryExpr_undump ( FILE *f)
1787 {
1788
1789   constraintExpr expr;
1790   constraintExprUnaryOpKind unaryOp;
1791   constraintExpr ret;
1792   
1793   char * str;
1794   char * os;
1795
1796   str = mstring_create (MAX_DUMP_LINE_LENGTH);
1797   os = str;
1798   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1799
1800   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
1801   
1802   expr = constraintExpr_undump (f);
1803
1804   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
1805
1806   free(os);
1807   
1808   return ret;
1809 }
1810
1811 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
1812 {
1813   constraintExprKind kind;
1814   constraintTerm t;
1815   
1816   
1817   kind = expr->kind;
1818   
1819   fprintf(f,"%d\n", (int) kind);
1820   
1821   switch (kind)
1822     {
1823     case term:
1824       t = constraintExprData_termGetTerm (expr->data);
1825       constraintTerm_dump (t, f);
1826       break;      
1827     case unaryExpr:
1828       unaryExpr_dump (expr->data, f);
1829       break;           
1830     case binaryexpr:
1831       binaryExpr_dump  (expr->data, f);
1832       break;
1833     }  
1834 }
1835
1836 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
1837 {
1838   constraintExprKind kind;
1839   constraintTerm t;
1840   constraintExpr ret;
1841   
1842   char * s;
1843   char * os;
1844   
1845   s = mstring_create (MAX_DUMP_LINE_LENGTH);
1846
1847   os = s;
1848   
1849   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1850
1851   kind = (constraintExprKind) reader_getInt(&s);
1852
1853   free (os);
1854   
1855   switch (kind)
1856     {
1857     case term:
1858       t = constraintTerm_undump (f);
1859       ret = constraintExpr_makeTerm(t);
1860       break;      
1861     case unaryExpr:
1862       ret = unaryExpr_undump (f);
1863       break;           
1864     case binaryexpr:
1865       ret = binaryExpr_undump  (f);
1866       break;
1867     }
1868
1869   return ret;
1870
1871 }
This page took 0.17625 seconds and 5 git commands to generate.