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