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