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