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