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