]> andersk Git - splint.git/blob - src/constraintExpr.c
Added klugdy support for malloc (sizeof type * expr) type statement.
[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 /*@only@*/
654 /*@unused@*/ static constraintExpr  constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
655 {
656   constraintExpr ret;
657   ret = constraintExpr_makeUnaryOpExprNode(expr);
658   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINSET);
659   return ret;
660 }
661
662 /*@only@*/
663 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
664 {
665   constraintExpr ret;
666   ret = constraintExpr_makeUnaryOpExprNode(expr);
667   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
668   return ret;
669 }
670
671
672 /*@only@*/
673 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
674 {
675   constraintExpr ret;
676   ret = constraintExpr_makeExprNode (expr);
677   return ret;
678 }
679
680 /*@only@*/
681 constraintExpr constraintExpr_makeIntLiteral (long i)
682 {
683   constraintExpr ret;
684   constraintTerm t;
685   ret = constraintExpr_alloc();
686   ret->kind = term;
687   ret->data = dmalloc (sizeof *(ret->data) );
688   t = constraintTerm_makeIntLiteral (i);
689   ret->data = constraintExprData_termSetTerm (ret->data, t);
690   return ret;
691 }
692
693 /*
694 constraintExpr constraintExpr_makeValueInt (int i)
695 {
696   return constraintExpr_makeIntLiteral (i);
697 }
698 */
699
700 /*@only@*/
701  /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
702       /*@allocates result->data @*/ /*@sets result->kind @*/
703 {
704   constraintExpr ret;
705   ret = constraintExpr_alloc();
706   ret->kind = binaryexpr;
707   ret->data = dmalloc ( sizeof *(ret->data) );
708
709   ret->data->binaryOp.expr1 = constraintExpr_undefined;
710   ret->data->binaryOp.expr2 = constraintExpr_undefined;
711   
712   //  ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
713   return ret;
714 }
715
716
717 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
718      
719 {
720   constraintExpr ret;
721
722   ret = constraintExpr_makeBinaryOp();
723   ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
724   ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
725   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
726   return ret;
727 }
728
729 /*@only@*/
730 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
731 {
732   constraintExpr ret;
733   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
734   if (op.tok == TPLUS)
735     ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
736   else if (op.tok == TMINUS)
737     ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
738     else
739       {
740         llassert(FALSE);
741       }
742   return ret;
743 }
744
745 /*@only@*/
746 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
747 {
748   constraintExpr ret;
749   constraintExpr sub1, sub2;
750   sub1 = constraintExpr_makeTermExprNode (expr1);
751   sub2 = constraintExpr_makeTermExprNode (expr2);
752   ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
753   return ret;
754 }
755
756 static /*@only@*/
757 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
758 {
759   constraintExpr ret;
760   constraintExpr constExpr;
761
762   constExpr = constraintExpr_makeIntLiteral (literal);
763   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
764   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
765   return ret;
766 }
767
768 /*@only@*/
769 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
770 {
771   constraintExpr ret;
772   constraintExpr inc;
773
774   inc = constraintExpr_makeIntLiteral (1);
775   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
776   ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
777   return ret;
778 }
779
780
781 /*@only@*/  constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
782 {
783   constraintExpr  ret;
784   
785   DPRINTF ( (message ("Making  subtract expression") ) );
786
787   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
788   ret->data = constraintExprData_binaryExprSetOp (ret->data, MINUS);
789   return ret;
790 }
791
792 /*@only@*/
793 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
794 constraintExpr expr, /*@only@*/
795 constraintExpr addent)
796 {
797   constraintExpr  ret;
798   
799   DPRINTF ( (message ("Doing addTerm simplification") ) );
800
801   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
802   ret->data = constraintExprData_binaryExprSetOp (ret->data, PLUS);
803   return ret;
804 }
805
806
807 /*@only@*/
808 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
809 {
810   constraintExpr ret;
811   constraintExpr inc;
812
813   inc = constraintExpr_makeIntLiteral (1);
814   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
815   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
816   return ret;
817 }
818
819 /*@only@*/
820 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
821 {
822   switch (op)
823     {
824     case MAXSET:
825       return message("maxSet");
826     case MINSET:
827       return message("minSet");
828     case MAXREAD:
829       return message("maxRead");
830     case MINREAD:
831       return message("minRead");
832     default:
833       llassert(FALSE);
834       return message ("<(Unary OP OTHER>");
835     }
836 }
837
838
839 /*@only@*/
840 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
841 {
842   
843   switch (op)
844     {
845     case PLUS:
846       return message("+");
847     case MINUS:
848       return message("-");
849
850     default:
851       llassert(FALSE);
852       return message ("<binary OP Unknown>");
853     }
854 }
855
856 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
857 {
858   constraintExprKind kind;
859   
860   llassert (expr1 != NULL);
861   llassert (expr2 != NULL);
862   if (expr1->kind != expr2->kind)
863     return FALSE;
864   
865   kind = expr1->kind;
866   
867   switch (kind)
868     {
869     case term:
870       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
871                                   constraintExprData_termGetTerm(expr2->data) );
872       /*@notreached@*/ break;
873       
874     case unaryExpr:
875       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
876         return FALSE;
877       
878       return (constraintExpr_similar (
879               constraintExprData_unaryExprGetExpr (expr1->data),
880               constraintExprData_unaryExprGetExpr (expr2->data)
881               ));
882       
883     case binaryexpr:
884       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
885         return FALSE;
886       
887       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
888                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
889         return FALSE;
890       
891       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
892                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
893         return FALSE;
894       else
895         return TRUE;
896       /*@notreached@*/
897       break;
898       
899     default:
900       llassert(FALSE);
901       return FALSE;
902     }
903   /*@notreached@*/
904   return FALSE;
905 }
906
907 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
908 {
909   constraintExprKind kind;
910   
911   llassert (expr1 != NULL);
912   llassert (expr2 != NULL);
913   if (expr1->kind != expr2->kind)
914     return FALSE;
915   
916   kind = expr1->kind;
917   
918   switch (kind)
919     {
920     case term:
921       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
922                                   constraintExprData_termGetTerm(expr2->data) );
923       /*@notreached@*/ break;
924       
925     case unaryExpr:
926       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
927         return FALSE;
928
929       return (constraintExpr_same (
930               constraintExprData_unaryExprGetExpr (expr1->data),
931               constraintExprData_unaryExprGetExpr (expr2->data)
932               ));
933       
934             
935     case binaryexpr:
936       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
937         return FALSE;
938       
939       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
940                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
941         return FALSE;
942       
943       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
944                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
945         return FALSE;
946       else
947         return TRUE;
948       /*@notreached@*/ break;
949       
950     default:
951       llassert(FALSE);
952       return FALSE;
953     }
954
955   /*@notreached@*/
956   BADEXIT;
957 }
958
959 bool constraintExpr_search (/*@observer@*/ constraintExpr c, /*@observer@*/ constraintExpr old)
960 {
961   bool ret = FALSE;
962   constraintExprKind kind;
963   constraintExpr temp;
964   
965   if ( constraintExpr_similar (c, old) )
966     {
967       DPRINTF((message ("Found  %q",
968                         constraintExpr_unparse(old)
969                         )));
970       return TRUE;
971     }
972
973   kind = c->kind;
974   
975   switch (kind)
976     {
977     case term:
978       break;      
979     case unaryExpr:
980       temp = constraintExprData_unaryExprGetExpr (c->data);
981       ret = ret || constraintExpr_search (temp, old);
982       break;           
983     case binaryexpr:
984       
985       temp = constraintExprData_binaryExprGetExpr1 (c->data);
986       ret = ret || constraintExpr_search(temp, old);
987            
988       temp = constraintExprData_binaryExprGetExpr2 (c->data);
989       ret = ret || constraintExpr_search(temp, old);
990       break;
991     default:
992       llassert(FALSE);
993     }
994   return ret;
995   
996 }
997
998
999 /*@only@*/ constraintExpr constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old, /*@temp@*/ constraintExpr newExpr )
1000 {
1001   constraintExprKind kind;
1002   constraintExpr temp;
1003   
1004   if ( constraintExpr_similar (c, old) )
1005     {
1006
1007       DPRINTF((message ("Replacing %s with %s",
1008                         constraintExpr_unparse(old), constraintExpr_unparse(newExpr)
1009                         )));
1010       constraintExpr_free(c);
1011       return constraintExpr_copy (newExpr);
1012     }
1013
1014   kind = c->kind;
1015   
1016   switch (kind)
1017     {
1018     case term:
1019       break;      
1020     case unaryExpr:
1021       temp = constraintExprData_unaryExprGetExpr (c->data);
1022       temp = constraintExpr_copy(temp);
1023       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1024       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1025       break;           
1026     case binaryexpr:
1027       
1028       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1029       temp = constraintExpr_copy(temp);
1030       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1031       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1032        
1033       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1034       temp = constraintExpr_copy(temp);
1035       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1036       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1037       break;
1038     default:
1039       llassert(FALSE);
1040     }
1041   return c;
1042   
1043 }
1044
1045 static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ constraintExpr c)
1046 {
1047   constraintExprKind kind;
1048   constraintExpr temp;
1049
1050   kind = c->kind;
1051   
1052   switch (kind)
1053     {
1054     case term:
1055       break;      
1056     case unaryExpr:
1057       temp = constraintExprData_unaryExprGetExpr (c->data);
1058       temp = constraintExpr_copy(temp);
1059       temp = constraintExpr_simplify (temp);
1060       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1061       break;           
1062     case binaryexpr:
1063       DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1064       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1065       temp = constraintExpr_copy(temp);
1066       temp = constraintExpr_simplify (temp);
1067
1068       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1069        
1070       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1071       temp = constraintExpr_copy(temp);
1072       temp = constraintExpr_simplify (temp);
1073
1074       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1075       break;
1076     default:
1077       llassert(FALSE);
1078     }
1079   return c;
1080   
1081 }
1082
1083
1084 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1085 {
1086   constraintTerm t;
1087   constraintExpr temp;
1088
1089   llassert(c != NULL);
1090   
1091   switch (c->kind)
1092     {
1093     case term:
1094       t = constraintExprData_termGetTerm (c->data);
1095       t = constraintTerm_copy(t);
1096       t = constraintTerm_setFileloc (t, loc);
1097       c->data = constraintExprData_termSetTerm (c->data, t);
1098       break;
1099     case binaryexpr:
1100       
1101       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1102       temp = constraintExpr_copy(temp);
1103       temp = constraintExpr_setFileloc (temp, loc);
1104       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1105       
1106       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1107       temp = constraintExpr_copy(temp);
1108       temp = constraintExpr_setFileloc (temp, loc);
1109       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1110       break;
1111     case unaryExpr:
1112       temp = constraintExprData_unaryExprGetExpr (c->data);
1113       temp = constraintExpr_copy(temp);
1114       temp = constraintExpr_setFileloc (temp, loc);
1115       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1116       break;
1117     }
1118   return c;
1119 }
1120
1121 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/constraintExpr c)
1122 {
1123   constraintExpr e1, e2;
1124   constraintExprBinaryOpKind  op;
1125   
1126   e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1127   e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1128
1129   if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1130     {
1131       long i;
1132
1133       i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1134       constraintExpr_free(c);
1135       c = constraintExpr_makeIntLiteral (i);
1136     }
1137   else
1138     {
1139       op = constraintExprData_binaryExprGetOp (c->data);      
1140       if (op == MINUS)
1141         if (constraintExpr_similar(e1, e2) )
1142           {
1143             constraintExpr_free(c);
1144             c =  constraintExpr_makeIntLiteral (0);
1145           }
1146     }
1147   
1148   return c;
1149 }
1150
1151 /*
1152   this thing takes the lexpr and expr of a constraint and modifies lexpr
1153   and returns a (possiblly new) value for expr
1154 */
1155 /* 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 */
1156
1157 /* the approach is a little Kludgy but seems to work.  I should probably use something cleaner at some point ... */
1158
1159
1160 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1161 {
1162   constraintExpr expr1, expr2;
1163   constraintExprBinaryOpKind op;
1164   
1165   if (lexpr->kind != binaryexpr)
1166     return expr;
1167
1168   expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1169   expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1170
1171   op    = constraintExprData_binaryExprGetOp (lexpr->data);
1172
1173   expr1 = constraintExpr_copy(expr1);
1174   expr2 = constraintExpr_copy(expr2);
1175
1176 //drl possible problem : warning make sure this works
1177     
1178     lexpr->kind = expr1->kind;
1179     free (lexpr->data);
1180
1181     lexpr->data = copyExprData (expr1->data, expr1->kind);
1182     constraintExpr_free(expr1);
1183     
1184     if (op == PLUS)
1185       expr = constraintExpr_makeSubtractExpr (expr, expr2);
1186     else if (op == MINUS)
1187       expr = constraintExpr_makeAddExpr (expr, expr2);
1188     else
1189       BADEXIT;
1190
1191     
1192     return expr;
1193
1194   /*
1195     #warning this needs to be checked
1196     expr = constraintExpr_solveBinaryExpr (expr1, expr);
1197     
1198     expr = constraintExpr_solveBinaryExpr (expr2, expr);
1199     return expr;
1200   */
1201 }
1202
1203 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1204 {
1205   constraintExpr exp;
1206   
1207   llassert (c->kind == unaryExpr);
1208
1209   DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1210   
1211   if ( (constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1212        (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1213     {
1214       return c;
1215     }
1216   // pattern mxr ( var + const) = mxr(var) - const
1217   
1218   exp = constraintExprData_unaryExprGetExpr (c->data);
1219   exp = constraintExpr_copy(exp);
1220   
1221   if (exp->kind == term)
1222     {
1223       constraintTerm cterm;
1224
1225       cterm = constraintExprData_termGetTerm (exp->data);
1226       
1227       if (constraintTerm_isStringLiteral(cterm) )
1228         {
1229           cstring val;
1230           val = constraintTerm_getStringLiteral (cterm);
1231           if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1232             {
1233               constraintExpr temp;
1234
1235               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1236               cstring_free(val);              
1237               constraintExpr_free(c);
1238               constraintExpr_free(exp);
1239
1240               return temp;
1241               
1242             }
1243           if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1244             {
1245               constraintExpr temp;
1246
1247               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1248               cstring_free(val);              
1249               constraintExpr_free(c);
1250               constraintExpr_free(exp);
1251
1252               return temp;
1253             }
1254           BADEXIT;
1255         }
1256
1257       // slight Kludge to hanlde var [] = { , , };
1258       // type syntax  I don't think this is sounds but it should be good
1259       // enough.  The C stanrad is very confusing about initialization
1260       // -- DRL 7/25/01
1261       
1262       if (constraintTerm_isInitBlock(cterm) )
1263         {
1264           constraintExpr temp;
1265           int len;
1266
1267           len = constraintTerm_getInitBlockLength(cterm);
1268
1269           temp = constraintExpr_makeIntLiteral (len );
1270           
1271           constraintExpr_free(c);
1272           DPRINTF(( message("Changed too %q", constraintExpr_print(temp)
1273                             ) ));
1274           constraintExpr_free(exp);
1275           return temp;
1276         }
1277       
1278       constraintExpr_free(exp);
1279       return c;
1280     }
1281   
1282   if (exp->kind != binaryexpr)
1283     {
1284       constraintExpr_free(exp);
1285       return c;
1286     }
1287   
1288   if (constraintExprData_binaryExprGetOp (exp->data) == PLUS  )
1289     {
1290  
1291       //      if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) )
1292         {
1293         
1294           constraintExpr  temp, temp2;
1295
1296           DPRINTF ( (message ("Doing fancy simplification") ) );
1297
1298           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1299
1300           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1301
1302           temp2 = constraintExpr_copy(temp2);
1303           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1304           
1305           
1306           temp = constraintExpr_copy (temp);
1307
1308           c = constraintExpr_makeSubtractExpr (c, temp);
1309
1310           DPRINTF ( (message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1311         }
1312     }
1313   
1314   DPRINTF ( (message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1315
1316   constraintExpr_free(exp);
1317   return c;
1318 }
1319
1320
1321 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1322 {
1323   constraintExprKind kind;
1324   constraintExpr ret;
1325   constraintTerm t;
1326   
1327   DPRINTF ( (message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1328   
1329
1330   /*@i22*/
1331   
1332   /*I think this is an LCLint bug */
1333
1334   ret =  constraintExpr_copy(c);
1335
1336   constraintExpr_free(c);
1337
1338   ret = constraintExpr_simplifyChildren (ret);
1339
1340   ret = constraintExpr_combineConstants (ret);
1341   
1342   ret = constraintExpr_simplifyChildren (ret);
1343   
1344
1345   kind = ret->kind;
1346   
1347   switch (kind)
1348     {
1349     case term:
1350       t = constraintExprData_termGetTerm (ret->data);
1351       t = constraintTerm_copy(t);
1352       t = constraintTerm_simplify (t);
1353       ret->data = constraintExprData_termSetTerm (ret->data, t);
1354       break;      
1355     case unaryExpr:
1356       ret = constraintExpr_simplifyunaryExpr (ret);
1357       break;           
1358     case binaryexpr:
1359       ret = constraintExpr_simplifybinaryExpr (ret);      
1360       break;
1361     default:
1362       llassert(FALSE);
1363     }    
1364   
1365   DPRINTF ( (message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );  
1366   return ret;
1367   
1368 }
1369
1370 /*@only@*/
1371 cstring constraintExpr_unparse (/*@temp@*/ /*@observer@*/ constraintExpr ex) /*@*/
1372 {
1373   cstring st;
1374   constraintExprKind kind;
1375
1376   llassert (ex != NULL);
1377
1378   kind = ex->kind;
1379   
1380   switch (kind)
1381     {
1382     case term:
1383
1384             if (context_getFlag (FLG_PARENCONSTRAINT) )
1385               {
1386                 st = message ("(%q) ", constraintTerm_print (constraintExprData_termGetTerm (ex->data)));
1387               }
1388             else
1389               {
1390                 st = message ("%q", constraintTerm_print (constraintExprData_termGetTerm (ex->data)));
1391               }
1392       break;
1393     case unaryExpr:
1394       st = message ("%q(%q)",
1395                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1396                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1397                     );
1398       break;
1399     case binaryexpr:
1400       if (context_getFlag (FLG_PARENCONSTRAINT) )
1401         {
1402           st = message ("(%q) %q (%q)",
1403                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1404                     constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1405                                                      ),
1406                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1407                     );
1408         }
1409       else
1410         {
1411           st = message ("%q %q %q",
1412                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1413                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1414                                                           ),
1415                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1416                         );
1417         }
1418       
1419       break;
1420     default:
1421       llassert(FALSE);
1422       st = message ("error");
1423       
1424     }
1425
1426   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1427   return st;
1428 }
1429
1430 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1431 {
1432   constraintTerm Term;
1433   constraintExprKind kind;
1434   constraintExpr expr1, expr2;
1435   constraintExprData data;
1436   llassert (expr != NULL);
1437
1438   data = expr->data;
1439   
1440   kind = expr->kind;
1441   
1442   switch (kind)
1443     {
1444     case term:
1445       Term = constraintExprData_termGetTerm(data);
1446       Term = constraintTerm_copy(Term);
1447
1448       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1449       data = constraintExprData_termSetTerm(data, Term);
1450       break;
1451     case unaryExpr:
1452       expr1 = constraintExprData_unaryExprGetExpr (data);
1453       expr1 = constraintExpr_copy(expr1);
1454
1455       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1456       data = constraintExprData_unaryExprSetExpr (data, expr1);
1457       break;
1458     case binaryexpr:
1459       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1460       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1461       
1462       expr1 = constraintExpr_copy(expr1);
1463       expr2 = constraintExpr_copy(expr2);
1464
1465       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1466       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1467       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1468       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1469       
1470       break;
1471     default:
1472       llassert(FALSE);
1473       data = NULL;
1474     }
1475   return expr;
1476 }
1477
1478 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1479 {
1480   constraintExprKind kind;
1481   constraintExpr expr1, expr2;
1482   constraintExprData data;
1483   llassert (expr != NULL);
1484
1485   data = expr->data;
1486   
1487   kind = expr->kind;
1488   
1489   switch (kind)
1490     {
1491     case term:
1492       expr = doSRefFixConstraintParamTerm (expr, arglist);
1493       break;
1494     case unaryExpr:
1495       expr1 = constraintExprData_unaryExprGetExpr (data);
1496       expr1 = constraintExpr_copy(expr1);
1497       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1498       data = constraintExprData_unaryExprSetExpr (data, expr1);
1499       break;
1500     case binaryexpr:
1501       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1502       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1503       
1504       expr1 = constraintExpr_copy(expr1);
1505       expr2 = constraintExpr_copy(expr2);
1506
1507       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1508       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1509       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1510       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1511       
1512       break;
1513     default:
1514       llassert(FALSE);
1515       data = NULL;
1516     }
1517   return expr;
1518 }
1519
1520 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/  constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1521 {
1522   constraintExprKind kind;
1523   constraintExpr expr1, expr2;
1524   constraintExprData data;
1525   llassert (expr != NULL);
1526
1527   data = expr->data;
1528   
1529   kind = expr->kind;
1530   
1531   switch (kind)
1532     {
1533     case term:
1534       expr = doFixResultTerm (expr, fcnCall);
1535       break;
1536     case unaryExpr:
1537       expr1 = constraintExprData_unaryExprGetExpr (data);
1538       expr1 = constraintExpr_copy(expr1);
1539
1540       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1541       data = constraintExprData_unaryExprSetExpr (data, expr1);
1542       break;
1543     case binaryexpr:
1544       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1545       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1546       
1547       expr1 = constraintExpr_copy(expr1);
1548       expr2 = constraintExpr_copy(expr2);
1549
1550       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1551       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1552       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1553       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1554       
1555       break;
1556     default:
1557       llassert(FALSE);
1558       data = NULL;
1559     }
1560   return expr;
1561 }
1562
1563 cstring constraintExpr_print (constraintExpr expr) /*@*/
1564 {
1565   return constraintExpr_unparse (expr);
1566 }
1567
1568 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1569 {
1570   cstring t;
1571
1572   t = constraintExpr_unparse(expr);
1573
1574   if (cstring_containsLit(t, "maxSet") != NULL )
1575     {
1576       cstring_free(t);
1577       return (TRUE);
1578     }
1579   else
1580     {
1581       cstring_free(t);
1582       return FALSE;
1583     }
1584 }
1585
1586
1587
1588       /*returns 1 0 -1 like strcmp
1589         1 => expr1 > expr2
1590         0 => expr1 == expr2
1591         -1 => expr1 < expr2
1592        */
1593
1594 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1595 {
1596   long value1, value2;
1597
1598   if (constraintExpr_similar (expr1, expr2) )
1599     {
1600       return 0;
1601     }
1602   
1603   value1 = constraintExpr_getValue(expr1);
1604   value2 = constraintExpr_getValue(expr2);
1605
1606   if (value1 > value2)
1607     return 1;
1608
1609   if (value1 == value2)
1610     return 0;
1611
1612   else
1613     return -1;
1614 }
1615
1616 long constraintExpr_getValue (constraintExpr expr)
1617 {
1618   llassert (expr->kind == term);
1619   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1620 }
1621
1622 bool constraintExpr_canGetValue (constraintExpr expr)
1623 {
1624   switch (expr->kind)
1625     {
1626     case term:
1627       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1628     default:
1629       return FALSE;
1630       
1631     }
1632
1633   BADEXIT;
1634 }
1635
1636 fileloc constraintExpr_getFileloc (constraintExpr expr)
1637 {
1638   constraintExpr e;
1639 constraintTerm t;
1640   constraintExprKind kind;
1641
1642  kind = expr->kind;
1643   
1644   switch (kind)
1645     {
1646     case term:
1647       t = constraintExprData_termGetTerm (expr->data);
1648       return (constraintTerm_getFileloc (t) );
1649       /*@notreached@*/
1650       break;      
1651     case unaryExpr:
1652       e = constraintExprData_unaryExprGetExpr (expr->data);
1653       return (constraintExpr_getFileloc (e) );
1654       /*@notreached@*/
1655       break;           
1656     case binaryexpr:
1657       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1658       return (constraintExpr_getFileloc (e) );
1659       /*@notreached@*/
1660       break;
1661     }
1662   llassert (FALSE);
1663   return (fileloc_undefined);
1664 }
1665
1666 /*drl moved from constriantTerm.c 5/20/001*/
1667 static /*@only@*/ constraintExpr 
1668 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1669 {
1670   constraintTerm t;
1671   sRef s;
1672   /*maybe this should move to cosntraintExpr.c -drl7x 5/18/01*/
1673   /*@i22*/
1674
1675   constraintExprData data = e->data;
1676   constraintExprKind kind = e->kind;
1677   
1678   constraintExpr ret;
1679
1680   llassert(kind == term);
1681
1682   t = constraintExprData_termGetTerm (data);
1683   llassert (constraintTerm_isDefined(t) );
1684
1685   ret = e;
1686   switch (constraintTerm_getKind(t) )
1687     {
1688     case EXPRNODE:
1689       break;
1690     case INTLITERAL:
1691       break;
1692       
1693     case SREF:
1694       s = constraintTerm_getSRef(t);
1695       if (sRef_isResult (s))
1696         {
1697           ret = constraintExpr_makeExprNode(fcnCall);
1698           constraintExpr_free(e);
1699           e = NULL;
1700         }
1701       else
1702         {
1703           e = NULL;
1704         }
1705       break;
1706     default:
1707       BADEXIT;
1708     }
1709   
1710   return ret;
1711   
1712 }
1713
1714 /*drl moved from constriantTerm.c 5/20/001*/
1715 /*@only@*/ static constraintExpr 
1716 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
1717 {
1718   constraintTerm t;
1719
1720   constraintExprData data = e->data;
1721   
1722   constraintExprKind kind = e->kind;
1723   
1724   constraintExpr ret;
1725
1726   llassert(kind == term);
1727
1728   t = constraintExprData_termGetTerm (data);
1729   llassert (constraintTerm_isDefined(t) );
1730
1731   ret = e;
1732
1733   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1734
1735   switch (constraintTerm_getKind(t))
1736     {
1737     case EXPRNODE:
1738       DPRINTF((message ("%q @ %q ", constraintTerm_print(t),
1739                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1740       break;
1741     case INTLITERAL:
1742       DPRINTF((message (" %q ", constraintTerm_print (t)) ));
1743       break;
1744       
1745     case SREF:
1746       /* evans 2001-07-24: constants should use the original term */
1747       if (!constraintTerm_canGetValue (t))
1748         {
1749           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
1750                              constraintTerm_print (t) ) ));
1751           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
1752           
1753           constraintExpr_free (e);
1754           
1755           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
1756                              constraintExpr_print (ret) ) ));
1757           /*@-branchstate@*/
1758         } /*@=branchstate@*/
1759
1760       break;
1761     default:
1762       BADEXIT;
1763     }
1764
1765   return ret;
1766   
1767 }
1768
1769
1770 /* bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term) */
1771 /* { */
1772 /*   if (constraintTerm_hasTerm (expr->term, term) ) */
1773 /*     return TRUE; */
1774
1775 /*   if ( (expr->expr) != NULL) */
1776 /*     { */
1777 /*       return ( constraintExpr_includesTerm (expr->expr, term) ); */
1778 /*     } */
1779 /*   return FALSE; */
1780
1781 /* } */
1782
1783 /*drl added 6/11/01 */
1784 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
1785 {
1786   if (c->kind == binaryexpr)
1787     return TRUE;
1788
1789   else
1790     return FALSE;
1791 }
1792
1793 /*drl added 8/08/001 */
1794 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
1795 {
1796   if (c->kind == term)
1797     return TRUE;
1798
1799   else
1800     return FALSE;
1801 }
1802
1803 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
1804 {
1805   constraintTerm term;
1806   
1807   llassert(constraintExpr_isTerm(c) );
1808
1809   term = constraintExprData_termGetTerm(c->data);
1810
1811   return term;
1812 }
1813
1814 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
1815 {
1816   constraintExpr expr1;
1817   constraintExprBinaryOpKind binaryOp;
1818   constraintExpr expr2;
1819
1820
1821   binaryOp = constraintExprData_binaryExprGetOp (data);
1822
1823   fprintf(f, "%d\n", (int) binaryOp);
1824   
1825   expr1 = constraintExprData_binaryExprGetExpr1 (data);
1826   expr2 = constraintExprData_binaryExprGetExpr2 (data);
1827
1828   fprintf(f, "e1\n");
1829
1830   constraintExpr_dump(expr1, f);
1831
1832   fprintf(f, "e2\n");
1833   constraintExpr_dump(expr2, f);
1834 }
1835
1836
1837 static constraintExpr  binaryExpr_undump (FILE *f)
1838 {
1839   constraintExpr expr1;
1840   constraintExprBinaryOpKind binaryOp;
1841   constraintExpr expr2;
1842
1843   constraintExpr ret;
1844
1845   
1846
1847   char * str;
1848   char * os;
1849
1850   str = mstring_create (MAX_DUMP_LINE_LENGTH);
1851   os = str;
1852   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1853
1854   
1855   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
1856   
1857   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1858
1859   reader_checkChar (&str, 'e');
1860   reader_checkChar (&str, '1');
1861   
1862   expr1 = constraintExpr_undump (f);
1863
1864   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1865
1866   reader_checkChar (&str, 'e');
1867   reader_checkChar (&str, '2');  
1868
1869   expr2 = constraintExpr_undump (f);
1870
1871   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
1872   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
1873
1874   free(os);
1875   return ret;
1876 }
1877
1878
1879
1880 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
1881 {
1882
1883   constraintExpr expr;
1884   constraintExprUnaryOpKind unaryOp;
1885
1886   unaryOp = constraintExprData_unaryExprGetOp (data);
1887
1888   fprintf(f, "%d\n", (int) unaryOp);
1889   
1890   expr = constraintExprData_unaryExprGetExpr (data);
1891
1892   constraintExpr_dump(expr, f);  
1893 }
1894
1895 static  constraintExpr  unaryExpr_undump ( FILE *f)
1896 {
1897
1898   constraintExpr expr;
1899   constraintExprUnaryOpKind unaryOp;
1900   constraintExpr ret;
1901   
1902   char * str;
1903   char * os;
1904
1905   str = mstring_create (MAX_DUMP_LINE_LENGTH);
1906   os = str;
1907   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1908
1909   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
1910   
1911   expr = constraintExpr_undump (f);
1912
1913   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
1914
1915   free(os);
1916   
1917   return ret;
1918 }
1919
1920 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
1921 {
1922   constraintExprKind kind;
1923   constraintTerm t;
1924   
1925   
1926   kind = expr->kind;
1927   
1928   fprintf(f,"%d\n", (int) kind);
1929   
1930   switch (kind)
1931     {
1932     case term:
1933       t = constraintExprData_termGetTerm (expr->data);
1934       constraintTerm_dump (t, f);
1935       break;      
1936     case unaryExpr:
1937       unaryExpr_dump (expr->data, f);
1938       break;           
1939     case binaryexpr:
1940       binaryExpr_dump  (expr->data, f);
1941       break;
1942     }  
1943 }
1944
1945 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
1946 {
1947   constraintExprKind kind;
1948   constraintTerm t;
1949   constraintExpr ret;
1950   
1951   char * s;
1952   char * os;
1953   
1954   s = mstring_create (MAX_DUMP_LINE_LENGTH);
1955
1956   os = s;
1957   
1958   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1959
1960   kind = (constraintExprKind) reader_getInt(&s);
1961
1962   free (os);
1963   
1964   switch (kind)
1965     {
1966     case term:
1967       t = constraintTerm_undump (f);
1968       ret = constraintExpr_makeTerm(t);
1969       break;      
1970     case unaryExpr:
1971       ret = unaryExpr_undump (f);
1972       break;           
1973     case binaryexpr:
1974       ret = binaryExpr_undump  (f);
1975       break;
1976     }
1977
1978   return ret;
1979
1980 }
1981
1982 int constraintExpr_getDepth (constraintExpr ex)
1983 {
1984   int ret;
1985   
1986   constraintExprKind kind;
1987
1988   llassert (ex != NULL);
1989
1990   kind = ex->kind;
1991   
1992   switch (kind)
1993     {
1994     case term:
1995       ret = 1;
1996       break;
1997     case unaryExpr:
1998       ret =  constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
1999       ret++;
2000       
2001       break;
2002     case binaryexpr:
2003       ret = 0;
2004       ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2005
2006       ret++;
2007
2008       ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2009
2010       break;
2011     default:
2012       BADEXIT;
2013     }
2014
2015   return ret;
2016 }
2017
2018
2019      
This page took 0.255986 seconds and 5 git commands to generate.