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