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