]> andersk Git - splint.git/blob - src/constraintExpr.c
updating to make tree consistent for start at cert
[splint.git] / src / constraintExpr.c
1 /*
2 ** constraintExpr.c
3 */
4
5 //#define DEBUGPRINT 1
6
7 # include "lclintMacros.nf"
8 # include "basic.h"
9 # include "cgrammar.h"
10 # include "cgrammar_tokens.h"
11
12 # include "exprChecks.h"
13 # include "aliasChecks.h"
14 # include "exprNodeSList.h"
15
16
17 # include "exprData.i"
18 # include "exprDataQuite.i"
19
20
21 /*@-czechfcns@*/
22
23
24
25 /*@access exprNode @*/
26
27 static constraintExpr 
28 doSRefFixConstraintParamTerm (constraintExpr e, exprNodeList arglist) /*@modifies e@*/;
29
30 static constraintExpr 
31 doFixResultTerm (constraintExpr e, exprNode fcnCall) /*@modifies e@*/;
32
33 /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void) /*@defines result->kind, result->data->binaryOp.binaryOp@*/;
34
35 //constraintExpr constraintExpr_makeMaxSetConstraintExpr (constraintExpr c);
36
37 bool constraintExpr_isLit (constraintExpr expr)
38 {
39   llassert (expr != NULL);
40   
41   if (expr->kind == term)
42     {
43       constraintTerm term = constraintExprData_termGetTerm (expr->data);
44       if (constraintTerm_isIntLiteral (term) )
45         {
46           return TRUE;
47         }
48
49     }
50   return FALSE;
51 }
52
53
54 constraintExpr constraintExpr_propagateConstants (constraintExpr expr,
55                                                 /*@out@*/ bool * propagate,
56                                                   /*@out@*/ int *literal)
57 {
58   constraintExpr expr1;
59   constraintExpr expr2;
60   bool propagate1, propagate2;
61   int literal1, literal2;
62   
63   propagate1 = FALSE;
64   propagate2 = FALSE;
65  
66   literal1 = 0;
67   literal2 = 0;
68   
69   *propagate = FALSE;
70   *literal = 0;
71
72   llassert (expr != NULL);
73   
74   // we simplify unaryExpr else where
75   if (expr->kind == unaryExpr)
76     return expr;
77
78   if (expr->kind == term)
79     return expr;
80   
81   if (constraintExpr_isLit (expr) )
82     return expr;
83
84   DPRINTF( (message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
85   
86   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
87   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
88
89   expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
90   expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
91
92   expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
93   expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
94   
95   *propagate = propagate1 || propagate2;
96   *literal    = literal1 +  literal2;
97   
98   if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
99     {
100       int t1, t2;
101       t1 = constraintExpr_getValue (expr1);
102       t2 = constraintExpr_getValue (expr2);
103       *propagate = FALSE;
104
105       /*@-compdef@*/
106       if (constraintExprData_binaryExprGetOp (expr->data) == PLUS )
107         return (constraintExpr_makeIntLiteral ( (t1+t2) ));
108       else if (constraintExprData_binaryExprGetOp (expr->data) ==  MINUS)
109         return (constraintExpr_makeIntLiteral ( (t1-t2) ));
110       else
111         llassert(FALSE);
112       /*@=compdef@*/
113     }
114   
115   if (constraintExpr_isLit (expr1) )
116     {
117       /*@i334*/
118       /*handle MINUS case right */
119       *propagate = TRUE;
120       *literal += constraintExpr_getValue (expr1);
121       /*@-compdef@*/
122       return expr2;
123       /*@=compdef@*/
124     }
125   
126   /*@-compdef@*/
127   if (constraintExpr_isLit (expr2) )
128     {
129       *propagate = TRUE;
130           
131       if (constraintExprData_binaryExprGetOp (expr->data) == PLUS )
132         *literal += constraintExpr_getValue (expr2);
133       else
134         *literal -= constraintExpr_getValue (expr2);
135       return expr1;
136     }
137
138
139   
140   
141   DPRINTF( (message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
142
143   return expr;
144   /*@=compdef@*/
145 }
146
147 static constraintExpr constraintExpr_combineConstants ( constraintExpr expr ) /*@modifies@*/
148 {
149   bool propagate;
150   int literal;
151
152   DPRINTF ( (message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
153   expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
154  
155
156   if (propagate)
157     {
158       constraintExpr ret;
159
160       if (literal != 0)
161         {
162           ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
163           expr = ret;
164         }
165     }
166    DPRINTF ( (message ("After combine %s", constraintExpr_unparse(expr) ) ) );
167   return expr;
168 }
169
170 /*@special@*/
171 static constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
172 {
173   constraintExpr ret;
174   ret = dmalloc (sizeof (*ret) );
175   ret->kind = term;
176   ret->data = NULL;
177   return ret;
178 }
179
180 static constraintExprData copyExprData (constraintExprData data, constraintExprKind kind)
181 {
182   constraintExprData ret;
183   llassert(constraintExprData_isDefined(data));
184
185   switch (kind)
186     {
187     case binaryexpr:
188       ret = constraintExprData_copyBinaryExpr(data);
189       break;
190     case unaryExpr:
191       ret = constraintExprData_copyUnaryExpr(data);
192       break;
193     case term:
194       ret = constraintExprData_copyTerm(data);
195       break;
196     default:
197       BADEXIT;
198     }
199   return ret;
200 }
201
202 constraintExpr constraintExpr_copy (constraintExpr expr)
203 {
204   constraintExpr ret;
205   ret = constraintExpr_alloc();
206   ret->kind = expr->kind;
207   
208   ret->data = copyExprData (expr->data, expr->kind);
209   return ret;
210 }
211
212
213 constraintExpr oldconstraintExpr_makeTermExprNode (exprNode e)
214 {
215   constraintExpr ret;
216   constraintTerm t;
217   ret = constraintExpr_alloc();
218   ret->kind = term;
219   ret->data = dmalloc (sizeof *(ret->data) );
220   t = constraintTerm_makeExprNode (e);
221   ret->data = constraintExprData_termSetTerm (ret->data, t);
222   return ret;
223 }
224
225 constraintExpr constraintExpr_makeExprNode (exprNode e)
226 {
227  sRef s;
228  constraintExpr ret, ce1, ce2;
229  exprData data;
230  exprNode t, t1, t2;
231  lltok tok;
232  
233  
234  llassert (e != NULL);
235  
236  data = e->edata;
237
238  switch (e->kind)
239    {
240    case XPR_SIZEOF:
241      t = exprData_getSingle (data);
242      s = exprNode_getSref (t);
243      if (sRef_isFixedArray(s) )
244       {
245         int size;
246
247         size = (int) sRef_getArraySize(s);
248         ret = constraintExpr_makeIntLiteral (size);
249       }
250      else
251        {
252          DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
253          ret = oldconstraintExpr_makeTermExprNode (e);
254        }
255      break;
256      
257    case XPR_OP:
258       DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
259      t1 = exprData_getOpA (data);
260      t2 = exprData_getOpB (data);
261      tok = exprData_getOpTok (data);
262      
263      if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
264        {
265          ce1 = constraintExpr_makeExprNode (t1);
266          ce2 = constraintExpr_makeExprNode (t2);
267          ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);         
268        }
269      else
270        {
271         ret = oldconstraintExpr_makeTermExprNode (e);
272        }
273      break;
274    case XPR_PARENS: 
275      t = exprData_getUopNode (data);
276      ret = constraintExpr_makeExprNode (t);
277      break;
278      
279    case XPR_PREOP:
280       t = exprData_getUopNode (data);
281       tok =  exprData_getUopTok (data);
282       if (lltok_isInc_Op (tok) )
283         {
284           constraintExpr temp;
285           temp = constraintExpr_makeExprNode(t);
286           ret = constraintExpr_makeIncConstraintExpr(temp);
287         }
288       else if (lltok_isDec_Op (tok) )
289         {
290           constraintExpr temp;
291           temp = constraintExpr_makeExprNode(t);
292           ret = constraintExpr_makeDecConstraintExpr(temp);
293         }
294       else
295         ret =  oldconstraintExpr_makeTermExprNode (e);
296       break;
297       
298    case XPR_POSTOP:
299      t = exprData_getUopNode (data);
300           ret = constraintExpr_makeExprNode (t);
301      break;
302    case XPR_CAST:
303      t = exprData_getCastNode (data);
304      ret = constraintExpr_makeExprNode (t);
305      break;
306    case XPR_COMMA:
307      t = exprData_getPairA(data);
308      ret = constraintExpr_makeExprNode(t);
309      /*@i3434*/ /*I'm not sure if this is right.  I'm adding a break to quite LCLint*/
310      break;
311    default:
312      ret = oldconstraintExpr_makeTermExprNode (e);
313      
314    }
315   return ret;
316 }
317
318
319 constraintExpr constraintExpr_makeTermExprNode (exprNode e)
320 {
321   return  oldconstraintExpr_makeTermExprNode(e); //constraintExpr_makeExprNode (e);
322 }
323
324
325 constraintExpr constraintExpr_makeTermsRef (sRef s)
326 {
327   constraintExpr ret;
328   constraintTerm t;
329   ret = constraintExpr_alloc();
330   ret->kind = term;
331   ret->data = dmalloc (sizeof *(ret->data) );
332   t = constraintTerm_makesRef (s);
333   ret->data = constraintExprData_termSetTerm (ret->data, t);
334   return ret;
335 }
336
337 /*@special@*/ static constraintExpr constraintExpr_makeUnaryOp (void) /*@allocates result->data@*/ /*@defines result->kind@*/
338 {
339   constraintExpr ret;
340   ret = constraintExpr_alloc();
341   ret->kind = unaryExpr;
342   ret->data = dmalloc ( sizeof *(ret->data) );
343   return ret;
344 }
345
346 static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (constraintExpr cexpr)
347 {
348   constraintExpr ret;
349   ret = constraintExpr_makeUnaryOp();
350
351   /*@-uniondef@*/ 
352   /*@-compdef@*/
353     ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
354     ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
355
356   return ret;
357
358   /*@=compdef@*/
359   /*@=uniondef@*/
360 }
361
362 constraintExpr constraintExpr_makeMaxSetConstraintExpr (constraintExpr c)
363 {
364   constraintExpr ret;
365   ret = constraintExpr_makeUnaryOpConstraintExpr (c);
366   ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
367   return ret;
368 }
369
370 constraintExpr constraintExpr_makeUnaryOpExprNode (exprNode expr)
371 {
372   constraintExpr ret;
373   constraintExpr sub;
374   sub = constraintExpr_makeExprNode (expr);
375   ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
376   return ret;
377 }
378
379
380
381 constraintExpr constraintExpr_makeSRefUnaryOp (sRef s,  constraintExprUnaryOpKind op)
382 {
383   constraintExpr ret;
384   constraintExpr t;
385
386   t = constraintExpr_makeTermsRef (s);
387   ret = constraintExpr_makeUnaryOpConstraintExpr (t);
388   ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
389   return ret;
390 }
391
392 constraintExpr constraintExpr_makeSRefMaxRead(sRef s)
393 {
394   return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
395 }     
396
397 constraintExpr constraintExpr_makeSRefMaxset (sRef s)
398 {
399   return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
400 }
401
402 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
403 {
404   constraintExpr ret;
405   ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
406
407   switch (op.tok)
408     {
409     case QMAXSET:
410       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
411       break;
412     case QMAXREAD:
413       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
414       break;
415     default:
416       llfatalbug(message("Unhandled Operation in Constraint") );
417     }
418   return ret;
419 }
420
421 constraintExpr constraintExpr_makeMaxSetExpr (exprNode expr)
422 {
423   constraintExpr ret;
424   ret = constraintExpr_makeExprNode (expr);
425
426   ret = constraintExpr_makeMaxSetConstraintExpr (ret);
427
428   llassert (ret != NULL);
429   return ret;
430 }
431
432 constraintExpr  constraintExpr_makeMaxReadExpr (exprNode expr)
433 {
434   constraintExpr ret;
435   ret = constraintExpr_makeUnaryOpExprNode(expr);
436   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
437   return ret; 
438 }
439
440 constraintExpr  constraintExpr_makeMinSetExpr (exprNode expr)
441 {
442   constraintExpr ret;
443   ret = constraintExpr_makeUnaryOpExprNode(expr);
444   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINSET);
445   return ret;
446 }
447
448 constraintExpr  constraintExpr_makeMinReadExpr (exprNode expr)
449 {
450   constraintExpr ret;
451   ret = constraintExpr_makeUnaryOpExprNode(expr);
452   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
453   return ret;
454 }
455
456
457 constraintExpr constraintExpr_makeValueExpr (exprNode expr)
458 {
459   constraintExpr ret;
460   ret = constraintExpr_makeExprNode (expr);
461   return ret;
462 }
463
464 constraintExpr constraintExpr_makeIntLiteral (int i)
465 {
466   constraintExpr ret;
467   constraintTerm t;
468   ret = constraintExpr_alloc();
469   ret->kind = term;
470   ret->data = dmalloc (sizeof *(ret->data) );
471   t = constraintTerm_makeIntLiteral (i);
472   ret->data = constraintExprData_termSetTerm (ret->data, t);
473   return ret;
474 }
475
476 /*
477 constraintExpr constraintExpr_makeValueInt (int i)
478 {
479   return constraintExpr_makeIntLiteral (i);
480 }
481 */
482
483 /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void) /*@defines result->kind, result->data->binaryOp.binaryOp@*/
484 {
485   constraintExpr ret;
486   ret = constraintExpr_alloc();
487   ret->kind = binaryexpr;
488   ret->data = dmalloc ( sizeof *(ret->data) );
489   ret->data = constraintExprData_binaryExprSetOp (ret->data, PLUS);
490   return ret;
491 }
492
493
494 constraintExpr constraintExpr_makeBinaryOpConstraintExpr (constraintExpr expr1,constraintExpr expr2)
495      
496 {
497   constraintExpr ret;
498   ret = constraintExpr_makeBinaryOp();
499   ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
500   ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
501   return ret;
502 }
503
504 constraintExpr constraintExpr_parseMakeBinaryOp (constraintExpr expr1, lltok op, constraintExpr expr2)
505 {
506   constraintExpr ret;
507   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
508   if (op.tok == TPLUS)
509     ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
510   else if (op.tok == TMINUS)
511     ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
512     else
513       {
514         llassert(FALSE);
515       }
516   return ret;
517 }
518
519 constraintExpr constraintExpr_makeBinaryOpExprNode (exprNode expr1, exprNode expr2)
520 {
521   constraintExpr ret;
522   constraintExpr sub1, sub2;
523   sub1 = constraintExpr_makeTermExprNode (expr1);
524   sub2 = constraintExpr_makeTermExprNode (expr2);
525   ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
526   return ret;
527 }
528
529 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (constraintExpr expr, int literal)
530 {
531   constraintExpr ret;
532   constraintExpr constExpr;
533
534   constExpr = constraintExpr_makeIntLiteral (literal);
535   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
536   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
537   return ret;
538 }
539
540 constraintExpr constraintExpr_makeDecConstraintExpr (constraintExpr expr)
541 {
542   constraintExpr ret;
543   constraintExpr inc;
544
545   inc = constraintExpr_makeIntLiteral (1);
546   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
547   ret->data = constraintExprData_binaryExprSetOp(ret->data, MINUS);
548   return ret;
549 }
550
551 constraintExpr constraintExpr_makeAddConstraintExpr (constraintExpr expr, constraintExpr add)
552 {
553   constraintExpr ret;
554
555   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, add);
556   
557   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
558
559   return ret;
560 }
561
562 constraintExpr constraintExpr_makeIncConstraintExpr (constraintExpr expr)
563 {
564   constraintExpr ret;
565   constraintExpr inc;
566
567   inc = constraintExpr_makeIntLiteral (1);
568   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
569   ret->data = constraintExprData_binaryExprSetOp(ret->data, PLUS);
570   return ret;
571 }
572
573 cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
574 {
575   switch (op)
576     {
577     case MAXSET:
578       return message("MAXSET");
579     case MINSET:
580       return message("MINSET");
581     case MAXREAD:
582       return message("MAXREAD");
583     case MINREAD:
584       return message("MINREAD");
585     default:
586       llassert(FALSE);
587       return message ("<(Unary OP OTHER>");
588     }
589 }
590
591
592 cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
593 {
594   
595   switch (op)
596     {
597     case PLUS:
598       return message("+");
599     case MINUS:
600       return message("-");
601
602     default:
603       llassert(FALSE);
604       return message ("<binary OP Unknown>");
605     }
606 }
607
608 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
609 {
610   constraintExprKind kind;
611   
612   llassert (expr1 != NULL);
613   llassert (expr2 != NULL);
614   if (expr1->kind != expr2->kind)
615     return FALSE;
616   
617   kind = expr1->kind;
618   
619   switch (kind)
620     {
621     case term:
622       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
623                                   constraintExprData_termGetTerm(expr2->data) );
624       /*@notreached@*/ break;
625       
626     case unaryExpr:
627       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
628         return FALSE;
629       
630       return (constraintExpr_similar (
631               constraintExprData_unaryExprGetExpr (expr1->data),
632               constraintExprData_unaryExprGetExpr (expr2->data)
633               ));
634       
635     case binaryexpr:
636       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
637         return FALSE;
638       
639       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
640                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
641         return FALSE;
642       
643       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
644                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
645         return FALSE;
646       else
647         return TRUE;
648       /*@notreached@*/
649       break;
650       
651     default:
652       llassert(FALSE);
653       return FALSE;
654     }
655   /*@notreached@*/
656   return FALSE;
657 }
658
659 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
660 {
661   constraintExprKind kind;
662   
663   llassert (expr1 != NULL);
664   llassert (expr2 != NULL);
665   if (expr1->kind != expr2->kind)
666     return FALSE;
667   
668   kind = expr1->kind;
669   
670   switch (kind)
671     {
672     case term:
673       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
674                                   constraintExprData_termGetTerm(expr2->data) );
675       /*@notreached@*/ break;
676       
677     case unaryExpr:
678       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
679         return FALSE;
680
681       return (constraintExpr_same (
682               constraintExprData_unaryExprGetExpr (expr1->data),
683               constraintExprData_unaryExprGetExpr (expr2->data)
684               ));
685       
686             
687     case binaryexpr:
688       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
689         return FALSE;
690       
691       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
692                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
693         return FALSE;
694       
695       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
696                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
697         return FALSE;
698       else
699         return TRUE;
700       /*@notreached@*/ break;
701       
702     default:
703       llassert(FALSE);
704       return FALSE;
705     }
706
707   /*@notreached@*/
708   BADEXIT;
709 }
710
711 bool constraintExpr_search (constraintExpr c, constraintExpr old)
712 {
713   bool ret = FALSE;
714   constraintExprKind kind;
715   constraintExpr temp;
716   
717   if ( constraintExpr_similar (c, old) )
718     {
719       #warning mem leak
720       DPRINTF((message ("Found  %s",
721                         constraintExpr_unparse(old)
722                         )));
723       return TRUE;
724     }
725
726   kind = c->kind;
727   
728   switch (kind)
729     {
730     case term:
731       break;      
732     case unaryExpr:
733       temp = constraintExprData_unaryExprGetExpr (c->data);
734       ret = ret || constraintExpr_search (temp, old);
735       break;           
736     case binaryexpr:
737       
738       temp = constraintExprData_binaryExprGetExpr1 (c->data);
739       ret = ret || constraintExpr_search(temp, old);
740            
741       temp = constraintExprData_binaryExprGetExpr2 (c->data);
742       ret = ret || constraintExpr_search(temp, old);
743       break;
744     default:
745       llassert(FALSE);
746     }
747   return ret;
748   
749 }
750
751
752 constraintExpr constraintExpr_searchandreplace (constraintExpr c, constraintExpr old, constraintExpr new )
753 {
754   constraintExprKind kind;
755   constraintExpr temp;
756   
757   if ( constraintExpr_similar (c, old) )
758     {
759       #warning mem leak
760       DPRINTF((message ("Replacing %s with %s",
761                         constraintExpr_unparse(old), constraintExpr_unparse(new)
762                         )));
763       return constraintExpr_copy (new);
764     }
765
766   kind = c->kind;
767   
768   switch (kind)
769     {
770     case term:
771       break;      
772     case unaryExpr:
773       temp = constraintExprData_unaryExprGetExpr (c->data);
774       temp = constraintExpr_searchandreplace (temp, old, new);
775       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
776       break;           
777     case binaryexpr:
778       
779       temp = constraintExprData_binaryExprGetExpr1 (c->data);
780       temp = constraintExpr_searchandreplace (temp, old, new);
781       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
782        
783       temp = constraintExprData_binaryExprGetExpr2 (c->data);
784       temp = constraintExpr_searchandreplace (temp, old, new);
785       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
786       break;
787     default:
788       llassert(FALSE);
789     }
790   return c;
791   
792 }
793
794 constraintExpr constraintExpr_simplifyChildren (constraintExpr c)
795 {
796   constraintExprKind kind;
797   constraintExpr temp;
798
799   kind = c->kind;
800   
801   switch (kind)
802     {
803     case term:
804       break;      
805     case unaryExpr:
806       temp = constraintExprData_unaryExprGetExpr (c->data);
807       temp = constraintExpr_simplify (temp);
808       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
809       break;           
810     case binaryexpr:
811       DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
812       temp = constraintExprData_binaryExprGetExpr1 (c->data);
813       temp = constraintExpr_simplify (temp);
814
815       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
816        
817       temp = constraintExprData_binaryExprGetExpr2 (c->data);
818       temp = constraintExpr_simplify (temp);
819
820       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
821       break;
822     default:
823       llassert(FALSE);
824     }
825   return c;
826   
827 }
828
829
830 constraintExpr constraintExpr_setFileloc (constraintExpr c, fileloc loc)
831 {
832   constraintTerm t;
833   constraintExpr temp;
834
835   llassert(c != NULL);
836   
837   switch (c->kind)
838     {
839     case term:
840       t = constraintExprData_termGetTerm (c->data);
841       t = constraintTerm_setFileloc (t, loc);
842       c->data = constraintExprData_termSetTerm (c->data, t);
843       break;
844     case binaryexpr:
845       
846       temp = constraintExprData_binaryExprGetExpr1 (c->data);
847       temp = constraintExpr_setFileloc (temp, loc);
848       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
849       
850       temp = constraintExprData_binaryExprGetExpr2 (c->data);
851       temp = constraintExpr_setFileloc (temp, loc);
852       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
853       break;
854     case unaryExpr:
855       temp = constraintExprData_unaryExprGetExpr (c->data);
856       temp = constraintExpr_setFileloc (temp, loc);
857       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
858       break;
859     }
860   return c;
861 }
862
863 constraintExpr constraintExpr_simplifybinaryExpr (constraintExpr c)
864 {
865   constraintExpr e1, e2;
866
867   e1 = constraintExprData_binaryExprGetExpr1 (c->data);
868   e2 = constraintExprData_binaryExprGetExpr2 (c->data);
869
870   if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
871     {
872       int i;
873
874       i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
875
876       c = constraintExpr_makeIntLiteral (i);
877
878     }
879   return c;
880 }
881
882
883 constraintExpr constraintExpr_subtractExpr (constraintExpr expr, constraintExpr addent)
884 {
885   constraintExpr  new;
886   
887   DPRINTF ( (message ("Doing subtraceTerm simplification") ) );
888
889   new = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
890   new->data = constraintExprData_binaryExprSetOp (new->data, MINUS);
891   return new;
892 }
893
894 constraintExpr constraintExpr_addExpr (constraintExpr expr, constraintExpr addent)
895 {
896   constraintExpr  new;
897   
898   DPRINTF ( (message ("Doing addTerm simplification") ) );
899
900   new = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
901   new->data = constraintExprData_binaryExprSetOp (new->data, PLUS);
902   return new;
903 }
904
905 constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, constraintExpr expr)
906 {
907   constraintExpr expr1, expr2;
908   constraintExprBinaryOpKind op;
909   
910   if (lexpr->kind != binaryexpr)
911     return expr;
912
913   expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
914   expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
915   op    = constraintExprData_binaryExprGetOp (lexpr->data);
916
917       
918   {
919 #warning make sure this works
920     
921     lexpr->kind = expr1->kind;
922     lexpr->data = copyExprData (expr1->data, expr1->kind);
923     
924     
925     if (op == PLUS)
926       expr = constraintExpr_subtractExpr (expr, expr2);
927     else
928       expr = constraintExpr_addExpr (expr, expr2);
929     
930     return expr;
931   }  
932   /*
933     #warning this needs to be checked
934     expr = constraintExpr_solveBinaryExpr (expr1, expr);
935     
936     expr = constraintExpr_solveBinaryExpr (expr2, expr);
937     return expr;
938   */
939 }
940
941 constraintExpr constraintExpr_simplifyunaryExpr (constraintExpr c)
942 {
943   constraintExpr exp;
944   
945   llassert (c->kind == unaryExpr);
946
947   DPRINTF ( (message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
948   
949   if ( (constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
950        (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
951     {
952       return c;
953     }
954   // pattern mxr ( var + const) = mxr(var) - const
955   
956   exp = constraintExprData_unaryExprGetExpr (c->data);
957
958   if (exp->kind == term)
959     {
960       constraintTerm cterm;
961
962       cterm = constraintExprData_termGetTerm (exp->data);
963       
964       if (constraintTerm_isStringLiteral(cterm) )
965         {
966           cstring val;
967           val = constraintTerm_getStringLiteral (cterm);
968           if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
969             {
970               return constraintExpr_makeIntLiteral ((int)strlen (val) );
971             }
972           if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
973             {
974               return constraintExpr_makeIntLiteral ((int)strlen (val) );
975             }
976           BADEXIT;
977         }
978       return c;
979     }
980   
981   if (exp->kind != binaryexpr)
982     return c;
983
984   if (constraintExprData_binaryExprGetOp (exp->data) == PLUS  )
985     {
986  
987       //      if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) )
988         {
989         
990           constraintExpr  temp, temp2, new;
991
992           DPRINTF ( (message ("Doing fancy simplification") ) );
993
994           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
995
996           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
997           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
998           
999           
1000           
1001           new = constraintExpr_subtractExpr (c, temp);
1002
1003           DPRINTF ( (message ("Done fancy simplification:%s", constraintExpr_unparse (new) ) ) );
1004
1005           c = new;
1006         }
1007     }
1008   
1009   DPRINTF ( (message ("Done simplification:%s", constraintExpr_unparse (c) ) ) );
1010   return c;
1011 }
1012
1013
1014 constraintExpr constraintExpr_simplify (constraintExpr c)
1015 {
1016   constraintExprKind kind;
1017   constraintTerm t;
1018
1019   
1020   DPRINTF ( (message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1021
1022   c = constraintExpr_simplifyChildren (c);
1023   c = constraintExpr_combineConstants (c);
1024   c = constraintExpr_simplifyChildren (c);
1025   
1026   kind = c->kind;
1027   
1028   switch (kind)
1029     {
1030     case term:
1031       t = constraintExprData_termGetTerm (c->data);
1032       t = constraintTerm_simplify (t);
1033       c->data = constraintExprData_termSetTerm (c->data, t);
1034       break;      
1035     case unaryExpr:
1036       c = constraintExpr_simplifyunaryExpr (c);
1037       break;           
1038     case binaryexpr:
1039       c = constraintExpr_simplifybinaryExpr (c);      
1040       break;
1041     default:
1042       llassert(FALSE);
1043     }
1044   return c;
1045   
1046 }
1047
1048 cstring constraintExpr_unparse (constraintExpr ex)
1049 {
1050   cstring st;
1051   constraintExprKind kind;
1052
1053   llassert (ex != NULL);
1054
1055   kind = ex->kind;
1056   
1057   switch (kind)
1058     {
1059     case term:
1060       st = message ("(%s) ", constraintTerm_print (constraintExprData_termGetTerm(ex->data) ) );
1061       break;
1062     case unaryExpr:
1063       st = message ("%s (%s)",
1064                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data)
1065                                                      ),
1066                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1067                     );
1068       break;
1069     case binaryexpr:
1070       st = message ("(%s) %s (%s)",
1071                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1072                     constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1073                                                      ),
1074                     constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1075                     );
1076       break;
1077     default:
1078       llassert(FALSE);
1079       st = message ("error");
1080       
1081     }
1082
1083   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1084   return st;
1085 }
1086
1087 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1088 {
1089   constraintTerm Term;
1090   constraintExprKind kind;
1091   constraintExpr expr1, expr2;
1092   constraintExprData data;
1093   llassert (expr != NULL);
1094
1095   data = expr->data;
1096   
1097   kind = expr->kind;
1098   
1099   switch (kind)
1100     {
1101     case term:
1102       Term = constraintExprData_termGetTerm(data);
1103       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1104       data = constraintExprData_termSetTerm(data, Term);
1105       break;
1106     case unaryExpr:
1107       expr1 = constraintExprData_unaryExprGetExpr (data);
1108       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1109       data = constraintExprData_unaryExprSetExpr (data, expr1);
1110       break;
1111     case binaryexpr:
1112       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1113       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1114       
1115       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1116       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1117       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1118       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1119       
1120       break;
1121     default:
1122       llassert(FALSE);
1123       data = NULL;
1124     }
1125   return expr;
1126 }
1127
1128 constraintExpr constraintExpr_doSRefFixConstraintParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist) /*@modifies@*/
1129 {
1130   constraintExprKind kind;
1131   constraintExpr expr1, expr2;
1132   constraintExprData data;
1133   llassert (expr != NULL);
1134
1135   data = expr->data;
1136   
1137   kind = expr->kind;
1138   
1139   switch (kind)
1140     {
1141     case term:
1142       expr = doSRefFixConstraintParamTerm (expr, arglist);
1143       break;
1144     case unaryExpr:
1145       expr1 = constraintExprData_unaryExprGetExpr (data);
1146       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1147       data = constraintExprData_unaryExprSetExpr (data, expr1);
1148       break;
1149     case binaryexpr:
1150       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1151       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1152       
1153       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1154       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1155       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1156       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1157       
1158       break;
1159     default:
1160       llassert(FALSE);
1161       data = NULL;
1162     }
1163   return expr;
1164 }
1165
1166 constraintExpr constraintExpr_doFixResult (/*@returned@*/  constraintExpr expr, exprNode fcnCall)
1167 {
1168   constraintExprKind kind;
1169   constraintExpr expr1, expr2;
1170   constraintExprData data;
1171   llassert (expr != NULL);
1172
1173   data = expr->data;
1174   
1175   kind = expr->kind;
1176   
1177   switch (kind)
1178     {
1179     case term:
1180       expr = doFixResultTerm (expr, fcnCall);
1181       break;
1182     case unaryExpr:
1183       expr1 = constraintExprData_unaryExprGetExpr (data);
1184       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1185       data = constraintExprData_unaryExprSetExpr (data, expr1);
1186       break;
1187     case binaryexpr:
1188       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1189       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1190       
1191       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1192       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1193       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1194       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1195       
1196       break;
1197     default:
1198       llassert(FALSE);
1199       data = NULL;
1200     }
1201   return expr;
1202 }
1203
1204 cstring constraintExpr_print (constraintExpr expr) /*@*/
1205 {
1206   return constraintExpr_unparse(expr);
1207 }
1208
1209 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1210 {
1211   cstring t;
1212
1213   t = constraintExpr_unparse(expr);
1214
1215   if (strstr (t, "MAXSET") != NULL )
1216     return (TRUE);
1217   else
1218     return FALSE;
1219 }
1220
1221
1222
1223       /*returns 1 0 -1 like strcmp
1224         1 => expr1 > expr2
1225         0 => expr1 == expr2
1226         -1 => expr1 < expr2
1227        */
1228 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1229 {
1230   int value1, value2;
1231
1232   if (constraintExpr_similar (expr1, expr2) )
1233     {
1234       return 0;
1235     }
1236   value1 = constraintExpr_getValue(expr1);
1237   value2 = constraintExpr_getValue(expr2);
1238
1239   if (value1 > value2)
1240     return 1;
1241
1242   if (value1 == value2)
1243     return 0;
1244
1245   else
1246     return -1;
1247 }
1248
1249 int constraintExpr_getValue (constraintExpr expr)
1250 {
1251   llassert (expr->kind == term);
1252   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data) ) );
1253 }
1254
1255 bool constraintExpr_canGetValue (constraintExpr expr)
1256 {
1257   switch (expr->kind)
1258     {
1259     case term:
1260       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1261     default:
1262       return FALSE;
1263       
1264     }
1265
1266   BADEXIT;
1267 }
1268
1269 bool constraintExpr_canCompare (constraintExpr expr1, constraintExpr expr2)
1270 {
1271   
1272   llassert(expr1 && expr2);
1273   return (  constraintExpr_canGetValue(expr1) &&
1274             constraintExpr_canGetValue(expr2)
1275             );
1276 }
1277
1278
1279 fileloc constraintExpr_getFileloc (constraintExpr expr)
1280 {
1281   constraintExpr e;
1282 constraintTerm t;
1283   constraintExprKind kind;
1284
1285  kind = expr->kind;
1286   
1287   switch (kind)
1288     {
1289     case term:
1290       t = constraintExprData_termGetTerm (expr->data);
1291       return (constraintTerm_getFileloc (t) );
1292       /*@notreached@*/
1293       break;      
1294     case unaryExpr:
1295       e = constraintExprData_unaryExprGetExpr (expr->data);
1296       return (constraintExpr_getFileloc (e) );
1297       /*@notreached@*/
1298       break;           
1299     case binaryexpr:
1300       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1301       return (constraintExpr_getFileloc (e) );
1302       /*@notreached@*/
1303       break;
1304     }
1305   llassert (FALSE);
1306   //  llfatalbug("Code should be reached");
1307   return (fileloc_undefined);
1308 }
1309
1310 /*drl moved from constriantTerm.c 5/20/001*/
1311 static constraintExpr 
1312 doFixResultTerm (constraintExpr e, exprNode fcnCall)
1313 {
1314   constraintTerm t;
1315   sRef s;
1316   /*maybe this should move to cosntraintExpr.c -drl7x 5/18/01*/
1317   /*@i22*/ constraintExprData data = e->data;
1318   
1319   /*@i22*/constraintExprKind kind = e->kind;
1320   
1321   constraintExpr ret;
1322
1323   llassert(kind == term);
1324
1325   t = constraintExprData_termGetTerm (data);
1326   llassert (t != NULL);
1327
1328   ret = e;
1329   switch (constraintTerm_getKind(t) )
1330     {
1331     case EXPRNODE:
1332       break;
1333     case INTLITERAL:
1334       break;
1335       
1336     case SREF:
1337       s = constraintTerm_getSRef(t);
1338       if (sRef_isResult (s))
1339         {
1340           ret = constraintExpr_makeExprNode(fcnCall);
1341         }
1342       break;
1343     default:
1344       BADEXIT;
1345     }
1346   
1347   return ret;
1348   
1349 }
1350
1351 /*drl moved from constriantTerm.c 5/20/001*/
1352 static constraintExpr 
1353 doSRefFixConstraintParamTerm (constraintExpr e, exprNodeList arglist)
1354 {
1355   constraintTerm t;
1356
1357   /*maybe this should move to cosntraintExpr.c -drl7x 5/18/01*/
1358
1359   /*@i22*/ constraintExprData data = e->data;
1360   
1361   /*@i22*/ constraintExprKind kind = e->kind;
1362   
1363   constraintExpr ret;
1364
1365   llassert(kind == term);
1366
1367   t = constraintExprData_termGetTerm (data);
1368   llassert (t != NULL);
1369
1370   ret = e;
1371   switch (t->kind)
1372     {
1373     case EXPRNODE:
1374       /*@i334*/  //wtf
1375       //   s = message ("%s @ %s ", exprNode_unparse (term->value.expr),
1376       //           fileloc_unparse (term->loc) );
1377       break;
1378     case INTLITERAL:
1379       //  s = message (" %d ", term->value.intlit);
1380        break;
1381       
1382     case SREF:
1383       ret = sRef_fixConstraintParam (t->value.sref, arglist);
1384       
1385       //      s = message ("%s ", sRef_unparse (term->value.sref) );
1386
1387       break;
1388     default:
1389       BADEXIT;
1390     }
1391   return ret;
1392   
1393 }
1394
1395
1396 /* bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term) */
1397 /* { */
1398 /*   if (constraintTerm_hasTerm (expr->term, term) ) */
1399 /*     return TRUE; */
1400
1401 /*   if ( (expr->expr) != NULL) */
1402 /*     { */
1403 /*       return ( constraintExpr_includesTerm (expr->expr, term) ); */
1404 /*     } */
1405 /*   return FALSE; */
1406
1407 /* } */
1408
1409
1410
1411
This page took 0.146148 seconds and 5 git commands to generate.