]> andersk Git - splint.git/blob - src/constraintExpr.c
f6284c6ea5d0de7719b63cf4b4546601559fec6d
[splint.git] / src / constraintExpr.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24
25 /*
26 ** constraintExpr.c
27 */
28
29 /* #define DEBUGPRINT 1 */
30
31 # include "splintMacros.nf"
32 # include "basic.h"
33 # include "cgrammar.h"
34 # include "cgrammar_tokens.h"
35
36 # include "exprChecks.h"
37 # include "exprNodeSList.h"
38
39
40 static ctype constraintExpr_getOrigType (constraintExpr p_e);
41 static bool constraintExpr_hasTypeChange(constraintExpr p_e) /*@*/;
42
43 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr, int p_literal);
44
45
46 /*@only@*/ static constraintExpr
47 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e,
48                               sRef p_s, ctype p_ct);
49
50 /*@only@*/ static constraintExpr 
51 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist) /*@modifies p_e@*/;
52
53 static /*@only@*/ constraintExpr 
54 doFixResultTerm (/*@only@*/ constraintExpr p_e, /*@exposed@*/ exprNode p_fcnCall)
55      /*@modifies p_e@*/;
56
57 static   bool  constraintExpr_canGetCType (constraintExpr p_e) /*@*/;
58
59 static ctype constraintExpr_getCType (constraintExpr p_e);
60
61 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast(/*@only@*/ constraintExpr p_e, ctype p_ct);
62
63 /*@special@*/ /*@notnull@*/ static constraintExpr constraintExpr_makeBinaryOp (void) 
64      /* @allocates result->data @ @sets result->kind @ */ ;
65
66 void constraintExpr_free (/*@only@*/ constraintExpr expr)
67 {
68   if (constraintExpr_isDefined(expr) )
69     {
70       switch (expr->kind)
71         {
72         case unaryExpr:
73           constraintExprData_freeUnaryExpr(expr->data);
74           break;
75         case binaryexpr:
76           constraintExprData_freeBinaryExpr(expr->data);
77           break;
78         case term:
79           constraintExprData_freeTerm(expr->data);
80           break;
81         default:
82           BADEXIT;
83         }
84
85       expr->data = NULL;
86       free (expr);
87     }
88   else
89     {
90       llcontbug(message("attempted to free null pointer in constraintExpr_free"));
91     }
92 }
93
94 bool constraintExpr_isLit (constraintExpr expr)
95 {
96   llassert (expr != NULL);
97   
98   if (expr->kind == term)
99     {
100       constraintTerm term = constraintExprData_termGetTerm (expr->data);
101       if (constraintTerm_isIntLiteral (term) )
102         {
103           return TRUE;
104         }
105
106     }
107   return FALSE;
108 }
109
110 static bool isZeroBinaryOp (constraintExpr expr)
111 {
112   constraintExpr e2;
113   
114   llassert (expr != NULL); /* evans 2001-07-18 */
115
116   if (!constraintExpr_isBinaryExpr (expr) )
117     {
118       return FALSE;
119     }
120
121   
122   e2 = constraintExprData_binaryExprGetExpr2(expr->data);
123
124   llassert (e2 != NULL); /* evans 2001-07-18 */
125
126   if (constraintExpr_isBinaryExpr (e2) )
127     {
128       constraintExpr e1;
129       constraintExprBinaryOpKind  op;
130
131       op = constraintExprData_binaryExprGetOp (e2->data);
132
133       e1 = constraintExprData_binaryExprGetExpr1(e2->data);
134
135         if (constraintExpr_isLit(e1) )
136           {
137             if (constraintExpr_getValue(e1) == 0 )
138               {
139                 return TRUE;
140               }
141           }
142     }
143   return FALSE;
144 }
145
146 /* change expr + (o - expr) to (expr -expr) */
147
148 /*@only@*/ /*@notnull@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
149 {
150   constraintExpr expr1, expr2;
151   
152   constraintExpr temp;
153
154   constraintExprBinaryOpKind  op;
155   
156   constraintExprBinaryOpKind  tempOp;
157
158   llassert (expr != NULL); /* evans 2001-07-18 */
159
160   if (!isZeroBinaryOp(expr) )
161     return expr;
162
163   
164   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
165   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
166   op = constraintExprData_binaryExprGetOp(expr->data);
167
168   llassert( constraintExpr_isBinaryExpr(expr2) );           
169
170   temp = constraintExprData_binaryExprGetExpr2 (expr2->data);
171   temp = constraintExpr_copy (temp);
172
173   tempOp = constraintExprData_binaryExprGetOp (expr2->data);
174
175   if (op == BINARYOP_PLUS)
176     op = tempOp;
177   else if (op == BINARYOP_MINUS)
178     {
179       if (tempOp == BINARYOP_PLUS)
180         op = BINARYOP_MINUS;
181       else if (tempOp == BINARYOP_MINUS)
182         op = BINARYOP_PLUS;
183       else
184         BADEXIT;
185     }
186   else
187     BADEXIT;
188
189   expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
190   expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
191
192   return expr;
193 }
194
195
196 /*@only@*//*@notnull@*/  constraintExpr constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr,
197                                                 /*@out@*/ bool * propagate,
198                                                   /*@out@*/ int *literal)
199 {
200   constraintExpr expr1;
201   constraintExpr expr2;
202   bool propagate1, propagate2;
203   int literal1, literal2;
204   constraintExprBinaryOpKind  op;
205   
206   propagate1 = FALSE;
207   propagate2 = FALSE;
208  
209   literal1 = 0;
210   literal2 = 0;
211   
212   *propagate = FALSE;
213   *literal = 0;
214
215   
216   llassert (expr != NULL);
217   
218   /* we simplify unaryExpr elsewhere */
219   if (expr->kind != binaryexpr)
220     return expr;
221
222   op = constraintExprData_binaryExprGetOp (expr->data);
223
224   DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
225
226   expr = removeZero(expr);
227   
228   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
229   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
230
231   expr1 = constraintExpr_copy(expr1);
232   expr2 = constraintExpr_copy(expr2);
233
234   expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
235   expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
236
237   expr1 = removeZero(expr1);
238   expr2 = removeZero(expr2);
239
240   
241   *propagate = propagate1 || propagate2;
242
243   if (op == BINARYOP_PLUS)
244     *literal    = literal1 +  literal2;
245   else   if (op == BINARYOP_MINUS)
246     *literal    = literal1 -  literal2;
247   else
248     BADEXIT;
249     
250   if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
251     {
252       long t1, t2;
253       t1 = constraintExpr_getValue (expr1);
254       t2 = constraintExpr_getValue (expr2);
255       llassert(*propagate == FALSE);
256       *propagate = FALSE;
257
258       constraintExpr_free (expr);
259       constraintExpr_free (expr1);
260       constraintExpr_free (expr2);
261
262       if (op == BINARYOP_PLUS )
263         return (constraintExpr_makeIntLiteral ((t1+t2) ));
264       else if (op ==  BINARYOP_MINUS)
265         return (constraintExpr_makeIntLiteral ((t1-t2) ));
266       else
267         BADEXIT;
268     }
269
270   
271   if (constraintExpr_isLit (expr1) )
272     {
273       *propagate = TRUE;
274
275       *literal += constraintExpr_getValue (expr1);
276
277       if (op == BINARYOP_PLUS)
278         {
279           constraintExpr_free(expr1);
280           constraintExpr_free(expr);
281           return expr2;
282         }
283       else if (op == BINARYOP_MINUS)
284         {
285           
286           constraintExpr temp;
287
288           /* this is an ugly kludge to deal with not
289              having a unary minus operation...*/
290
291           temp = constraintExpr_makeIntLiteral (0);
292           temp = constraintExpr_makeSubtractExpr (temp, expr2);
293           
294           constraintExpr_free(expr1);
295           constraintExpr_free(expr);
296
297           llassert (constraintExpr_isDefined(temp) );
298           return temp;
299         }
300       else
301         {
302           BADBRANCH; /* evans 2001-07-18 */
303         }
304     }
305   
306   if (constraintExpr_isLit (expr2) )
307     {
308       *propagate = TRUE;
309           
310       if ( op == BINARYOP_PLUS )
311         *literal += constraintExpr_getValue (expr2);
312       else if (op ==  BINARYOP_MINUS)
313         *literal -= constraintExpr_getValue (expr2);
314       else
315         BADEXIT;
316
317
318       constraintExpr_free(expr2);
319       constraintExpr_free(expr);
320       return expr1;
321     }
322   
323   DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
324
325   expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
326   expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
327
328   expr = removeZero(expr);
329   return expr;
330 }
331
332 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
333 {
334   bool propagate;
335   int literal;
336
337   DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
338   expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
339  
340
341   if (propagate)
342     {
343       constraintExpr ret;
344
345       if (literal != 0)
346         {
347           ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
348           expr = ret;
349         }
350     }
351    DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr) ) ) );
352
353    llassert(constraintExpr_isDefined(expr) );
354    return expr;
355 }
356
357 /*@special@*/
358 static /*@notnull@*/ constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
359 {
360   constraintExpr ret;
361   ret = dmalloc (sizeof (*ret) );
362   ret->kind = term;
363   ret->data = NULL;
364   ret->ct = FALSE;
365   ret->origType = ctype_undefined; 
366   return ret;
367 }
368
369 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
370 {
371   constraintExprData ret;
372   llassert(constraintExprData_isDefined(data));
373
374   switch (kind)
375     {
376     case binaryexpr:
377       ret = constraintExprData_copyBinaryExpr(data);
378       break;
379     case unaryExpr:
380       ret = constraintExprData_copyUnaryExpr(data);
381       break;
382     case term:
383       ret = constraintExprData_copyTerm(data);
384       break;
385     default:
386       BADEXIT;
387     }
388   return ret;
389 }
390
391 constraintExpr constraintExpr_copy (constraintExpr expr)
392 {
393   constraintExpr ret;
394   ret = constraintExpr_alloc ();
395
396
397   /*drl 03/02/2003 this shouldn't be used to copy a null
398     expression but handle things cleanly if it is*/
399   llassert (!constraintExpr_isUndefined(expr) );
400
401   if (constraintExpr_isUndefined(expr) )
402     {
403       return constraintExpr_undefined;
404     }
405   
406   ret->kind = expr->kind;
407   
408   ret->data = copyExprData (expr->data, expr->kind);
409   ret->ct = expr->ct;
410   ret->origType = expr->origType;
411   return ret;
412 }
413
414
415 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
416 {
417   constraintExpr ret;
418   constraintTerm t;
419   ret = constraintExpr_alloc();
420   ret->kind = term;
421   ret->data = dmalloc (sizeof *(ret->data) );
422   t = constraintTerm_makeExprNode (e);
423   ret->data = constraintExprData_termSetTerm (ret->data, t);
424   ret->ct = FALSE;
425   ret->origType = ctype_undefined;
426
427   return ret;
428 }
429
430 /*@access exprNode@*/
431 constraintExpr constraintExpr_makeExprNode (exprNode e)
432 {
433  sRef s;
434  constraintExpr ret, ce1, ce2;
435  exprData data;
436  exprNode t, t1, t2;
437  lltok tok;
438  
439  llassert (e != NULL);
440  
441  data = e->edata;
442
443  switch (e->kind)
444    {
445    case XPR_SIZEOF:
446      t = exprData_getSingle (data);
447      while (exprNode_isInParens (t) )
448        {
449          t = exprData_getUopNode (t->edata);
450        }
451      s = exprNode_getSref (t);
452      if (sRef_isFixedArray(s) )
453       {
454         int size;
455
456         size = (int) sRef_getArraySize(s);
457         ret = constraintExpr_makeIntLiteral (size);
458       }
459      else if (exprNode_isStringLiteral (t))
460       {
461         cstring str = multiVal_forceString (exprNode_getValue(t));
462         ret = constraintExpr_makeIntLiteral (size_toLong (cstring_length (str) + 1));
463       } 
464      else
465        {
466          DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
467          ret = oldconstraintExpr_makeTermExprNode (e);
468        }
469      break;
470      
471    case XPR_OP:
472       DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
473      t1 = exprData_getOpA (data);
474      t2 = exprData_getOpB (data);
475      tok = exprData_getOpTok (data);
476      
477      if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
478        {
479          ce1 = constraintExpr_makeExprNode (t1);
480          ce2 = constraintExpr_makeExprNode (t2);
481          ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);         
482        }
483
484
485         /* define this block to activate the cheesy heuristic
486         for handling sizeof expressions*/
487 #if 0     
488
489         
490      /*
491        drl 8-11-001
492        
493        We handle expressions containing sizeof with the rule
494        (sizeof type ) * Expr = Expr
495
496        This is the total wronge way to do this but...
497        it may be better than nothing
498      */
499
500      
501       
502      else if (lltok_isMult(tok) )
503        {
504          if  ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
505            {
506              ret = constraintExpr_makeExprNode(t2);
507            }
508          else if  ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
509            {
510              ret = constraintExpr_makeExprNode(t1);
511              } 
512          else
513            {
514            ret =  oldconstraintExpr_makeTermExprNode (e);
515            }
516        }
517 #endif
518      
519      else
520         ret = oldconstraintExpr_makeTermExprNode (e);
521    
522      break;
523    case XPR_PARENS: 
524      t = exprData_getUopNode (data);
525      ret = constraintExpr_makeExprNode (t);
526      break;
527      
528    case XPR_PREOP:
529       t = exprData_getUopNode (data);
530       tok =  exprData_getUopTok (data);
531       if (lltok_isIncOp (tok))
532         {
533           constraintExpr temp;
534           temp = constraintExpr_makeExprNode(t);
535           ret = constraintExpr_makeIncConstraintExpr(temp);
536         }
537       else if (lltok_isDecOp (tok))
538         {
539           constraintExpr temp;
540           temp = constraintExpr_makeExprNode(t);
541           ret = constraintExpr_makeDecConstraintExpr(temp);
542         }
543       else
544         ret =  oldconstraintExpr_makeTermExprNode (e);
545       break;
546       
547    case XPR_POSTOP:
548      t = exprData_getUopNode (data);
549           ret = constraintExpr_makeExprNode (t);
550      break;
551    case XPR_CAST:
552      t = exprData_getCastNode (data);
553      ret = constraintExpr_makeExprNode (t);
554      break;
555    case XPR_COMMA:
556      t = exprData_getPairA(data);
557      ret = constraintExpr_makeExprNode(t);
558      break;
559    default:
560      ret = oldconstraintExpr_makeTermExprNode (e);
561      
562    }
563   return ret;
564 }
565
566 /*@noaccess exprNode@*/
567
568
569
570
571 /*@only@*/ constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
572 {
573   return  oldconstraintExpr_makeTermExprNode(e);
574 }
575
576 static constraintExpr constraintExpr_makeTerm (/*@only@*/  constraintTerm t)
577 {
578   constraintExpr ret;
579
580   ret = constraintExpr_alloc();
581   ret->kind = term;
582   ret->data = dmalloc (sizeof *(ret->data) );
583   ret->data->term = NULL;
584   ret->data = constraintExprData_termSetTerm (ret->data, t);
585   ret->ct = FALSE;
586   ret->origType = ctype_undefined; 
587
588   return ret;
589 }
590
591 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
592 {
593   constraintExpr ret;
594   constraintTerm t;
595   ret = constraintExpr_alloc();
596   ret->kind = term;
597   ret->data = dmalloc (sizeof *(ret->data) );
598   t = constraintTerm_makesRef (s);
599   ret->data = constraintExprData_termSetTerm (ret->data, t);
600
601   ret->ct = FALSE;
602   ret->origType = ctype_undefined; 
603
604   return ret;
605 }
606
607 /*@special@*/ /*@notnull@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
608 {
609   constraintExpr ret;
610   ret = constraintExpr_alloc();
611   ret->kind = unaryExpr;
612   ret->data = dmalloc ( sizeof *(ret->data) );
613   ret->data->unaryOp.expr = constraintExpr_undefined;
614   return ret;
615 }
616
617 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
618 {
619   constraintExpr ret;
620   ret = makeUnaryOpGeneric();
621
622   /*@-uniondef@*/ 
623   /*@-compdef@*/
624   ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
625   ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
626   
627   return ret;
628   
629   /*@=compdef@*/
630   /*@=uniondef@*/
631 }
632
633
634 /*@only@*/ /*@notnull@*/static constraintExpr constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr,   constraintExprUnaryOpKind Op )
635 {
636   constraintExpr ret;
637   ret = makeUnaryOpGeneric();
638
639   ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
640   ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
641
642   ret->ct = FALSE;
643   ret->origType = ctype_undefined; 
644
645   return ret;
646 }
647
648 /*@only@*/ /*@notnull@*/
649 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
650 {
651   constraintExpr ret;
652   constraintExpr sub;
653   sub = constraintExpr_makeExprNode (expr);
654   ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
655
656   return ret;
657 }
658
659 /*@only@*/ /*@notnull@*/
660 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
661 {
662   constraintExpr ret;
663   ret = constraintExpr_makeUnaryOp (c, MAXSET);
664   return ret;
665 }
666
667
668 /*@only@*/ /*@notnull@*/
669 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s,  constraintExprUnaryOpKind op)
670 {
671   constraintExpr ret;
672   constraintExpr t;
673
674   t = constraintExpr_makeTermsRef (s);
675   ret = constraintExpr_makeUnaryOpConstraintExpr (t);
676   ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
677
678   return ret;
679 }
680
681 /*@only@*/
682 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
683 {
684   return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
685 }     
686
687 /*@only@*/
688 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
689 {
690   return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
691 }
692
693 /*@only@*/
694 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
695 {
696   constraintExpr ret;
697   ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
698
699   switch (lltok_getTok (op))
700     {
701     case QMAXSET:
702       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
703       break;
704     case QMAXREAD:
705       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
706       break;
707     default:
708       llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op)));
709     }
710   return ret;
711 }
712
713 /*@only@*/
714 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
715 {
716   constraintExpr ret;
717   ret = constraintExpr_makeExprNode (expr);
718
719   ret = constraintExpr_makeMaxSetConstraintExpr (ret);
720
721   llassert (ret != NULL);
722   return ret;
723 }
724
725 /*@only@*/
726 constraintExpr  constraintExpr_makeMaxReadExpr (exprNode expr)
727 {
728   constraintExpr ret;
729   ret = constraintExpr_makeUnaryOpExprNode(expr);
730   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
731   return ret; 
732 }
733
734 # if 0
735 /*@only@*/
736 /*@unused@*/ static constraintExpr  constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
737 {
738   constraintExpr ret;
739   ret = constraintExpr_makeUnaryOpExprNode(expr);
740   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINSET);
741   return ret;
742 }
743
744 /*@only@*/
745 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
746 {
747   constraintExpr ret;
748   ret = constraintExpr_makeUnaryOpExprNode(expr);
749   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
750   return ret;
751 }
752 # endif
753
754 /*@only@*/
755 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
756 {
757   constraintExpr ret;
758   ret = constraintExpr_makeExprNode (expr);
759   return ret;
760 }
761
762 /*@only@*/ /*@notnull@*/
763 constraintExpr constraintExpr_makeIntLiteral (long i)
764 {
765   constraintExpr ret;
766   constraintTerm t;
767   ret = constraintExpr_alloc();
768   ret->kind = term;
769   ret->data = dmalloc (sizeof *(ret->data) );
770   t = constraintTerm_makeIntLiteral (i);
771   ret->data = constraintExprData_termSetTerm (ret->data, t);
772
773   ret->ct = FALSE;
774   ret->origType = ctype_undefined; 
775
776   return ret;
777 }
778
779 /*
780 constraintExpr constraintExpr_makeValueInt (int i)
781 {
782   return constraintExpr_makeIntLiteral (i);
783 }
784 */
785
786 /*@only@*/ /*@notnull@*/
787  /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
788       /*@allocates result->data @*/ /*@sets result->kind @*/
789 {
790   constraintExpr ret;
791   ret = constraintExpr_alloc();
792   ret->kind = binaryexpr;
793   ret->data = dmalloc ( sizeof *(ret->data) );
794
795   ret->data->binaryOp.expr1 = constraintExpr_undefined;
796   ret->data->binaryOp.expr2 = constraintExpr_undefined;
797   
798   return ret;
799 }
800
801
802 static /*@notnull@*/ /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
803      
804 {
805   constraintExpr ret;
806
807   ret = constraintExpr_makeBinaryOp();
808   ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
809   ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
810   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
811
812   ret->ct = FALSE;
813   ret->origType = ctype_undefined; 
814
815   return ret;
816 }
817
818 /*@only@*/
819 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
820 {
821   constraintExpr ret;
822   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
823
824   if (lltok_getTok (op) == TPLUS)
825     {
826       ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
827     }
828   else if (lltok_getTok (op) == TMINUS)
829     {
830       ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
831     }
832   else
833     {
834       llassert (FALSE);
835     }
836
837   return ret;
838 }
839
840 # if 0
841 /*@only@*/
842 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
843 {
844   constraintExpr ret;
845   constraintExpr sub1, sub2;
846   sub1 = constraintExpr_makeTermExprNode (expr1);
847   sub2 = constraintExpr_makeTermExprNode (expr2);
848   ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
849   return ret;
850 }
851 # endif
852
853 static /*@notnull@*/ /*@only@*/
854 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
855 {
856   constraintExpr ret;
857   constraintExpr constExpr;
858
859   constExpr = constraintExpr_makeIntLiteral (literal);
860   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
861   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
862   return ret;
863 }
864
865 /*@only@*/
866 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
867 {
868   constraintExpr ret;
869   constraintExpr inc;
870
871   inc = constraintExpr_makeIntLiteral (1);
872   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
873   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
874   return ret;
875 }
876
877
878 /*@only@*/  constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
879 {
880   constraintExpr  ret;
881   
882   DPRINTF ((message ("Making  subtract expression") ) );
883
884   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
885   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_MINUS);
886   return ret;
887 }
888
889 /*@only@*/
890 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
891 constraintExpr expr, /*@only@*/
892 constraintExpr addent)
893 {
894   constraintExpr  ret;
895   
896   DPRINTF ((message ("Doing addTerm simplification") ) );
897
898   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
899   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_PLUS);
900   return ret;
901 }
902
903
904 /*@only@*/
905 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
906 {
907   constraintExpr ret;
908   constraintExpr inc;
909
910   inc = constraintExpr_makeIntLiteral (1);
911   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
912   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
913   return ret;
914 }
915
916 /*@only@*/
917 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
918 {
919   switch (op)
920     {
921     case MAXSET:
922       return message("maxSet");
923     case MINSET:
924       return message("minSet");
925     case MAXREAD:
926       return message("maxRead");
927     case MINREAD:
928       return message("minRead");
929     default:
930       llassert(FALSE);
931       return message ("<(Unary OP OTHER>");
932     }
933 }
934
935
936 /*@only@*/
937 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
938 {
939   
940   switch (op)
941     {
942     case BINARYOP_PLUS:
943       return message("+");
944     case BINARYOP_MINUS:
945       return message("-");
946
947     default:
948       llassert(FALSE);
949       return message ("<binary OP Unknown>");
950     }
951 }
952
953 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
954 {
955   constraintExprKind kind;
956   
957   llassert (expr1 != NULL);
958   llassert (expr2 != NULL);
959   if (expr1->kind != expr2->kind)
960     return FALSE;
961   
962   kind = expr1->kind;
963   
964   switch (kind)
965     {
966     case term:
967       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
968                                   constraintExprData_termGetTerm(expr2->data) );
969       /*@notreached@*/ break;
970       
971     case unaryExpr:
972       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
973         return FALSE;
974       
975       return (constraintExpr_similar (
976               constraintExprData_unaryExprGetExpr (expr1->data),
977               constraintExprData_unaryExprGetExpr (expr2->data)
978               ));
979       
980     case binaryexpr:
981       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
982         return FALSE;
983       
984       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
985                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
986         return FALSE;
987       
988       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
989                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
990         return FALSE;
991       else
992         return TRUE;
993       /*@notreached@*/
994       break;
995       
996     default:
997       llassert(FALSE);
998       return FALSE;
999     }
1000   /*@notreached@*/
1001   return FALSE;
1002 }
1003
1004 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
1005 {
1006   constraintExprKind kind;
1007   
1008   llassert (expr1 != NULL);
1009   llassert (expr2 != NULL);
1010   if (expr1->kind != expr2->kind)
1011     return FALSE;
1012   
1013   kind = expr1->kind;
1014   
1015   switch (kind)
1016     {
1017     case term:
1018       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
1019                                   constraintExprData_termGetTerm(expr2->data) );
1020       /*@notreached@*/ break;
1021       
1022     case unaryExpr:
1023       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
1024         return FALSE;
1025
1026       return (constraintExpr_same (
1027               constraintExprData_unaryExprGetExpr (expr1->data),
1028               constraintExprData_unaryExprGetExpr (expr2->data)
1029               ));
1030       
1031             
1032     case binaryexpr:
1033       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
1034         return FALSE;
1035       
1036       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
1037                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
1038         return FALSE;
1039       
1040       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
1041                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
1042         return FALSE;
1043       else
1044         return TRUE;
1045       /*@notreached@*/ break;
1046       
1047     default:
1048       llassert(FALSE);
1049       return FALSE;
1050     }
1051
1052   /*@notreached@*/
1053   BADEXIT;
1054 }
1055
1056 bool 
1057 constraintExpr_search (/*@observer@*/ constraintExpr c, 
1058                        /*@observer@*/ constraintExpr old)
1059 {
1060   bool ret = FALSE;
1061   constraintExprKind kind;
1062   constraintExpr temp;
1063   
1064   if (constraintExpr_similar (c, old))
1065     {
1066       DPRINTF (("Found  %q", constraintExpr_unparse (old)));
1067       return TRUE;
1068     }
1069
1070   llassert (constraintExpr_isDefined (c) && constraintExpr_isDefined(old) );
1071
1072   if ( !(constraintExpr_isDefined (c) && constraintExpr_isDefined(old) ) )
1073     return FALSE;
1074
1075   kind = c->kind;
1076   
1077   switch (kind)
1078     {
1079     case term:
1080       break;      
1081     case unaryExpr:
1082       temp = constraintExprData_unaryExprGetExpr (c->data);
1083       ret = ret || constraintExpr_search (temp, old);
1084       break;           
1085     case binaryexpr:
1086       
1087       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1088       ret = ret || constraintExpr_search(temp, old);
1089            
1090       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1091       ret = ret || constraintExpr_search(temp, old);
1092       break;
1093     default:
1094       llassert(FALSE);
1095     }
1096   return ret;
1097   
1098 }
1099
1100
1101 /*@only@*/ constraintExpr constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old, /*@temp@*/ constraintExpr newExpr )
1102 {
1103   constraintExprKind kind;
1104   constraintExpr temp;
1105   constraintExpr ret;
1106
1107   llassert(constraintExpr_isDefined (newExpr) && (constraintExpr_isDefined (old) && constraintExpr_isDefined(c) ) );
1108   
1109   if ( constraintExpr_similar (c, old) )
1110     {
1111       
1112       ctype newType, cType;
1113
1114
1115       
1116       
1117       ret = constraintExpr_copy (newExpr);
1118       llassert(constraintExpr_isDefined(ret) );
1119       /*drl if newExpr != NULL then ret will != NULL*/
1120       
1121       DPRINTF((message ("Replacing %s with %s",
1122                         constraintExpr_unparse(old), constraintExpr_unparse(newExpr)
1123                         )));
1124
1125       if (constraintExpr_canGetCType(c) && constraintExpr_canGetCType(newExpr) )
1126         {
1127           cType = constraintExpr_getCType(c);
1128           newType =  constraintExpr_getCType(newExpr);
1129           
1130           if (ctype_match(cType,newType) )
1131             {
1132               DPRINTF(( message("constraintExpr_searchandreplace: replacing "
1133                                 " %s with type %s with %s with type %s",
1134                                 constraintExpr_print(c), ctype_unparse(cType),
1135                                 constraintExpr_print(newExpr), ctype_unparse(newType)
1136                                 )
1137                         ));
1138               
1139               ret->ct = TRUE;
1140               ret->origType = cType;
1141             }
1142         }
1143
1144       if (constraintExpr_hasMaxSet(c) )
1145         {
1146           if (constraintExpr_hasTypeChange(c))
1147           {
1148           DPRINTF(( message("constraintExpr_searchandreplace: encountered "
1149                             "MaxSet with changed type %s ",
1150                             constraintExpr_print(c) )
1151                     ));
1152           
1153           /*fix this with a conversation */
1154           ret = constraintExpr_adjustMaxSetForCast(ret, constraintExpr_getOrigType(c));
1155           }
1156         }
1157       constraintExpr_free(c);
1158       
1159       return ret;
1160     }
1161
1162   kind = c->kind;
1163   
1164   switch (kind)
1165     {
1166     case term:
1167       break;      
1168     case unaryExpr:
1169       temp = constraintExprData_unaryExprGetExpr (c->data);
1170       temp = constraintExpr_copy(temp);
1171       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1172       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1173       break;           
1174     case binaryexpr:
1175       
1176       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1177       temp = constraintExpr_copy(temp);
1178       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1179       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1180        
1181       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1182       temp = constraintExpr_copy(temp);
1183       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1184       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1185       break;
1186     default:
1187       llassert(FALSE);
1188     }
1189   return c;
1190 }
1191
1192 /*@notnull@*/ static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c)
1193 {
1194   constraintExprKind kind;
1195   constraintExpr temp;
1196
1197   kind = c->kind;
1198   
1199   switch (kind)
1200     {
1201     case term:
1202       break;      
1203     case unaryExpr:
1204       temp = constraintExprData_unaryExprGetExpr (c->data);
1205       temp = constraintExpr_copy(temp);
1206       temp = constraintExpr_simplify (temp);
1207       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1208       break;           
1209     case binaryexpr:
1210       DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1211       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1212       temp = constraintExpr_copy(temp);
1213       temp = constraintExpr_simplify (temp);
1214
1215       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1216        
1217       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1218       temp = constraintExpr_copy(temp);
1219       temp = constraintExpr_simplify (temp);
1220
1221       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1222       break;
1223     default:
1224       llassert(FALSE);
1225     }
1226   return c;
1227   
1228 }
1229
1230
1231 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1232 {
1233   constraintTerm t;
1234   constraintExpr temp;
1235
1236   llassert(c != NULL);
1237   
1238   switch (c->kind)
1239     {
1240     case term:
1241       t = constraintExprData_termGetTerm (c->data);
1242       t = constraintTerm_copy(t);
1243       t = constraintTerm_setFileloc (t, loc);
1244       c->data = constraintExprData_termSetTerm (c->data, t);
1245       break;
1246     case binaryexpr:
1247       
1248       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1249       temp = constraintExpr_copy(temp);
1250       temp = constraintExpr_setFileloc (temp, loc);
1251       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1252       
1253       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1254       temp = constraintExpr_copy(temp);
1255       temp = constraintExpr_setFileloc (temp, loc);
1256       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1257       break;
1258     case unaryExpr:
1259       temp = constraintExprData_unaryExprGetExpr (c->data);
1260       temp = constraintExpr_copy(temp);
1261       temp = constraintExpr_setFileloc (temp, loc);
1262       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1263       break;
1264     }
1265   return c;
1266 }
1267
1268 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/ /*@notnull@*/ constraintExpr c)
1269 {
1270   constraintExpr e1, e2;
1271   constraintExprBinaryOpKind  op;
1272   
1273   e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1274   e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1275
1276   if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1277     {
1278       long i;
1279
1280       i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1281       constraintExpr_free(c);
1282       c = constraintExpr_makeIntLiteral (i);
1283     }
1284   else
1285     {
1286       op = constraintExprData_binaryExprGetOp (c->data);      
1287       if (op == BINARYOP_MINUS)
1288         if (constraintExpr_similar(e1, e2) )
1289           {
1290             constraintExpr_free(c);
1291             c =  constraintExpr_makeIntLiteral (0);
1292           }
1293     }
1294   
1295   return c;
1296 }
1297
1298 /*
1299   this thing takes the lexpr and expr of a constraint and modifies lexpr
1300   and returns a (possiblly new) value for expr
1301 */
1302 /* 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 */
1303
1304 /* the approach is a little Kludgy but seems to work.  I should probably use something cleaner at some point ... */
1305
1306
1307 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1308 {
1309   constraintExpr expr1, expr2;
1310   constraintExprBinaryOpKind op;
1311
1312   llassert(constraintExpr_isDefined (lexpr)  && constraintExpr_isDefined (expr)  );
1313   
1314   if (lexpr->kind != binaryexpr)
1315     return expr;
1316
1317   expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1318   expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1319
1320   op    = constraintExprData_binaryExprGetOp (lexpr->data);
1321
1322   expr1 = constraintExpr_copy(expr1);
1323   expr2 = constraintExpr_copy(expr2);
1324   
1325   llassert(constraintExpr_isDefined (expr1)  && constraintExpr_isDefined (expr2)  );
1326   
1327   /* drl possible problem : warning make sure this works */
1328   
1329   lexpr->kind = expr1->kind;
1330   sfree (lexpr->data);
1331   
1332   lexpr->data = copyExprData (expr1->data, expr1->kind);
1333   constraintExpr_free(expr1);
1334   
1335   if (op == BINARYOP_PLUS)
1336     expr = constraintExpr_makeSubtractExpr (expr, expr2);
1337   else if (op == BINARYOP_MINUS)
1338     expr = constraintExpr_makeAddExpr (expr, expr2);
1339   else
1340     BADEXIT;
1341   
1342   
1343   return expr;
1344
1345   /*
1346     #warning this needs to be checked
1347     expr = constraintExpr_solveBinaryExpr (expr1, expr);
1348     
1349     expr = constraintExpr_solveBinaryExpr (expr2, expr);
1350     return expr;
1351   */
1352 }
1353
1354 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1355 {
1356   constraintExpr exp;
1357
1358   llassert(constraintExpr_isDefined (c) );
1359   llassert (c->kind == unaryExpr);
1360
1361   DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1362   
1363   if ((constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1364        (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1365     {
1366       return c;
1367     }
1368   
1369   exp = constraintExprData_unaryExprGetExpr (c->data);
1370   exp = constraintExpr_copy(exp);
1371   
1372   llassert(constraintExpr_isDefined (exp)  );
1373   
1374   if (exp->kind == term)
1375     {
1376       constraintTerm cterm;
1377
1378       cterm = constraintExprData_termGetTerm (exp->data);
1379       
1380       if (constraintTerm_isStringLiteral(cterm) )
1381         {
1382           cstring val;
1383           val = constraintTerm_getStringLiteral (cterm);
1384           if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1385             {
1386               constraintExpr temp;
1387
1388               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1389               cstring_free(val);              
1390               constraintExpr_free(c);
1391               constraintExpr_free(exp);
1392
1393               return temp;
1394               
1395             }
1396           if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1397             {
1398               constraintExpr temp;
1399
1400               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1401               cstring_free(val);              
1402               constraintExpr_free(c);
1403               constraintExpr_free(exp);
1404
1405               return temp;
1406             }
1407           BADEXIT;
1408         }
1409
1410       /* slight Kludge to hanlde var [] = { , , };
1411       ** type syntax  I don't think this is sounds but it should be good
1412       ** enough.  The C stanrad is very confusing about initialization
1413       ** -- DRL 7/25/01
1414       */
1415       
1416       if (constraintTerm_isInitBlock(cterm) )
1417         {
1418           constraintExpr temp;
1419           int len;
1420
1421           len = constraintTerm_getInitBlockLength(cterm);
1422
1423           temp = constraintExpr_makeIntLiteral (len );
1424           
1425           constraintExpr_free(c);
1426           DPRINTF(( message("Changed too %q", constraintExpr_print(temp)
1427                             ) ));
1428           constraintExpr_free(exp);
1429           return temp;
1430         }
1431       
1432       constraintExpr_free(exp);
1433       return c;
1434     }
1435   
1436   if (exp->kind != binaryexpr)
1437     {
1438       constraintExpr_free(exp);
1439       return c;
1440     }
1441   
1442   if (constraintExprData_binaryExprGetOp (exp->data) == BINARYOP_PLUS  )
1443     {
1444  
1445       /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1446         {
1447         
1448           constraintExpr  temp, temp2;
1449
1450           DPRINTF ((message ("Doing fancy simplification") ) );
1451
1452           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1453
1454           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1455
1456           temp2 = constraintExpr_copy(temp2);
1457           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1458           
1459           
1460           temp = constraintExpr_copy (temp);
1461
1462           c = constraintExpr_makeSubtractExpr (c, temp);
1463
1464           DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1465         }
1466     }
1467   
1468   DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1469
1470   constraintExpr_free(exp);
1471   return c;
1472 }
1473
1474
1475 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1476 {
1477   constraintExprKind kind;
1478   constraintExpr ret;
1479   constraintTerm t;
1480   
1481   DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1482   
1483
1484   
1485   llassert ( constraintExpr_isDefined (c) );
1486   if (constraintExpr_isUndefined (c) )
1487     {
1488       return constraintExpr_undefined;
1489     }
1490   
1491   ret =  constraintExpr_copy(c);
1492   llassert(constraintExpr_isDefined (ret) );
1493            
1494   constraintExpr_free(c);
1495
1496   ret = constraintExpr_simplifyChildren (ret);
1497
1498   ret = constraintExpr_combineConstants (ret);
1499   
1500   ret = constraintExpr_simplifyChildren (ret);
1501   
1502
1503   kind = ret->kind;
1504   
1505   switch (kind)
1506     {
1507     case term:
1508       t = constraintExprData_termGetTerm (ret->data);
1509       t = constraintTerm_copy(t);
1510       t = constraintTerm_simplify (t);
1511       ret->data = constraintExprData_termSetTerm (ret->data, t);
1512       break;      
1513     case unaryExpr:
1514       ret = constraintExpr_simplifyunaryExpr (ret);
1515       break;           
1516     case binaryexpr:
1517       ret = constraintExpr_simplifybinaryExpr (ret);      
1518       break;
1519     default:
1520       llassert(FALSE);
1521     }    
1522   
1523   DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );  
1524   return ret;
1525   
1526 }
1527
1528 /*@only@*/
1529 cstring constraintExpr_unparse (/*@temp@*/ /*@observer@*/ constraintExpr ex) /*@*/
1530 {
1531   cstring st;
1532   constraintExprKind kind;
1533
1534   llassert (ex != NULL);
1535
1536   kind = ex->kind;
1537   
1538   switch (kind)
1539     {
1540     case term:
1541
1542             if (context_getFlag (FLG_PARENCONSTRAINT) )
1543               {
1544                 st = message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1545               }
1546             else
1547               {
1548                 st = message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1549               }
1550       break;
1551     case unaryExpr:
1552       st = message ("%q(%q)",
1553                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1554                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1555                     );
1556       break;
1557     case binaryexpr:
1558       if (context_getFlag (FLG_PARENCONSTRAINT) )
1559         {
1560           st = message ("(%q) %q (%q)",
1561                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1562                     constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1563                                                      ),
1564                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1565                     );
1566         }
1567       else
1568         {
1569           st = message ("%q %q %q",
1570                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1571                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1572                                                           ),
1573                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1574                         );
1575         }
1576       
1577       break;
1578     default:
1579       llassert(FALSE);
1580       st = message ("error");
1581       
1582     }
1583
1584   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1585   return st;
1586 }
1587
1588 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1589 {
1590   constraintTerm Term;
1591   constraintExprKind kind;
1592   constraintExpr expr1, expr2;
1593   constraintExprData data;
1594   llassert (expr != NULL);
1595
1596   data = expr->data;
1597   
1598   kind = expr->kind;
1599   
1600   switch (kind)
1601     {
1602     case term:
1603       Term = constraintExprData_termGetTerm(data);
1604       Term = constraintTerm_copy(Term);
1605
1606       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1607       data = constraintExprData_termSetTerm(data, Term);
1608       break;
1609     case unaryExpr:
1610       expr1 = constraintExprData_unaryExprGetExpr (data);
1611       expr1 = constraintExpr_copy(expr1);
1612
1613       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1614       data = constraintExprData_unaryExprSetExpr (data, expr1);
1615       break;
1616     case binaryexpr:
1617       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1618       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1619       
1620       expr1 = constraintExpr_copy(expr1);
1621       expr2 = constraintExpr_copy(expr2);
1622
1623       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1624       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1625       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1626       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1627       
1628       break;
1629     default:
1630       llassert(FALSE);
1631       data = NULL;
1632     }
1633   return expr;
1634 }
1635
1636 /*
1637 / *@only@* / constraintExpr constraintExpr_doSRefFixInvarConstraint (/ *@only@* / constraintExpr expr, sRef s, ctype ct)
1638 {
1639   constraintExprKind kind;
1640   constraintExpr expr1, expr2;
1641   constraintExprData data;
1642   llassert (expr != NULL);
1643
1644   data = expr->data;
1645   
1646   kind = expr->kind;
1647   
1648   switch (kind)
1649     {
1650     case term:
1651       expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1652       break;
1653     case unaryExpr:
1654       expr1 = constraintExprData_unaryExprGetExpr (data);
1655       expr1 = constraintExpr_copy(expr1);
1656       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1657       data = constraintExprData_unaryExprSetExpr (data, expr1);
1658       break;
1659     case binaryexpr:
1660       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1661       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1662       
1663       expr1 = constraintExpr_copy(expr1);
1664       expr2 = constraintExpr_copy(expr2);
1665
1666       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1667       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1668       expr2 = constraintExpr_doSRefFixInvarConstraint (expr2, s, ct);
1669       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1670       
1671       break;
1672     default:
1673       llassert(FALSE);
1674       data = NULL;
1675     }
1676   return expr;
1677 }
1678 */
1679
1680 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1681 {
1682   constraintExprKind kind;
1683   constraintExpr expr1, expr2;
1684   constraintExprData data;
1685   llassert (expr != NULL);
1686
1687   data = expr->data;
1688   
1689   kind = expr->kind;
1690   
1691   switch (kind)
1692     {
1693     case term:
1694       expr = doSRefFixConstraintParamTerm (expr, arglist);
1695       break;
1696     case unaryExpr:
1697       expr1 = constraintExprData_unaryExprGetExpr (data);
1698       expr1 = constraintExpr_copy(expr1);
1699       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1700       data = constraintExprData_unaryExprSetExpr (data, expr1);
1701       break;
1702     case binaryexpr:
1703       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1704       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1705       
1706       expr1 = constraintExpr_copy(expr1);
1707       expr2 = constraintExpr_copy(expr2);
1708
1709       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1710       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1711       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1712       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1713       
1714       break;
1715     default:
1716       llassert(FALSE);
1717       data = NULL;
1718     }
1719   return expr;
1720 }
1721
1722 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/  constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1723 {
1724   constraintExprKind kind;
1725   constraintExpr expr1, expr2;
1726   constraintExprData data;
1727   llassert (expr != NULL);
1728
1729   data = expr->data;
1730   
1731   kind = expr->kind;
1732   
1733   switch (kind)
1734     {
1735     case term:
1736       expr = doFixResultTerm (expr, fcnCall);
1737       break;
1738     case unaryExpr:
1739       expr1 = constraintExprData_unaryExprGetExpr (data);
1740       expr1 = constraintExpr_copy(expr1);
1741
1742       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1743       data = constraintExprData_unaryExprSetExpr (data, expr1);
1744       break;
1745     case binaryexpr:
1746       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1747       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1748       
1749       expr1 = constraintExpr_copy(expr1);
1750       expr2 = constraintExpr_copy(expr2);
1751
1752       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1753       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1754       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1755       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1756       
1757       break;
1758     default:
1759       llassert(FALSE);
1760       data = NULL;
1761     }
1762   return expr;
1763 }
1764
1765 cstring constraintExpr_print (constraintExpr expr) /*@*/
1766 {
1767   return constraintExpr_unparse (expr);
1768 }
1769
1770 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1771 {
1772   cstring t;
1773
1774   t = constraintExpr_unparse(expr);
1775
1776   if (cstring_containsLit(t, "maxSet") != NULL )
1777     {
1778       cstring_free(t);
1779       return (TRUE);
1780     }
1781   else
1782     {
1783       cstring_free(t);
1784       return FALSE;
1785     }
1786 }
1787
1788
1789
1790       /*returns 1 0 -1 like strcmp
1791         1 => expr1 > expr2
1792         0 => expr1 == expr2
1793         -1 => expr1 < expr2
1794        */
1795
1796 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1797 {
1798   long value1, value2;
1799
1800   if (constraintExpr_similar (expr1, expr2) )
1801     {
1802       return 0;
1803     }
1804   
1805   value1 = constraintExpr_getValue(expr1);
1806   value2 = constraintExpr_getValue(expr2);
1807
1808   if (value1 > value2)
1809     return 1;
1810
1811   if (value1 == value2)
1812     return 0;
1813
1814   else
1815     return -1;
1816 }
1817
1818 long constraintExpr_getValue (constraintExpr expr)
1819 {
1820   llassert (constraintExpr_isDefined(expr) );
1821   llassert (expr->kind == term);
1822   
1823   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1824 }
1825
1826 bool constraintExpr_canGetValue (constraintExpr expr)
1827 {
1828   llassert ( constraintExpr_isDefined (expr) );
1829   if (constraintExpr_isUndefined (expr) )
1830     {
1831       return FALSE;
1832     }
1833
1834   switch (expr->kind)
1835     {
1836     case term:
1837       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1838     default:
1839       return FALSE;
1840       
1841     }
1842
1843   BADEXIT;
1844 }
1845
1846 fileloc constraintExpr_getFileloc (constraintExpr expr)
1847 {
1848   constraintExpr e;
1849 constraintTerm t;
1850   constraintExprKind kind;
1851
1852   llassert ( constraintExpr_isDefined (expr) );
1853   if (constraintExpr_isUndefined (expr) )
1854     {
1855       return fileloc_undefined;
1856     }
1857
1858   
1859  kind = expr->kind;
1860   
1861   switch (kind)
1862     {
1863     case term:
1864       t = constraintExprData_termGetTerm (expr->data);
1865       return (constraintTerm_getFileloc (t) );
1866       /*@notreached@*/
1867       break;      
1868     case unaryExpr:
1869       e = constraintExprData_unaryExprGetExpr (expr->data);
1870       return (constraintExpr_getFileloc (e) );
1871       /*@notreached@*/
1872       break;           
1873     case binaryexpr:
1874       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1875       return (constraintExpr_getFileloc (e) );
1876       /*@notreached@*/
1877       break;
1878     }
1879   llassert (FALSE);
1880   return (fileloc_undefined);
1881 }
1882
1883 /*drl moved from constriantTerm.c 5/20/001*/
1884 static /*@only@*/ constraintExpr 
1885 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1886 {
1887   constraintTerm t;
1888   sRef s;
1889   constraintExprData data;
1890   constraintExprKind kind;
1891   constraintExpr ret;
1892   
1893   llassert (constraintExpr_isDefined (e) );
1894   
1895   data = e->data;
1896   kind = e->kind;
1897   
1898   llassert (kind == term);
1899   
1900   t = constraintExprData_termGetTerm (data);
1901   llassert (constraintTerm_isDefined (t));
1902   
1903   ret = e;
1904
1905   switch (constraintTerm_getKind (t))
1906     {
1907     case CTT_EXPR:
1908     case CTT_INTLITERAL:
1909       break;
1910       
1911     case CTT_SREF:
1912       s = constraintTerm_getSRef(t);
1913       if (sRef_isResult (s))
1914         {
1915           ret = constraintExpr_makeExprNode(fcnCall);
1916           constraintExpr_free(e);
1917           e = NULL;
1918         }
1919       else
1920         {
1921           e = NULL;
1922         }
1923       break;
1924     default:
1925       BADEXIT;
1926     }
1927   
1928   return ret;
1929   
1930 }
1931
1932 #if 0
1933
1934 /*to be used for structure checking */
1935
1936 / *@only@* / static constraintExpr
1937 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e,
1938  sRef s, ctype ct)
1939 {
1940   constraintTerm t;
1941
1942   constraintExprData data = e->data;
1943   
1944   constraintExprKind kind = e->kind;
1945   
1946   constraintExpr ret;
1947
1948   llassert(kind == term);
1949
1950   t = constraintExprData_termGetTerm (data);
1951   llassert (constraintTerm_isDefined(t) );
1952
1953   ret = e;
1954
1955   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1956
1957   switch (constraintTerm_getKind(t))
1958     {
1959     case CTT_EXPR:
1960       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1961                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1962       break;
1963     case CTT_INTLITERAL:
1964       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1965       break;
1966       
1967     case CTT_SREF:
1968       / * evans 2001-07-24: constants should use the original term * /
1969       if (!constraintTerm_canGetValue (t))
1970         {
1971           sRef snew;
1972           DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ", 
1973                              constraintTerm_unparse (t) ) ));
1974
1975           snew = fixSref (ct, s, constraintTerm_getSRef(t));
1976
1977           ret = constraintExpr_makeTermsRef(snew);
1978           
1979           constraintExpr_free (e);
1980           
1981           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
1982                              constraintExpr_print (ret) ) ));
1983           / *@-branchstate@* /
1984         } / *@=branchstate@* /
1985
1986       break;
1987     default:
1988       BADEXIT;
1989     }
1990
1991   return ret;
1992   
1993 }
1994 #endif
1995  
1996 /*drl moved from constriantTerm.c 5/20/001*/
1997 /*@only@*/ static constraintExpr 
1998 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
1999 {
2000   constraintTerm t;
2001
2002   constraintExprData data;
2003   
2004   constraintExprKind kind;
2005   
2006   constraintExpr ret;
2007
2008
2009   llassert(constraintExpr_isDefined (e) );
2010
2011   data = e->data;
2012   
2013   kind = e->kind;
2014
2015   
2016
2017   llassert(kind == term);
2018
2019   t = constraintExprData_termGetTerm (data);
2020   llassert (constraintTerm_isDefined(t) );
2021
2022   ret = e;
2023
2024   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2025
2026   switch (constraintTerm_getKind(t))
2027     {
2028     case CTT_EXPR:
2029       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2030                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2031       break;
2032     case CTT_INTLITERAL:
2033       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2034       break;
2035     case CTT_SREF:
2036       /* evans 2001-07-24: constants should use the original term */
2037       if (!constraintTerm_canGetValue (t))
2038         {
2039           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
2040                              constraintTerm_unparse (t) ) ));
2041           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
2042           
2043           constraintExpr_free (e);
2044           
2045           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2046                              constraintExpr_print (ret) ) ));
2047           /*@-branchstate@*/
2048         } /*@=branchstate@*/
2049
2050       break;
2051     default:
2052       BADEXIT;
2053     }
2054
2055   return ret;
2056   
2057 }
2058
2059
2060 #if 0
2061 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2062 {
2063   if (constraintTerm_hasTerm (expr->term, term) )
2064     return TRUE;
2065
2066   if ((expr->expr) != NULL)
2067     {
2068       return ( constraintExpr_includesTerm (expr->expr, term) );
2069     }
2070   return FALSE;
2071
2072 }
2073 #endif
2074
2075 /*drl added 6/11/01 */
2076 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2077 {
2078
2079   llassert(constraintExpr_isDefined (c) );
2080
2081   if ( ! (constraintExpr_isDefined (c) ) )
2082     return FALSE;
2083   
2084   if (c->kind == binaryexpr)
2085     return TRUE;
2086
2087   else
2088     return FALSE;
2089 }
2090
2091 /*drl added 8/08/001 */
2092 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2093 {
2094   llassert(constraintExpr_isDefined (c) );
2095   
2096   if (c->kind == term)
2097     return TRUE;
2098
2099   else
2100     return FALSE;
2101 }
2102
2103 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2104 {
2105   constraintTerm term;
2106   
2107   llassert(constraintExpr_isDefined (c) );
2108   
2109   llassert(constraintExpr_isTerm(c) );
2110
2111   term = constraintExprData_termGetTerm(c->data);
2112
2113   return term;
2114 }
2115
2116 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2117 {
2118   constraintExpr expr1;
2119   constraintExprBinaryOpKind binaryOp;
2120   constraintExpr expr2;
2121
2122
2123   binaryOp = constraintExprData_binaryExprGetOp (data);
2124
2125   fprintf(f, "%d\n", (int) binaryOp);
2126   
2127   expr1 = constraintExprData_binaryExprGetExpr1 (data);
2128   expr2 = constraintExprData_binaryExprGetExpr2 (data);
2129
2130   fprintf(f, "e1\n");
2131
2132   constraintExpr_dump(expr1, f);
2133
2134   fprintf(f, "e2\n");
2135   constraintExpr_dump(expr2, f);
2136 }
2137
2138
2139 static constraintExpr  binaryExpr_undump (FILE *f)
2140 {
2141   constraintExpr expr1;
2142   constraintExprBinaryOpKind binaryOp;
2143   constraintExpr expr2;
2144
2145   constraintExpr ret;
2146
2147   
2148
2149   char * str;
2150   char * os;
2151
2152   os = mstring_create (MAX_DUMP_LINE_LENGTH);
2153
2154   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2155
2156   if (! mstring_isDefined(str) )
2157     {
2158       llfatalbug(message("Library file is corrupted") );
2159     }
2160   
2161   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2162   
2163   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2164
2165   if (! mstring_isDefined(str) )
2166     {
2167       llfatalbug(message("Library file is corrupted") );
2168     }
2169
2170   reader_checkChar (&str, 'e');
2171   reader_checkChar (&str, '1');
2172   
2173   expr1 = constraintExpr_undump (f);
2174
2175   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2176
2177   reader_checkChar (&str, 'e');
2178   reader_checkChar (&str, '2');  
2179
2180   expr2 = constraintExpr_undump (f);
2181
2182   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2183   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2184
2185   free(os);
2186   return ret;
2187 }
2188
2189
2190
2191 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2192 {
2193
2194   constraintExpr expr;
2195   constraintExprUnaryOpKind unaryOp;
2196
2197   unaryOp = constraintExprData_unaryExprGetOp (data);
2198
2199   fprintf(f, "%d\n", (int) unaryOp);
2200   
2201   expr = constraintExprData_unaryExprGetExpr (data);
2202
2203   constraintExpr_dump(expr, f);  
2204 }
2205
2206 static  constraintExpr  unaryExpr_undump ( FILE *f)
2207 {
2208
2209   constraintExpr expr;
2210   constraintExprUnaryOpKind unaryOp;
2211   constraintExpr ret;
2212   
2213   char * str;
2214   char * os;
2215
2216   str = mstring_create (MAX_DUMP_LINE_LENGTH);
2217   os = str;
2218   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2219
2220   if (! mstring_isDefined(str) )
2221     {
2222       llfatalbug(message("Library file is corrupted") );
2223     }
2224
2225   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2226   
2227   expr = constraintExpr_undump (f);
2228
2229   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2230
2231   free(os);
2232   
2233   return ret;
2234 }
2235
2236 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
2237 {
2238   constraintExprKind kind;
2239   constraintTerm t;
2240   
2241
2242   llassert(constraintExpr_isDefined(expr) );
2243   
2244   DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2245                    constraintExpr_unparse(expr)
2246                    ) ));
2247   
2248   kind = expr->kind;
2249   
2250   fprintf(f,"%d\n", (int) kind);
2251   
2252   switch (kind)
2253     {
2254     case term:
2255       t = constraintExprData_termGetTerm (expr->data);
2256       constraintTerm_dump (t, f);
2257       break;      
2258     case unaryExpr:
2259       unaryExpr_dump (expr->data, f);
2260       break;           
2261     case binaryexpr:
2262       binaryExpr_dump  (expr->data, f);
2263       break;
2264     }  
2265 }
2266
2267 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
2268 {
2269   constraintExprKind kind;
2270   constraintTerm t;
2271   constraintExpr ret;
2272   
2273   char * s;
2274   char * os;
2275   
2276   s = mstring_create (MAX_DUMP_LINE_LENGTH);
2277
2278   os = s;
2279   
2280   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2281
2282   if (! mstring_isDefined(s) )
2283     {
2284       llfatalbug(message("Library file is corrupted") );
2285     }
2286
2287   kind = (constraintExprKind) reader_getInt(&s);
2288
2289   free (os);
2290   
2291   switch (kind)
2292     {
2293     case term:
2294       t = constraintTerm_undump (f);
2295       ret = constraintExpr_makeTerm(t);
2296       break;      
2297     case unaryExpr:
2298       ret = unaryExpr_undump (f);
2299       break;           
2300     case binaryexpr:
2301       ret = binaryExpr_undump  (f);
2302       break;
2303     }
2304
2305   return ret;
2306
2307 }
2308
2309 int constraintExpr_getDepth (constraintExpr ex)
2310 {
2311   int ret;
2312   
2313   constraintExprKind kind;
2314
2315   llassert (ex != NULL);
2316
2317   kind = ex->kind;
2318   
2319   switch (kind)
2320     {
2321     case term:
2322       ret = 1;
2323       break;
2324     case unaryExpr:
2325       ret =  constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2326       ret++;
2327       
2328       break;
2329     case binaryexpr:
2330       ret = 0;
2331       ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2332
2333       ret++;
2334
2335       ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2336
2337       break;
2338     default:
2339       BADEXIT;
2340     }
2341
2342   return ret;
2343 }
2344
2345
2346 bool  constraintExpr_canGetCType (constraintExpr e) /*@*/
2347 {
2348   if (constraintExpr_isUndefined(e) )
2349     return FALSE;
2350   
2351   if (e->kind == term)
2352     {
2353       return TRUE;
2354     }
2355   else
2356     {
2357       DPRINTF(( message("constraintExpr_canGetCType: can't get type for %s ",
2358                         constraintExpr_print(e) ) ));
2359       return FALSE;
2360     }
2361 }
2362
2363 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2364 {
2365   constraintTerm t;
2366
2367   llassert(constraintExpr_isDefined(e) );
2368
2369   llassert(constraintExpr_canGetCType(e) );
2370
2371   switch (e->kind)
2372     {
2373     case term:
2374       t = constraintExprData_termGetTerm (e->data);
2375       return (constraintTerm_getCType(t) );
2376       /* assume that a unary expression will be an int ... */
2377     case unaryExpr:
2378       return ctype_signedintegral;
2379
2380       /* drl for just return type of first operand */
2381     case binaryexpr:
2382       return (
2383               constraintExpr_getCType
2384               (constraintExprData_binaryExprGetExpr1 (e->data) )
2385               );
2386     default:
2387       BADEXIT;
2388     }
2389   BADEXIT;
2390 }
2391
2392 /* drl add 10-5-001 */
2393
2394 static bool constraintExpr_hasTypeChange(constraintExpr e)
2395 {
2396   llassert(constraintExpr_isDefined(e) );
2397   if (constraintExpr_isDefined((e)) && (e->ct == TRUE) )
2398     {
2399       return TRUE;
2400     }
2401
2402   if (e->kind == unaryExpr)
2403     {
2404       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2405         {
2406           constraintExpr ce;
2407
2408           ce = constraintExprData_unaryExprGetExpr(e->data);
2409
2410           return (constraintExpr_hasTypeChange(ce) );
2411         }
2412         
2413     }
2414   return FALSE;
2415 }
2416
2417 /* drl add 10-5-001 */
2418
2419 static ctype constraintExpr_getOrigType (constraintExpr e)
2420 {
2421
2422   llassert(constraintExpr_isDefined(e) );
2423   llassert(constraintExpr_hasTypeChange(e) );
2424   
2425   
2426   if (e->ct == TRUE) 
2427     {
2428       return e->origType;
2429     }
2430
2431   if (e->kind == unaryExpr)
2432     {
2433       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2434         {
2435           constraintExpr ce;
2436
2437           ce = constraintExprData_unaryExprGetExpr(e->data);
2438
2439           return (constraintExpr_getOrigType(ce) );
2440         }
2441         
2442     }
2443
2444   BADEXIT;
2445
2446
2447 /*drl added these around 10/18/001*/
2448
2449 static /*@only@*/ constraintExpr constraintExpr_div (/*@only@*/ constraintExpr e, /*@unused@*/ ctype ct)
2450 {
2451   return e;
2452 }
2453
2454
2455 /*@access exprNode@*/ 
2456 static /*@only@*/ constraintExpr  constraintTerm_simpleDivTypeExprNode(/*@only@*/ constraintExpr e, ctype ct)
2457 {
2458   exprData data;
2459   exprNode t1, t2, expr;
2460   lltok tok;
2461   constraintTerm t;
2462
2463   llassert(constraintExpr_isDefined(e) );
2464   
2465   DPRINTF((
2466            message("constraintTerm_simpleDivTypeExprNode e=%s, ct=%s",
2467                    constraintExpr_print(e), ctype_unparse(ct)
2468                    )
2469            ));
2470   
2471   t = constraintExprData_termGetTerm(e->data);
2472   
2473   expr = constraintTerm_getExprNode(t);
2474
2475   llassert(constraintExpr_isDefined(e) );
2476   llassert(exprNode_isDefined(expr) );
2477   
2478   if (expr->kind == XPR_OP)
2479     {
2480       data = expr->edata;
2481       
2482       t1 = exprData_getOpA (data);
2483       t2 = exprData_getOpB (data);
2484       tok = exprData_getOpTok (data);
2485       if (lltok_isMult(tok) )
2486         {
2487           llassert(exprNode_isDefined(t1) && exprNode_isDefined(t2) );
2488           /*drl 3/2/2003 we know this from the fact that it's a
2489             multiplication operation...*/
2490           
2491           if  ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
2492             {
2493               ctype ct2;
2494               
2495               if (t1->kind == XPR_SIZEOFT)
2496                 {
2497                   ct2 = qtype_getType (exprData_getType (t1->edata));
2498                 }
2499               else
2500                 {
2501                   exprNode tempE;
2502                 
2503                   tempE = exprData_getSingle (t1->edata);
2504                   
2505                   ct2 =  exprNode_getType (tempE); 
2506                 }
2507               if (ctype_match (ctype_makePointer(ct2), ct) )
2508                 {
2509                   /* this is a bit sloopy but ... */
2510                                   constraintExpr_free(e);
2511                   return constraintExpr_makeExprNode(t2);
2512                 }
2513             }
2514           
2515           
2516           else   if  ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
2517             {
2518               ctype ct2;
2519               
2520               if (t2->kind == XPR_SIZEOFT)
2521                 {
2522                   ct2 = qtype_getType (exprData_getType (t2->edata));
2523                 }
2524               else
2525                 {
2526                   exprNode exprTemp;
2527                   exprData eDTemp;
2528                   
2529                   exprTemp = exprData_getSingle (t2->edata);
2530
2531                   llassert(exprNode_isDefined(exprTemp) );
2532                   eDTemp = exprTemp->edata;
2533                   
2534                   ct2 = qtype_getType (exprData_getType(eDTemp ) );
2535                   
2536                 }
2537               if (ctype_match (ctype_makePointer(ct2),ct) )
2538                 {
2539                   /*a bit of a sloopy way to do this but... */
2540                                   constraintExpr_free(e);
2541                   return constraintExpr_makeExprNode(t1);
2542                 }
2543             }
2544           else
2545             {
2546               /*empty*/
2547             }
2548           
2549         }
2550     }
2551   return (constraintExpr_div (e, ct) );
2552 }
2553 /*@noaccess exprNode@*/ 
2554
2555 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype ct)
2556 {
2557   DPRINTF(( (message("simpleDiv got %s ", constraintExpr_unparse(e) ) )
2558             ));
2559
2560   llassert(constraintExpr_isDefined(e) );
2561   
2562   switch (e->kind)
2563     {
2564     case term:
2565       
2566       {
2567         constraintTerm t;
2568
2569         t = constraintExprData_termGetTerm(e->data);
2570         
2571
2572         if (constraintTerm_isExprNode (t) )
2573         {
2574           return constraintTerm_simpleDivTypeExprNode(e, ct);
2575           
2576           /* search for * size of ct and remove */
2577         }
2578         return constraintExpr_div (e, ct);
2579       }
2580       
2581     case binaryexpr:
2582       {
2583         constraintExpr temp;
2584         
2585         temp = constraintExprData_binaryExprGetExpr1 (e->data);
2586         temp = constraintExpr_copy(temp);
2587         temp = simpleDivType (temp, ct);
2588         
2589         e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2590         
2591         temp = constraintExprData_binaryExprGetExpr2 (e->data);
2592         temp = constraintExpr_copy(temp);
2593         temp = simpleDivType (temp, ct);
2594         e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2595
2596         DPRINTF(( (message("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e) ) )
2597             ));
2598
2599         return e;
2600       }
2601     case unaryExpr:
2602       return constraintExpr_div (e, ct);
2603
2604     default:
2605       BADEXIT;
2606     }
2607 }
2608
2609 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast(/*@only@*/ constraintExpr e, ctype ct)
2610 {
2611
2612   DPRINTF(( (message("constraintExpr_adjustMaxSetForCast got %s ", constraintExpr_unparse(e) ) )
2613             ));
2614   
2615   e = constraintExpr_makeIncConstraintExpr(e);
2616   
2617   e = constraintExpr_simplify(e);
2618   
2619
2620   e = simpleDivType (e, ct);
2621
2622   e = constraintExpr_makeDecConstraintExpr(e);
2623   
2624   e = constraintExpr_simplify(e);
2625   
2626   DPRINTF(( (message("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e) ) )
2627             ));
2628
2629   return e;
2630 }
2631
2632
2633 bool  constraintExpr_isConstantOnly ( constraintExpr e )
2634 {
2635   DPRINTF(( (message("constraintExpr_isConstantOnly %s ",
2636                      constraintExpr_unparse(e) ) )
2637             ));
2638
2639   llassert(constraintExpr_isDefined(e) );
2640
2641   switch (e->kind)
2642     {
2643     case term:
2644       {
2645         constraintTerm t;
2646         
2647         t = constraintExprData_termGetTerm(e->data);
2648         
2649         
2650         if (constraintTerm_isConstantOnly (t) )
2651           {
2652             return TRUE;
2653           }
2654         else
2655           {
2656             return FALSE;
2657           }
2658       }
2659       
2660     case binaryexpr:
2661       {
2662         constraintExpr temp1, temp2;
2663         
2664         temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2665         
2666         temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2667         
2668         if (constraintExpr_isConstantOnly(temp1) &&
2669             constraintExpr_isConstantOnly(temp2) )
2670           {
2671             return TRUE;
2672           }
2673         else
2674           {
2675             return FALSE;
2676           }
2677       }
2678       
2679     case unaryExpr:
2680       {
2681         constraintExpr temp;
2682         
2683         temp = constraintExprData_unaryExprGetExpr (e->data );
2684
2685         if (constraintExpr_isConstantOnly(temp) )
2686           {
2687             return TRUE;
2688           }
2689         else
2690           {
2691             return FALSE;
2692           }
2693       }
2694     default:
2695       BADEXIT;
2696     }
2697 }
2698
This page took 0.23278 seconds and 3 git commands to generate.