Switched from manual to automated handling of cgrammar
[splint-patched.git] / src / constraintExpr.c
blob627cfc25cc01f65ae078492e33a69fc2ad4b4e19
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
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
26 ** constraintExpr.c
29 /* #define DEBUGPRINT 1 */
31 # include "splintMacros.nf"
32 # include "basic.h"
33 # include "cgrammar.h"
35 # include "exprChecks.h"
36 # include "exprNodeSList.h"
39 static ctype constraintExpr_getOrigType (constraintExpr p_e);
40 static bool constraintExpr_hasTypeChange(constraintExpr p_e) /*@*/;
42 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr, int p_literal);
45 /*@only@*/ static constraintExpr
46 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e,
47 sRef p_s, ctype p_ct);
49 /*@only@*/ static constraintExpr
50 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist) /*@modifies p_e@*/;
52 static /*@only@*/ constraintExpr
53 doFixResultTerm (/*@only@*/ constraintExpr p_e, /*@exposed@*/ exprNode p_fcnCall)
54 /*@modifies p_e@*/;
56 static bool constraintExpr_canGetCType (constraintExpr p_e) /*@*/;
58 static ctype constraintExpr_getCType (constraintExpr p_e);
60 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr p_e,
61 ctype p_tfrom, ctype p_tto,
62 fileloc p_loc);
64 /*@special@*/ /*@notnull@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
65 /* @allocates result->data @ @sets result->kind @ */ ;
67 void constraintExpr_free (/*@only@*/ constraintExpr expr)
69 if (constraintExpr_isDefined(expr) )
71 switch (expr->kind)
73 case unaryExpr:
74 constraintExprData_freeUnaryExpr(expr->data);
75 break;
76 case binaryexpr:
77 constraintExprData_freeBinaryExpr(expr->data);
78 break;
79 case term:
80 constraintExprData_freeTerm(expr->data);
81 break;
82 default:
83 BADEXIT;
86 expr->data = NULL;
87 free (expr);
89 else
91 llcontbug(message("attempted to free null pointer in constraintExpr_free"));
95 bool constraintExpr_isLit (constraintExpr expr)
97 llassert (expr != NULL);
99 if (expr->kind == term)
101 constraintTerm term = constraintExprData_termGetTerm (expr->data);
102 if (constraintTerm_isIntLiteral (term) )
104 return TRUE;
108 return FALSE;
111 static bool isZeroBinaryOp (constraintExpr expr)
113 constraintExpr e2;
115 llassert (expr != NULL); /* evans 2001-07-18 */
117 if (!constraintExpr_isBinaryExpr (expr) )
119 return FALSE;
123 e2 = constraintExprData_binaryExprGetExpr2(expr->data);
125 llassert (e2 != NULL); /* evans 2001-07-18 */
127 if (constraintExpr_isBinaryExpr (e2) )
129 constraintExpr e1;
130 constraintExprBinaryOpKind op;
132 op = constraintExprData_binaryExprGetOp (e2->data);
134 e1 = constraintExprData_binaryExprGetExpr1(e2->data);
136 if (constraintExpr_isLit(e1) )
138 if (constraintExpr_getValue(e1) == 0 )
140 return TRUE;
144 return FALSE;
147 /* change expr + (o - expr) to (expr -expr) */
149 /*@only@*/ /*@notnull@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
151 constraintExpr expr1, expr2;
153 constraintExpr temp;
155 constraintExprBinaryOpKind op;
157 constraintExprBinaryOpKind tempOp;
159 llassert (expr != NULL); /* evans 2001-07-18 */
161 if (!isZeroBinaryOp(expr) )
162 return expr;
165 expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
166 expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
167 op = constraintExprData_binaryExprGetOp(expr->data);
169 llassert( constraintExpr_isBinaryExpr(expr2) );
171 temp = constraintExprData_binaryExprGetExpr2 (expr2->data);
172 temp = constraintExpr_copy (temp);
174 tempOp = constraintExprData_binaryExprGetOp (expr2->data);
176 if (op == BINARYOP_PLUS)
177 op = tempOp;
178 else if (op == BINARYOP_MINUS)
180 if (tempOp == BINARYOP_PLUS)
181 op = BINARYOP_MINUS;
182 else if (tempOp == BINARYOP_MINUS)
183 op = BINARYOP_PLUS;
184 else
185 BADEXIT;
187 else
188 BADEXIT;
190 expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
191 expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
193 return expr;
197 /*@only@*//*@notnull@*/ constraintExpr constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr,
198 /*@out@*/ bool * propagate,
199 /*@out@*/ int *literal)
201 constraintExpr expr1;
202 constraintExpr expr2;
203 bool propagate1, propagate2;
204 int literal1, literal2;
205 constraintExprBinaryOpKind op;
207 propagate1 = FALSE;
208 propagate2 = FALSE;
210 literal1 = 0;
211 literal2 = 0;
213 *propagate = FALSE;
214 *literal = 0;
217 llassert (expr != NULL);
219 /* we simplify unaryExpr elsewhere */
220 if (expr->kind != binaryexpr)
221 return expr;
223 op = constraintExprData_binaryExprGetOp (expr->data);
225 DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
227 expr = removeZero(expr);
229 expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
230 expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
232 expr1 = constraintExpr_copy(expr1);
233 expr2 = constraintExpr_copy(expr2);
235 expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
236 expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
238 expr1 = removeZero(expr1);
239 expr2 = removeZero(expr2);
242 *propagate = propagate1 || propagate2;
244 if (op == BINARYOP_PLUS)
245 *literal = literal1 + literal2;
246 else if (op == BINARYOP_MINUS)
247 *literal = literal1 - literal2;
248 else
249 BADEXIT;
251 if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
253 long t1, t2;
254 t1 = constraintExpr_getValue (expr1);
255 t2 = constraintExpr_getValue (expr2);
256 llassert(*propagate == FALSE);
257 *propagate = FALSE;
259 constraintExpr_free (expr);
260 constraintExpr_free (expr1);
261 constraintExpr_free (expr2);
263 if (op == BINARYOP_PLUS )
264 return (constraintExpr_makeIntLiteral ((t1+t2) ));
265 else if (op == BINARYOP_MINUS)
266 return (constraintExpr_makeIntLiteral ((t1-t2) ));
267 else
268 BADEXIT;
272 if (constraintExpr_isLit (expr1) )
274 *propagate = TRUE;
276 *literal += constraintExpr_getValue (expr1);
278 if (op == BINARYOP_PLUS)
280 constraintExpr_free(expr1);
281 constraintExpr_free(expr);
282 return expr2;
284 else if (op == BINARYOP_MINUS)
287 constraintExpr temp;
289 /* this is an ugly kludge to deal with not
290 having a unary minus operation...*/
292 temp = constraintExpr_makeIntLiteral (0);
293 temp = constraintExpr_makeSubtractExpr (temp, expr2);
295 constraintExpr_free(expr1);
296 constraintExpr_free(expr);
298 llassert (constraintExpr_isDefined(temp) );
299 return temp;
301 else
303 BADBRANCH; /* evans 2001-07-18 */
307 if (constraintExpr_isLit (expr2) )
309 *propagate = TRUE;
311 if ( op == BINARYOP_PLUS )
312 *literal += constraintExpr_getValue (expr2);
313 else if (op == BINARYOP_MINUS)
314 *literal -= constraintExpr_getValue (expr2);
315 else
316 BADEXIT;
319 constraintExpr_free(expr2);
320 constraintExpr_free(expr);
321 return expr1;
324 DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
326 expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
327 expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
329 expr = removeZero(expr);
330 return expr;
333 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
335 bool propagate;
336 int literal;
338 DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
339 expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
342 if (propagate)
344 constraintExpr ret;
346 if (literal != 0)
348 ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
349 expr = ret;
352 DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr) ) ) );
354 llassert(constraintExpr_isDefined(expr) );
355 return expr;
358 /*@special@*/
359 static /*@notnull@*/ constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
361 constraintExpr ret;
362 ret = dmalloc (sizeof (*ret) );
363 ret->kind = term;
364 ret->data = NULL;
365 ret->ct = FALSE;
366 ret->origType = ctype_undefined;
367 return ret;
370 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
372 constraintExprData ret;
373 llassert(constraintExprData_isDefined(data));
375 switch (kind)
377 case binaryexpr:
378 ret = constraintExprData_copyBinaryExpr(data);
379 break;
380 case unaryExpr:
381 ret = constraintExprData_copyUnaryExpr(data);
382 break;
383 case term:
384 ret = constraintExprData_copyTerm(data);
385 break;
386 default:
387 BADEXIT;
389 return ret;
392 constraintExpr constraintExpr_copy (constraintExpr expr)
394 constraintExpr ret;
395 ret = constraintExpr_alloc ();
398 /*drl 03/02/2003 this shouldn't be used to copy a null
399 expression but handle things cleanly if it is*/
400 llassert (!constraintExpr_isUndefined(expr) );
402 if (constraintExpr_isUndefined(expr) )
404 return constraintExpr_undefined;
407 ret->kind = expr->kind;
409 ret->data = copyExprData (expr->data, expr->kind);
410 ret->ct = expr->ct;
411 ret->origType = expr->origType;
412 return ret;
416 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
418 constraintExpr ret;
419 constraintTerm t;
420 ret = constraintExpr_alloc();
421 ret->kind = term;
422 ret->data = dmalloc (sizeof *(ret->data) );
423 t = constraintTerm_makeExprNode (e);
424 ret->data = constraintExprData_termSetTerm (ret->data, t);
425 ret->ct = FALSE;
426 ret->origType = ctype_undefined;
428 return ret;
431 /*@access exprNode@*/
432 constraintExpr constraintExpr_makeExprNode (exprNode e)
434 sRef s;
435 constraintExpr ret, ce1, ce2;
436 exprData data;
437 exprNode t, t1, t2;
438 lltok tok;
440 if (exprNode_isUndefined (e))
442 return constraintExpr_undefined;
445 data = e->edata;
447 switch (e->kind)
449 case XPR_SIZEOF:
450 t = exprData_getSingle (data);
451 while (exprNode_isInParens (t) )
453 t = exprData_getUopNode (t->edata);
455 s = exprNode_getSref (t);
456 if (sRef_isFixedArray(s) )
458 int size;
460 size = (int) sRef_getArraySize(s);
461 ret = constraintExpr_makeIntLiteral (size);
463 else if (exprNode_isStringLiteral (t))
465 cstring str = multiVal_forceString (exprNode_getValue(t));
466 ret = constraintExpr_makeIntLiteral (size_toLong (cstring_length (str) + 1));
468 else
470 DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
471 ret = oldconstraintExpr_makeTermExprNode (e);
473 break;
475 case XPR_OP:
476 DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
477 t1 = exprData_getOpA (data);
478 t2 = exprData_getOpB (data);
479 tok = exprData_getOpTok (data);
481 if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
483 ce1 = constraintExpr_makeExprNode (t1);
484 ce2 = constraintExpr_makeExprNode (t2);
485 ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);
489 /* define this block to activate the cheesy heuristic
490 for handling sizeof expressions*/
491 #if 0
495 drl 8-11-001
497 We handle expressions containing sizeof with the rule
498 (sizeof type ) * Expr = Expr
500 This is the total wronge way to do this but...
501 it may be better than nothing
506 else if (lltok_isMult(tok) )
508 if ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
510 ret = constraintExpr_makeExprNode(t2);
512 else if ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
514 ret = constraintExpr_makeExprNode(t1);
516 else
518 ret = oldconstraintExpr_makeTermExprNode (e);
521 #endif
523 else
524 ret = oldconstraintExpr_makeTermExprNode (e);
526 break;
527 case XPR_PARENS:
528 t = exprData_getUopNode (data);
529 ret = constraintExpr_makeExprNode (t);
530 break;
532 case XPR_PREOP:
533 t = exprData_getUopNode (data);
534 tok = exprData_getUopTok (data);
535 if (lltok_isIncOp (tok))
537 constraintExpr temp;
538 temp = constraintExpr_makeExprNode(t);
539 ret = constraintExpr_makeIncConstraintExpr(temp);
541 else if (lltok_isDecOp (tok))
543 constraintExpr temp;
544 temp = constraintExpr_makeExprNode(t);
545 ret = constraintExpr_makeDecConstraintExpr(temp);
547 else
548 ret = oldconstraintExpr_makeTermExprNode (e);
549 break;
551 case XPR_POSTOP:
552 t = exprData_getUopNode (data);
553 ret = constraintExpr_makeExprNode (t);
554 break;
555 case XPR_CAST:
556 t = exprData_getCastNode (data);
557 ret = constraintExpr_makeExprNode (t);
558 break;
559 case XPR_COMMA:
560 t = exprData_getPairA (data);
561 ret = constraintExpr_makeExprNode(t);
562 break;
563 default:
564 ret = oldconstraintExpr_makeTermExprNode (e);
567 return ret;
570 /*@noaccess exprNode@*/
575 /*@only@*/ constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
577 return oldconstraintExpr_makeTermExprNode(e);
580 static constraintExpr constraintExpr_makeTerm (/*@only@*/ constraintTerm t)
582 constraintExpr ret;
584 ret = constraintExpr_alloc();
585 ret->kind = term;
586 ret->data = dmalloc (sizeof *(ret->data) );
587 ret->data->term = NULL;
588 ret->data = constraintExprData_termSetTerm (ret->data, t);
589 ret->ct = FALSE;
590 ret->origType = ctype_undefined;
592 return ret;
595 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
597 constraintExpr ret;
598 constraintTerm t;
599 ret = constraintExpr_alloc();
600 ret->kind = term;
601 ret->data = dmalloc (sizeof *(ret->data) );
602 t = constraintTerm_makesRef (s);
603 ret->data = constraintExprData_termSetTerm (ret->data, t);
605 ret->ct = FALSE;
606 ret->origType = ctype_undefined;
608 return ret;
611 /*@special@*/ /*@notnull@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
613 constraintExpr ret;
614 ret = constraintExpr_alloc();
615 ret->kind = unaryExpr;
616 ret->data = dmalloc (sizeof *(ret->data));
617 ret->data->unaryOp.expr = constraintExpr_undefined;
618 return ret;
621 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
623 constraintExpr ret;
624 ret = makeUnaryOpGeneric();
626 /*@-uniondef@*/
627 /*@-compdef@*/
628 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
629 ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
631 return ret;
633 /*@=compdef@*/
634 /*@=uniondef@*/
638 /*@only@*/ /*@notnull@*/ static constraintExpr
639 constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr, constraintExprUnaryOpKind Op)
641 constraintExpr ret;
642 ret = makeUnaryOpGeneric();
644 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
645 ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
647 ret->ct = FALSE;
648 ret->origType = ctype_undefined;
650 return ret;
653 /*@only@*/ /*@notnull@*/
654 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
656 constraintExpr ret;
657 constraintExpr sub;
658 sub = constraintExpr_makeExprNode (expr);
659 ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
661 return ret;
664 /*@only@*/ /*@notnull@*/
665 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
667 constraintExpr ret;
668 ret = constraintExpr_makeUnaryOp (c, MAXSET);
669 return ret;
673 /*@only@*/ /*@notnull@*/
674 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s, constraintExprUnaryOpKind op)
676 constraintExpr ret;
677 constraintExpr t;
679 t = constraintExpr_makeTermsRef (s);
680 ret = constraintExpr_makeUnaryOpConstraintExpr (t);
681 ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
683 return ret;
686 /*@only@*/
687 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
689 return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
692 /*@only@*/
693 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
695 return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
698 /*@only@*/
699 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
701 constraintExpr ret;
702 ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
704 switch (lltok_getTok (op))
706 case QMAXSET:
707 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
708 break;
709 case QMAXREAD:
710 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
711 break;
712 default:
713 llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op)));
715 return ret;
718 /*@only@*/
719 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
721 constraintExpr ret;
722 ret = constraintExpr_makeExprNode (expr);
724 ret = constraintExpr_makeMaxSetConstraintExpr (ret);
726 llassert (ret != NULL);
727 return ret;
730 /*@only@*/
731 constraintExpr constraintExpr_makeMaxReadExpr (exprNode expr)
733 constraintExpr ret;
734 ret = constraintExpr_makeUnaryOpExprNode(expr);
735 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
736 return ret;
739 # if 0
740 /*@only@*/
741 /*@unused@*/ static constraintExpr constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
743 constraintExpr ret;
744 ret = constraintExpr_makeUnaryOpExprNode(expr);
745 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINSET);
746 return ret;
749 /*@only@*/
750 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
752 constraintExpr ret;
753 ret = constraintExpr_makeUnaryOpExprNode(expr);
754 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
755 return ret;
757 # endif
759 /*@only@*/
760 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
762 constraintExpr ret;
763 ret = constraintExpr_makeExprNode (expr);
764 return ret;
767 /*@only@*/ /*@notnull@*/
768 constraintExpr constraintExpr_makeIntLiteral (long i)
770 constraintExpr ret;
771 constraintTerm t;
772 ret = constraintExpr_alloc();
773 ret->kind = term;
774 ret->data = dmalloc (sizeof *(ret->data) );
775 t = constraintTerm_makeIntLiteral (i);
776 ret->data = constraintExprData_termSetTerm (ret->data, t);
778 ret->ct = FALSE;
779 ret->origType = ctype_undefined;
781 return ret;
785 constraintExpr constraintExpr_makeValueInt (int i)
787 return constraintExpr_makeIntLiteral (i);
791 /*@only@*/ /*@notnull@*/
792 /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
793 /*@allocates result->data @*/ /*@sets result->kind @*/
795 constraintExpr ret;
796 ret = constraintExpr_alloc();
797 ret->kind = binaryexpr;
798 ret->data = dmalloc ( sizeof *(ret->data) );
800 ret->data->binaryOp.expr1 = constraintExpr_undefined;
801 ret->data->binaryOp.expr2 = constraintExpr_undefined;
803 return ret;
807 static /*@notnull@*/ /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
810 constraintExpr ret;
812 ret = constraintExpr_makeBinaryOp();
813 ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
814 ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
815 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
817 ret->ct = FALSE;
818 ret->origType = ctype_undefined;
820 return ret;
823 /*@only@*/
824 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
826 constraintExpr ret;
827 ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
829 if (lltok_getTok (op) == TPLUS)
831 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
833 else if (lltok_getTok (op) == TMINUS)
835 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
837 else
839 llassert (FALSE);
842 return ret;
845 # if 0
846 /*@only@*/
847 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
849 constraintExpr ret;
850 constraintExpr sub1, sub2;
851 sub1 = constraintExpr_makeTermExprNode (expr1);
852 sub2 = constraintExpr_makeTermExprNode (expr2);
853 ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
854 return ret;
856 # endif
858 static /*@notnull@*/ /*@only@*/
859 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
861 constraintExpr ret;
862 constraintExpr constExpr;
864 constExpr = constraintExpr_makeIntLiteral (literal);
865 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
866 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
867 return ret;
870 /*@only@*/
871 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
873 constraintExpr ret;
874 constraintExpr inc;
876 inc = constraintExpr_makeIntLiteral (1);
877 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
878 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
879 return ret;
883 /*@only@*/ constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
885 constraintExpr ret;
887 DPRINTF ((message ("Making subtract expression") ) );
889 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
890 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_MINUS);
891 return ret;
894 /*@only@*/
895 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
896 constraintExpr expr, /*@only@*/
897 constraintExpr addent)
899 constraintExpr ret;
901 DPRINTF ((message ("Doing addTerm simplification") ) );
903 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
904 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_PLUS);
905 return ret;
909 /*@only@*/
910 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
912 constraintExpr ret;
913 constraintExpr inc;
915 inc = constraintExpr_makeIntLiteral (1);
916 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
917 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
918 return ret;
921 /*@only@*/
922 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
924 switch (op)
926 case MAXSET:
927 return message("maxSet");
928 case MINSET:
929 return message("minSet");
930 case MAXREAD:
931 return message("maxRead");
932 case MINREAD:
933 return message("minRead");
934 default:
935 llassert(FALSE);
936 return message ("<(Unary OP OTHER>");
941 /*@only@*/
942 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
945 switch (op)
947 case BINARYOP_PLUS:
948 return message("+");
949 case BINARYOP_MINUS:
950 return message("-");
952 default:
953 llassert(FALSE);
954 return message ("<binary OP Unknown>");
958 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
960 constraintExprKind kind;
962 llassert (expr1 != NULL);
963 llassert (expr2 != NULL);
964 if (expr1->kind != expr2->kind)
965 return FALSE;
967 kind = expr1->kind;
969 switch (kind)
971 case term:
972 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
973 constraintExprData_termGetTerm(expr2->data) );
974 /*@notreached@*/ break;
976 case unaryExpr:
977 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
978 return FALSE;
980 return (constraintExpr_similar (
981 constraintExprData_unaryExprGetExpr (expr1->data),
982 constraintExprData_unaryExprGetExpr (expr2->data)
985 case binaryexpr:
986 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
987 return FALSE;
989 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
990 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
991 return FALSE;
993 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
994 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
995 return FALSE;
996 else
997 return TRUE;
998 /*@notreached@*/
999 break;
1001 default:
1002 llassert(FALSE);
1003 return FALSE;
1005 /*@notreached@*/
1006 return FALSE;
1009 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
1011 constraintExprKind kind;
1013 llassert (expr1 != NULL);
1014 llassert (expr2 != NULL);
1015 if (expr1->kind != expr2->kind)
1016 return FALSE;
1018 kind = expr1->kind;
1020 switch (kind)
1022 case term:
1023 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
1024 constraintExprData_termGetTerm(expr2->data) );
1025 /*@notreached@*/ break;
1027 case unaryExpr:
1028 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
1029 return FALSE;
1031 return (constraintExpr_same (
1032 constraintExprData_unaryExprGetExpr (expr1->data),
1033 constraintExprData_unaryExprGetExpr (expr2->data)
1037 case binaryexpr:
1038 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
1039 return FALSE;
1041 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
1042 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
1043 return FALSE;
1045 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
1046 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
1047 return FALSE;
1048 else
1049 return TRUE;
1050 /*@notreached@*/ break;
1052 default:
1053 llassert(FALSE);
1054 return FALSE;
1057 /*@notreached@*/
1058 BADEXIT;
1061 bool
1062 constraintExpr_search (/*@observer@*/ constraintExpr c,
1063 /*@observer@*/ constraintExpr old)
1065 bool ret = FALSE;
1066 constraintExprKind kind;
1067 constraintExpr temp;
1069 if (constraintExpr_similar (c, old))
1071 DPRINTF (("Found %q", constraintExpr_unparse (old)));
1072 return TRUE;
1075 llassert (constraintExpr_isDefined (c) && constraintExpr_isDefined(old) );
1077 if ( !(constraintExpr_isDefined (c) && constraintExpr_isDefined(old) ) )
1078 return FALSE;
1080 kind = c->kind;
1082 switch (kind)
1084 case term:
1085 break;
1086 case unaryExpr:
1087 temp = constraintExprData_unaryExprGetExpr (c->data);
1088 ret = ret || constraintExpr_search (temp, old);
1089 break;
1090 case binaryexpr:
1092 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1093 ret = ret || constraintExpr_search(temp, old);
1095 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1096 ret = ret || constraintExpr_search(temp, old);
1097 break;
1098 default:
1099 llassert(FALSE);
1101 return ret;
1106 /*@only@*/ constraintExpr
1107 constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old,
1108 /*@temp@*/ constraintExpr newExpr )
1110 constraintExprKind kind;
1111 constraintExpr temp;
1112 constraintExpr ret;
1114 llassert (constraintExpr_isDefined (newExpr) && (constraintExpr_isDefined (old) && constraintExpr_isDefined(c) ) );
1116 if (constraintExpr_similar (c, old))
1118 ctype newType = ctype_unknown;
1119 ctype cType = ctype_unknown;
1121 ret = constraintExpr_copy (newExpr);
1122 llassert(constraintExpr_isDefined(ret) );
1123 /*drl if newExpr != NULL then ret will != NULL*/
1125 DPRINTF (("Replacing %s with %s in %s",
1126 constraintExpr_unparse (old), constraintExpr_unparse (newExpr),
1127 constraintExpr_unparse (c)));
1129 if (constraintExpr_canGetCType (c) && constraintExpr_canGetCType (newExpr))
1131 cType = constraintExpr_getCType(c);
1132 newType = constraintExpr_getCType (newExpr);
1134 if (ctype_match (cType,newType))
1136 DPRINTF (("constraintExpr_searchandreplace: replacing "
1137 " %s with type %s with %s with type %s",
1138 constraintExpr_unparse (c), ctype_unparse(cType),
1139 constraintExpr_unparse (newExpr), ctype_unparse(newType)));
1141 ret->ct = TRUE;
1142 ret->origType = cType;
1143 DPRINTF (("Type: %s", ctype_unparse (constraintExpr_getCType (ret))));
1147 if (constraintExpr_hasMaxSet (c))
1149 if (constraintExpr_hasTypeChange (c))
1151 fileloc loc = constraintExpr_loc (c);
1152 DPRINTF (("constraintExpr_searchandreplace: encountered "
1153 "MaxSet with changed type %s ",
1154 constraintExpr_unparse (c)));
1156 if (c->kind == unaryExpr)
1158 constraintExpr ce = constraintExprData_unaryExprGetExpr (c->data);
1159 DPRINTF (("Its a unary! %s / %s",
1160 ctype_unparse (constraintExpr_getCType (ce)),
1161 ctype_unparse (constraintExpr_getOrigType (ce))));
1162 ret = constraintExpr_adjustMaxSetForCast (ret, constraintExpr_getCType (ce),
1163 constraintExpr_getOrigType (ce),
1164 loc);
1166 else
1168 /* fix this with a conversation */
1169 DPRINTF (("Types: %s / %s", ctype_unparse (newType), ctype_unparse (cType)));
1170 ret = constraintExpr_adjustMaxSetForCast (ret, constraintExpr_getCType (c),
1171 constraintExpr_getOrigType(c),
1172 loc);
1177 constraintExpr_free (c);
1178 DPRINTF (("ret: %s", constraintExpr_unparse (ret)));
1179 return ret;
1182 kind = c->kind;
1184 switch (kind)
1186 case term:
1187 break;
1188 case unaryExpr:
1189 DPRINTF (("Making unary expression!"));
1190 temp = constraintExprData_unaryExprGetExpr (c->data);
1191 temp = constraintExpr_copy (temp);
1192 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1193 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1194 break;
1195 case binaryexpr:
1196 DPRINTF (("Making binary expression!"));
1197 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1198 temp = constraintExpr_copy (temp);
1199 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1200 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1202 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1203 temp = constraintExpr_copy (temp);
1204 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1205 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1206 break;
1207 default:
1208 llassert (FALSE);
1211 DPRINTF (("ret: %s", constraintExpr_unparse (c)));
1212 return c;
1215 /*@notnull@*/ static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c)
1217 constraintExprKind kind;
1218 constraintExpr temp;
1220 kind = c->kind;
1222 switch (kind)
1224 case term:
1225 break;
1226 case unaryExpr:
1227 temp = constraintExprData_unaryExprGetExpr (c->data);
1228 temp = constraintExpr_copy(temp);
1229 temp = constraintExpr_simplify (temp);
1230 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1231 break;
1232 case binaryexpr:
1233 DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1234 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1235 temp = constraintExpr_copy(temp);
1236 temp = constraintExpr_simplify (temp);
1238 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1240 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1241 temp = constraintExpr_copy(temp);
1242 temp = constraintExpr_simplify (temp);
1244 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1245 break;
1246 default:
1247 llassert(FALSE);
1249 return c;
1254 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1256 constraintTerm t;
1257 constraintExpr temp;
1259 llassert(c != NULL);
1261 switch (c->kind)
1263 case term:
1264 t = constraintExprData_termGetTerm (c->data);
1265 t = constraintTerm_copy(t);
1266 t = constraintTerm_setFileloc (t, loc);
1267 c->data = constraintExprData_termSetTerm (c->data, t);
1268 break;
1269 case binaryexpr:
1271 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1272 temp = constraintExpr_copy(temp);
1273 temp = constraintExpr_setFileloc (temp, loc);
1274 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1276 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1277 temp = constraintExpr_copy(temp);
1278 temp = constraintExpr_setFileloc (temp, loc);
1279 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1280 break;
1281 case unaryExpr:
1282 temp = constraintExprData_unaryExprGetExpr (c->data);
1283 temp = constraintExpr_copy(temp);
1284 temp = constraintExpr_setFileloc (temp, loc);
1285 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1286 break;
1288 return c;
1291 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/ /*@notnull@*/ constraintExpr c)
1293 constraintExpr e1, e2;
1294 constraintExprBinaryOpKind op;
1296 e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1297 e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1299 if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1301 long i;
1303 i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1304 constraintExpr_free(c);
1305 c = constraintExpr_makeIntLiteral (i);
1307 else
1309 op = constraintExprData_binaryExprGetOp (c->data);
1310 if (op == BINARYOP_MINUS)
1311 if (constraintExpr_similar(e1, e2) )
1313 constraintExpr_free(c);
1314 c = constraintExpr_makeIntLiteral (0);
1318 return c;
1322 this thing takes the lexpr and expr of a constraint and modifies lexpr
1323 and returns a (possiblly new) value for expr
1325 /* 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 */
1327 /* the approach is a little Kludgy but seems to work. I should probably use something cleaner at some point ... */
1330 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1332 constraintExpr expr1, expr2;
1333 constraintExprBinaryOpKind op;
1335 llassert(constraintExpr_isDefined (lexpr) && constraintExpr_isDefined (expr) );
1337 if (lexpr->kind != binaryexpr)
1338 return expr;
1340 expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1341 expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1343 op = constraintExprData_binaryExprGetOp (lexpr->data);
1345 expr1 = constraintExpr_copy(expr1);
1346 expr2 = constraintExpr_copy(expr2);
1348 llassert(constraintExpr_isDefined (expr1) && constraintExpr_isDefined (expr2) );
1350 /* drl possible problem : warning make sure this works */
1352 lexpr->kind = expr1->kind;
1353 sfree (lexpr->data);
1355 lexpr->data = copyExprData (expr1->data, expr1->kind);
1356 constraintExpr_free(expr1);
1358 if (op == BINARYOP_PLUS)
1359 expr = constraintExpr_makeSubtractExpr (expr, expr2);
1360 else if (op == BINARYOP_MINUS)
1361 expr = constraintExpr_makeAddExpr (expr, expr2);
1362 else
1363 BADEXIT;
1366 return expr;
1369 #warning this needs to be checked
1370 expr = constraintExpr_solveBinaryExpr (expr1, expr);
1372 expr = constraintExpr_solveBinaryExpr (expr2, expr);
1373 return expr;
1377 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1379 constraintExpr exp;
1381 llassert(constraintExpr_isDefined (c) );
1382 llassert (c->kind == unaryExpr);
1384 DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1386 if ((constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1387 (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1389 return c;
1392 exp = constraintExprData_unaryExprGetExpr (c->data);
1393 exp = constraintExpr_copy(exp);
1395 llassert(constraintExpr_isDefined (exp) );
1397 if (exp->kind == term)
1399 constraintTerm cterm;
1401 cterm = constraintExprData_termGetTerm (exp->data);
1403 if (constraintTerm_isStringLiteral(cterm) )
1405 cstring val;
1406 val = constraintTerm_getStringLiteral (cterm);
1407 if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1409 constraintExpr temp;
1411 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1412 cstring_free(val);
1413 constraintExpr_free(c);
1414 constraintExpr_free(exp);
1416 return temp;
1419 if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1421 constraintExpr temp;
1423 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1424 cstring_free(val);
1425 constraintExpr_free(c);
1426 constraintExpr_free(exp);
1428 return temp;
1430 BADEXIT;
1433 /* slight Kludge to handle var [] = { , , };
1434 ** type syntax I don't think this is sound but it should be good
1435 ** enough. The C standard is very confusing about initialization
1436 ** -- DRL 7/25/01
1439 if (constraintTerm_isInitBlock(cterm) )
1441 constraintExpr temp;
1442 int len;
1444 len = constraintTerm_getInitBlockLength(cterm);
1446 /* -- drl 12/08/2003 : decrementing to fix off by one error */
1448 len--;
1450 temp = constraintExpr_makeIntLiteral (len );
1452 constraintExpr_free(c);
1453 DPRINTF(( message("Changed to %q", constraintExpr_print(temp)
1454 ) ));
1455 constraintExpr_free(exp);
1456 return temp;
1459 constraintExpr_free(exp);
1460 return c;
1463 if (exp->kind != binaryexpr)
1465 constraintExpr_free(exp);
1466 return c;
1469 if (constraintExprData_binaryExprGetOp (exp->data) == BINARYOP_PLUS )
1472 /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1475 constraintExpr temp, temp2;
1477 DPRINTF ((message ("Doing fancy simplification") ) );
1479 temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1481 temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1483 temp2 = constraintExpr_copy(temp2);
1484 c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1487 temp = constraintExpr_copy (temp);
1489 c = constraintExpr_makeSubtractExpr (c, temp);
1491 DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1495 DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1497 constraintExpr_free(exp);
1498 return c;
1502 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1504 constraintExprKind kind;
1505 constraintExpr ret;
1506 constraintTerm t;
1508 DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );
1512 llassert ( constraintExpr_isDefined (c) );
1513 if (constraintExpr_isUndefined (c) )
1515 return constraintExpr_undefined;
1518 ret = constraintExpr_copy(c);
1519 llassert(constraintExpr_isDefined (ret) );
1521 constraintExpr_free(c);
1523 ret = constraintExpr_simplifyChildren (ret);
1525 ret = constraintExpr_combineConstants (ret);
1527 ret = constraintExpr_simplifyChildren (ret);
1530 kind = ret->kind;
1532 switch (kind)
1534 case term:
1535 t = constraintExprData_termGetTerm (ret->data);
1536 t = constraintTerm_copy(t);
1537 t = constraintTerm_simplify (t);
1538 ret->data = constraintExprData_termSetTerm (ret->data, t);
1539 break;
1540 case unaryExpr:
1541 ret = constraintExpr_simplifyunaryExpr (ret);
1542 break;
1543 case binaryexpr:
1544 ret = constraintExpr_simplifybinaryExpr (ret);
1545 break;
1546 default:
1547 llassert(FALSE);
1550 DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );
1551 return ret;
1555 /*@only@*/
1556 cstring constraintExpr_unparse (/*@temp@*/ constraintExpr ex) /*@*/
1558 cstring st;
1559 constraintExprKind kind;
1561 llassert (ex != NULL);
1563 kind = ex->kind;
1565 switch (kind)
1567 case term:
1568 if (context_getFlag (FLG_PARENCONSTRAINT) )
1570 st = message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1572 else
1574 st = message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1576 break;
1577 case unaryExpr:
1578 st = message ("%q(%q)",
1579 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1580 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1582 break;
1583 case binaryexpr:
1584 if (context_getFlag (FLG_PARENCONSTRAINT) )
1586 st = message ("(%q) %q (%q)",
1587 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1588 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1589 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1592 else
1594 st = message ("%q %q %q",
1595 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data)),
1596 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1597 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data))
1601 break;
1602 default:
1603 llassert(FALSE);
1604 st = message ("error");
1608 DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1609 return st;
1612 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/ constraintExpr expr, exprNodeList arglist)
1614 constraintTerm Term;
1615 constraintExprKind kind;
1616 constraintExpr expr1, expr2;
1617 constraintExprData data;
1618 llassert (expr != NULL);
1620 data = expr->data;
1622 kind = expr->kind;
1624 switch (kind)
1626 case term:
1627 Term = constraintExprData_termGetTerm(data);
1628 Term = constraintTerm_copy(Term);
1630 Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1631 data = constraintExprData_termSetTerm(data, Term);
1632 break;
1633 case unaryExpr:
1634 expr1 = constraintExprData_unaryExprGetExpr (data);
1635 expr1 = constraintExpr_copy(expr1);
1637 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1638 data = constraintExprData_unaryExprSetExpr (data, expr1);
1639 break;
1640 case binaryexpr:
1641 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1642 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1644 expr1 = constraintExpr_copy(expr1);
1645 expr2 = constraintExpr_copy(expr2);
1647 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1648 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1649 expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1650 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1652 break;
1653 default:
1654 llassert(FALSE);
1655 data = NULL;
1657 return expr;
1661 / *@only@* / constraintExpr constraintExpr_doSRefFixInvarConstraint (/ *@only@* / constraintExpr expr, sRef s, ctype ct)
1663 constraintExprKind kind;
1664 constraintExpr expr1, expr2;
1665 constraintExprData data;
1666 llassert (expr != NULL);
1668 data = expr->data;
1670 kind = expr->kind;
1672 switch (kind)
1674 case term:
1675 expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1676 break;
1677 case unaryExpr:
1678 expr1 = constraintExprData_unaryExprGetExpr (data);
1679 expr1 = constraintExpr_copy(expr1);
1680 expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1681 data = constraintExprData_unaryExprSetExpr (data, expr1);
1682 break;
1683 case binaryexpr:
1684 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1685 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1687 expr1 = constraintExpr_copy(expr1);
1688 expr2 = constraintExpr_copy(expr2);
1690 expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1691 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1692 expr2 = constraintExpr_doSRefFixInvarConstraint (expr2, s, ct);
1693 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1695 break;
1696 default:
1697 llassert(FALSE);
1698 data = NULL;
1700 return expr;
1704 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1706 constraintExprKind kind;
1707 constraintExpr expr1, expr2;
1708 constraintExprData data;
1709 llassert (expr != NULL);
1711 data = expr->data;
1713 kind = expr->kind;
1715 switch (kind)
1717 case term:
1718 expr = doSRefFixConstraintParamTerm (expr, arglist);
1719 break;
1720 case unaryExpr:
1721 expr1 = constraintExprData_unaryExprGetExpr (data);
1722 expr1 = constraintExpr_copy(expr1);
1723 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1724 data = constraintExprData_unaryExprSetExpr (data, expr1);
1725 break;
1726 case binaryexpr:
1727 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1728 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1730 expr1 = constraintExpr_copy(expr1);
1731 expr2 = constraintExpr_copy(expr2);
1733 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1734 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1735 expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1736 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1738 break;
1739 default:
1740 llassert(FALSE);
1741 data = NULL;
1743 return expr;
1746 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/ constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1748 constraintExprKind kind;
1749 constraintExpr expr1, expr2;
1750 constraintExprData data;
1751 llassert (expr != NULL);
1753 data = expr->data;
1755 kind = expr->kind;
1757 switch (kind)
1759 case term:
1760 expr = doFixResultTerm (expr, fcnCall);
1761 break;
1762 case unaryExpr:
1763 expr1 = constraintExprData_unaryExprGetExpr (data);
1764 expr1 = constraintExpr_copy(expr1);
1766 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1767 data = constraintExprData_unaryExprSetExpr (data, expr1);
1768 break;
1769 case binaryexpr:
1770 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1771 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1773 expr1 = constraintExpr_copy(expr1);
1774 expr2 = constraintExpr_copy(expr2);
1776 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1777 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1778 expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1779 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1781 break;
1782 default:
1783 llassert(FALSE);
1784 data = NULL;
1786 return expr;
1789 cstring constraintExpr_print (constraintExpr expr) /*@*/
1791 return constraintExpr_unparse (expr);
1794 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1796 cstring t;
1798 t = constraintExpr_unparse(expr);
1800 if (cstring_containsLit(t, "maxSet") != NULL )
1802 cstring_free(t);
1803 return (TRUE);
1805 else
1807 cstring_free(t);
1808 return FALSE;
1814 /*returns 1 0 -1 like strcmp
1815 1 => expr1 > expr2
1816 0 => expr1 == expr2
1817 -1 => expr1 < expr2
1820 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1822 long value1, value2;
1824 if (constraintExpr_similar (expr1, expr2) )
1826 return 0;
1829 value1 = constraintExpr_getValue(expr1);
1830 value2 = constraintExpr_getValue(expr2);
1832 if (value1 > value2)
1833 return 1;
1835 if (value1 == value2)
1836 return 0;
1838 else
1839 return -1;
1842 long constraintExpr_getValue (constraintExpr expr)
1844 llassert (constraintExpr_isDefined(expr) );
1845 llassert (expr->kind == term);
1847 return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1850 bool constraintExpr_canGetValue (constraintExpr expr)
1852 llassert ( constraintExpr_isDefined (expr) );
1853 if (constraintExpr_isUndefined (expr) )
1855 return FALSE;
1858 switch (expr->kind)
1860 case term:
1861 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1862 default:
1863 return FALSE;
1867 BADEXIT;
1870 fileloc constraintExpr_loc (constraintExpr expr)
1872 constraintExpr e;
1873 constraintTerm t;
1874 constraintExprKind kind;
1876 llassert ( constraintExpr_isDefined (expr) );
1877 if (constraintExpr_isUndefined (expr) )
1879 return fileloc_undefined;
1883 kind = expr->kind;
1885 switch (kind)
1887 case term:
1888 t = constraintExprData_termGetTerm (expr->data);
1889 return (constraintTerm_getFileloc (t) );
1890 /*@notreached@*/
1891 break;
1892 case unaryExpr:
1893 e = constraintExprData_unaryExprGetExpr (expr->data);
1894 return (constraintExpr_loc (e) );
1895 /*@notreached@*/
1896 break;
1897 case binaryexpr:
1898 e = constraintExprData_binaryExprGetExpr1 (expr->data);
1899 return (constraintExpr_loc (e) );
1900 /*@notreached@*/
1901 break;
1903 llassert (FALSE);
1904 return (fileloc_undefined);
1907 /*drl moved from constriantTerm.c 5/20/001*/
1908 static /*@only@*/ constraintExpr
1909 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1911 constraintTerm t;
1912 sRef s;
1913 constraintExprData data;
1914 constraintExprKind kind;
1915 constraintExpr ret;
1917 llassert (constraintExpr_isDefined (e) );
1919 data = e->data;
1920 kind = e->kind;
1922 llassert (kind == term);
1924 t = constraintExprData_termGetTerm (data);
1925 llassert (constraintTerm_isDefined (t));
1927 ret = e;
1929 switch (constraintTerm_getKind (t))
1931 case CTT_EXPR:
1932 case CTT_INTLITERAL:
1933 break;
1935 case CTT_SREF:
1936 s = constraintTerm_getSRef(t);
1937 if (sRef_isResult (s))
1939 ret = constraintExpr_makeExprNode(fcnCall);
1940 constraintExpr_free(e);
1941 e = NULL;
1943 else
1945 e = NULL;
1947 break;
1948 default:
1949 BADEXIT;
1952 return ret;
1956 #if 0
1958 /*to be used for structure checking */
1960 / *@only@* / static constraintExpr
1961 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e, sRef s, ctype ct)
1963 constraintTerm t;
1965 constraintExprData data = e->data;
1967 constraintExprKind kind = e->kind;
1969 constraintExpr ret;
1971 llassert(kind == term);
1973 t = constraintExprData_termGetTerm (data);
1974 llassert (constraintTerm_isDefined(t) );
1976 ret = e;
1978 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1980 switch (constraintTerm_getKind(t))
1982 case CTT_EXPR:
1983 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1984 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1985 break;
1986 case CTT_INTLITERAL:
1987 DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1988 break;
1990 case CTT_SREF:
1991 / * evans 2001-07-24: constants should use the original term * /
1992 if (!constraintTerm_canGetValue (t))
1994 sRef snew;
1995 DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ",
1996 constraintTerm_unparse (t) ) ));
1998 snew = fixSref (ct, s, constraintTerm_getSRef(t));
2000 ret = constraintExpr_makeTermsRef(snew);
2002 constraintExpr_free (e);
2004 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
2005 constraintExpr_print (ret) ) ));
2006 / *@-branchstate@* /
2007 } / *@=branchstate@* /
2009 break;
2010 default:
2011 BADEXIT;
2014 return ret;
2017 #endif
2019 /*drl moved from constriantTerm.c 5/20/001*/
2020 /*@only@*/ static constraintExpr
2021 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
2023 constraintTerm t;
2025 constraintExprData data;
2027 constraintExprKind kind;
2029 constraintExpr ret;
2032 llassert(constraintExpr_isDefined (e) );
2034 data = e->data;
2036 kind = e->kind;
2040 llassert(kind == term);
2042 t = constraintExprData_termGetTerm (data);
2043 llassert (constraintTerm_isDefined(t) );
2045 ret = e;
2047 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2049 switch (constraintTerm_getKind(t))
2051 case CTT_EXPR:
2052 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2053 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2054 break;
2055 case CTT_INTLITERAL:
2056 DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2057 break;
2058 case CTT_SREF:
2059 /* evans 2001-07-24: constants should use the original term */
2060 if (!constraintTerm_canGetValue (t))
2062 DPRINTF ((message("Doing sRef_fixConstraintParam for %q ",
2063 constraintTerm_unparse (t) ) ));
2064 ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
2066 constraintExpr_free (e);
2068 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
2069 constraintExpr_print (ret) ) ));
2070 /*@-branchstate@*/
2071 } /*@=branchstate@*/
2073 break;
2074 default:
2075 BADEXIT;
2078 return ret;
2083 #if 0
2084 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2086 if (constraintTerm_hasTerm (expr->term, term) )
2087 return TRUE;
2089 if ((expr->expr) != NULL)
2091 return ( constraintExpr_includesTerm (expr->expr, term) );
2093 return FALSE;
2096 #endif
2098 /*drl added 6/11/01 */
2099 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2102 llassert(constraintExpr_isDefined (c) );
2104 if ( ! (constraintExpr_isDefined (c) ) )
2105 return FALSE;
2107 if (c->kind == binaryexpr)
2108 return TRUE;
2110 else
2111 return FALSE;
2114 /*drl added 8/08/001 */
2115 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2117 llassert(constraintExpr_isDefined (c) );
2119 if (c->kind == term)
2120 return TRUE;
2122 else
2123 return FALSE;
2126 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2128 constraintTerm term;
2130 llassert(constraintExpr_isDefined (c) );
2132 llassert(constraintExpr_isTerm(c) );
2134 term = constraintExprData_termGetTerm(c->data);
2136 return term;
2139 static void binaryExpr_dump (/*@observer@*/ constraintExprData data, FILE *f)
2141 constraintExpr expr1;
2142 constraintExprBinaryOpKind binaryOp;
2143 constraintExpr expr2;
2146 binaryOp = constraintExprData_binaryExprGetOp (data);
2148 fprintf(f, "%d\n", (int) binaryOp);
2150 expr1 = constraintExprData_binaryExprGetExpr1 (data);
2151 expr2 = constraintExprData_binaryExprGetExpr2 (data);
2153 fprintf(f, "e1\n");
2155 constraintExpr_dump(expr1, f);
2157 fprintf(f, "e2\n");
2158 constraintExpr_dump(expr2, f);
2162 static constraintExpr binaryExpr_undump (FILE *f)
2164 constraintExpr expr1;
2165 constraintExprBinaryOpKind binaryOp;
2166 constraintExpr expr2;
2168 constraintExpr ret;
2172 char * str;
2173 char * os;
2175 os = mstring_create (MAX_DUMP_LINE_LENGTH);
2177 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2179 if (! mstring_isDefined(str) )
2181 llfatalbug(message("Library file is corrupted") );
2184 binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2186 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2188 if (! mstring_isDefined(str) )
2190 llfatalbug(message("Library file is corrupted") );
2193 reader_checkChar (&str, 'e');
2194 reader_checkChar (&str, '1');
2196 expr1 = constraintExpr_undump (f);
2198 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2200 reader_checkChar (&str, 'e');
2201 reader_checkChar (&str, '2');
2203 expr2 = constraintExpr_undump (f);
2205 ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2206 ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2208 free(os);
2209 return ret;
2214 static void unaryExpr_dump (/*@observer@*/ constraintExprData data, FILE *f)
2217 constraintExpr expr;
2218 constraintExprUnaryOpKind unaryOp;
2220 unaryOp = constraintExprData_unaryExprGetOp (data);
2222 fprintf(f, "%d\n", (int) unaryOp);
2224 expr = constraintExprData_unaryExprGetExpr (data);
2226 constraintExpr_dump(expr, f);
2229 static constraintExpr unaryExpr_undump ( FILE *f)
2232 constraintExpr expr;
2233 constraintExprUnaryOpKind unaryOp;
2234 constraintExpr ret;
2236 char * str;
2237 char * os;
2239 str = mstring_create (MAX_DUMP_LINE_LENGTH);
2240 os = str;
2241 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2243 if (! mstring_isDefined(str) )
2245 llfatalbug(message("Library file is corrupted") );
2248 unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2250 expr = constraintExpr_undump (f);
2252 ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2254 free(os);
2256 return ret;
2259 void constraintExpr_dump (/*@observer@*/ constraintExpr expr, FILE *f)
2261 constraintExprKind kind;
2262 constraintTerm t;
2265 llassert(constraintExpr_isDefined(expr) );
2267 DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2268 constraintExpr_unparse(expr)
2269 ) ));
2271 kind = expr->kind;
2273 fprintf(f,"%d\n", (int) kind);
2275 switch (kind)
2277 case term:
2278 t = constraintExprData_termGetTerm (expr->data);
2279 constraintTerm_dump (t, f);
2280 break;
2281 case unaryExpr:
2282 unaryExpr_dump (expr->data, f);
2283 break;
2284 case binaryexpr:
2285 binaryExpr_dump (expr->data, f);
2286 break;
2290 /*@only@*/ constraintExpr constraintExpr_undump (FILE *f)
2292 constraintExprKind kind;
2293 constraintTerm t;
2294 constraintExpr ret;
2296 char * s;
2297 char * os;
2299 s = mstring_create (MAX_DUMP_LINE_LENGTH);
2301 os = s;
2303 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2305 if (! mstring_isDefined(s) )
2307 llfatalbug(message("Library file is corrupted") );
2310 kind = (constraintExprKind) reader_getInt(&s);
2312 free (os);
2314 switch (kind)
2316 case term:
2317 t = constraintTerm_undump (f);
2318 ret = constraintExpr_makeTerm(t);
2319 break;
2320 case unaryExpr:
2321 ret = unaryExpr_undump (f);
2322 break;
2323 case binaryexpr:
2324 ret = binaryExpr_undump (f);
2325 break;
2328 return ret;
2332 int constraintExpr_getDepth (constraintExpr ex)
2334 int ret;
2336 constraintExprKind kind;
2338 llassert (ex != NULL);
2340 kind = ex->kind;
2342 switch (kind)
2344 case term:
2345 ret = 1;
2346 break;
2347 case unaryExpr:
2348 ret = constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2349 ret++;
2351 break;
2352 case binaryexpr:
2353 ret = 0;
2354 ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2356 ret++;
2358 ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2360 break;
2361 default:
2362 BADEXIT;
2365 return ret;
2369 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2371 if (constraintExpr_isUndefined(e))
2372 return FALSE;
2374 if (e->kind == term)
2376 return TRUE;
2378 else
2380 DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e)));
2381 return FALSE;
2385 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2387 constraintTerm t;
2389 llassert (constraintExpr_isDefined (e));
2390 llassert (constraintExpr_canGetCType (e));
2392 switch (e->kind)
2394 case term:
2395 t = constraintExprData_termGetTerm (e->data);
2396 return (constraintTerm_getCType(t) );
2397 /* assume that a unary expression will be an int ... */
2398 case unaryExpr:
2399 return ctype_unknown; /* was ctype_signedintegral; */
2400 /* drl for just return type of first operand */
2401 case binaryexpr:
2402 return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e->data)));
2403 default:
2404 BADEXIT;
2406 BADEXIT;
2409 /* drl add 10-5-001 */
2411 static bool constraintExpr_hasTypeChange (constraintExpr e)
2413 llassert(constraintExpr_isDefined(e));
2415 if (constraintExpr_isDefined((e)) && (e->ct == TRUE))
2417 return TRUE;
2420 if (e->kind == unaryExpr)
2422 if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2424 constraintExpr ce = constraintExprData_unaryExprGetExpr(e->data);
2425 DPRINTF (("Unary type change: [%x] %s", ce, constraintExpr_unparse (ce)));
2426 DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce)),
2427 ctype_unparse (constraintExpr_getOrigType (ce))));
2428 return (constraintExpr_hasTypeChange(ce));
2432 return FALSE;
2435 /* drl add 10-5-001 */
2437 static ctype constraintExpr_getOrigType (constraintExpr e)
2439 llassert (constraintExpr_isDefined (e));
2440 llassert (constraintExpr_hasTypeChange (e));
2442 if (e->ct == TRUE)
2444 return e->origType;
2447 if (e->kind == unaryExpr)
2449 if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2451 constraintExpr ce = constraintExprData_unaryExprGetExpr (e->data);
2452 return (constraintExpr_getOrigType(ce));
2457 BADEXIT;
2460 /*drl added these around 10/18/001*/
2462 static /*@only@*/ constraintExpr
2463 constraintExpr_div (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2465 int sizefrom = ctype_getSize (tfrom);
2466 int sizeto = ctype_getSize (tto);
2468 DPRINTF (("constraintExpr_div: %s", constraintExpr_unparse (e)));
2469 DPRINTF (("Types: %s / %s",
2470 ctype_unparse (tfrom),
2471 ctype_unparse (tto)));
2473 if (sizefrom == -1) {
2474 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tfrom)));
2477 if (sizeto == -1) {
2478 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tto)));
2481 if (sizeto == sizefrom)
2483 DPRINTF (("Sizes match: %d / %d", sizeto, sizefrom));
2484 ; /* Sizes match, a-ok */
2486 else
2488 float scale = (float) sizefrom / (float) sizeto;
2489 constraintTerm ct;
2490 long val;
2491 float fnewval;
2492 long newval;
2494 llassert (e != NULL);
2495 llassert (e->kind == term);
2496 ct = constraintExprData_termGetTerm (e->data);
2497 DPRINTF (("constraint: %s / %s", constraintExpr_unparse (e), constraintTerm_unparse (ct)));
2498 llassert (constraintTerm_canGetValue (ct));
2499 val = constraintTerm_getValue (ct);
2501 DPRINTF (("Scaling constraints by: %ld * %f", val, scale));
2503 fnewval = ((float) val) * scale;
2504 newval = (long) fnewval;
2506 DPRINTF (("Values: %f / %ld", fnewval, newval));
2508 if ((fnewval - (float) newval) > FLT_EPSILON)
2510 voptgenerror (FLG_ALLOCMISMATCH,
2511 message ("Allocated memory is converted to type %s of (size %d), "
2512 "which is not divisible into original allocation of space "
2513 "for %d elements of type %s (size %d)",
2514 ctype_unparse (tto), sizeto,
2515 long_toInt (val), ctype_unparse (tfrom), sizefrom),
2516 loc);
2519 constraintTerm_setValue (ct, newval);
2522 DPRINTF (("After div: %s", constraintExpr_unparse (e)));
2523 return e;
2527 /*@access exprNode@*/
2528 static /*@only@*/ constraintExpr
2529 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2531 exprData data;
2532 exprNode t1, t2, expr;
2533 lltok tok;
2534 constraintTerm t;
2536 llassert (constraintExpr_isDefined(e) );
2538 DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e),
2539 ctype_unparse(tfrom), ctype_unparse (tto)));
2541 t = constraintExprData_termGetTerm (e->data);
2543 expr = constraintTerm_getExprNode (t);
2545 llassert (constraintExpr_isDefined(e));
2546 llassert (exprNode_isDefined(expr));
2548 if (expr->kind == XPR_OP)
2550 data = expr->edata;
2552 t1 = exprData_getOpA (data);
2553 t2 = exprData_getOpB (data);
2554 tok = exprData_getOpTok (data);
2556 if (lltok_isMult (tok))
2559 ** If the sizeof is first, flip them.
2562 llassert (exprNode_isDefined(t1) && exprNode_isDefined(t2));
2564 if (t2->kind == XPR_SIZEOF || t2->kind == XPR_SIZEOFT)
2566 exprNode tmp = t1;
2567 t1 = t2;
2568 t2 = tmp;
2571 /*drl 3/2/2003 we know this from the fact that it's a
2572 multiplication operation...*/
2574 if (t1->kind == XPR_SIZEOF || t1->kind == XPR_SIZEOFT)
2576 ctype multype;
2578 if (t1->kind == XPR_SIZEOFT)
2580 multype = qtype_getType (exprData_getType (t1->edata));
2582 else
2584 exprNode tempE = exprData_getSingle (t1->edata);
2585 multype = exprNode_getType (tempE);
2588 DPRINTF (("Here we go sizeof: %s / %s / %s",
2589 ctype_unparse (multype), ctype_unparse (tfrom), ctype_unparse (tto)));
2590 llassert (ctype_isPointer (tfrom));
2592 if (ctype_almostEqual (ctype_makePointer (multype), tto))
2594 /* this is a bit sloopy but ... */
2595 constraintExpr_free (e);
2596 DPRINTF (("Sizeof types match okay!"));
2597 return constraintExpr_makeExprNode (t2);
2599 else
2601 int sizemul = ctype_getSize (multype);
2602 ctype tobase = ctype_baseArrayPtr (tto);
2603 int sizeto = ctype_getSize (tobase);
2605 DPRINTF (("Types: %s / %s / %s",
2606 ctype_unparse (tfrom), ctype_unparse (tto), ctype_unparse (multype)));
2608 voptgenerror (FLG_ALLOCMISMATCH,
2609 message ("Allocated memory is used as a different type (%s) from the sizeof type (%s)",
2610 ctype_unparse (tobase), ctype_unparse (multype)),
2611 loc);
2613 if (sizemul == sizeto)
2615 constraintExpr_free (e);
2616 DPRINTF (("Sizeof types match okay!"));
2617 return constraintExpr_makeExprNode (t2);
2619 else
2621 /* nothing was here */
2622 DPRINTF (("MISMATCHING TYPES!"));
2623 return (constraintExpr_div (constraintExpr_makeExprNode (t2), multype, tto, loc));
2627 else
2629 DPRINTF (("NOT A SIZEOF!"));
2630 /* empty */
2633 else
2635 DPRINTF (("Not a mult: %s", constraintExpr_unparse (e)));
2639 return (constraintExpr_div (e, tfrom, tto, loc));
2641 /*@noaccess exprNode@*/
2643 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2645 DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e)));
2646 DPRINTF (("Types: %s / %s",
2647 ctype_unparse (tfrom),
2648 ctype_unparse (tto)));
2650 llassert (constraintExpr_isDefined(e));
2652 switch (e->kind)
2654 case term:
2656 constraintTerm t = constraintExprData_termGetTerm (e->data);
2658 DPRINTF (("Term: %s", constraintTerm_unparse (t)));
2660 if (constraintTerm_isExprNode (t))
2662 return constraintTerm_simpleDivTypeExprNode (e, tfrom, tto, loc);
2664 /* search for * size of ct and remove */
2666 DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e), ctype_unparse (tfrom), ctype_unparse (tto)));
2667 return constraintExpr_div (e, tfrom, tto, loc);
2670 case binaryexpr:
2672 constraintExpr temp;
2674 temp = constraintExprData_binaryExprGetExpr1 (e->data);
2675 temp = constraintExpr_copy(temp);
2676 temp = simpleDivType (temp, tfrom, tto, loc);
2678 e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2680 temp = constraintExprData_binaryExprGetExpr2 (e->data);
2681 temp = constraintExpr_copy(temp);
2682 temp = simpleDivType (temp, tfrom, tto, loc);
2683 e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2685 DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e)));
2686 return e;
2688 case unaryExpr:
2690 return constraintExpr_div (e, tfrom, tto, loc);
2693 default:
2694 BADEXIT;
2698 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e, ctype tfrom,
2699 ctype tto, fileloc loc)
2701 DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e),
2702 ctype_unparse (tfrom), ctype_unparse (tto)));
2704 e = constraintExpr_makeIncConstraintExpr (e);
2705 e = constraintExpr_simplify (e);
2706 e = simpleDivType (e, tfrom, tto, loc);
2707 e = constraintExpr_makeDecConstraintExpr (e);
2708 e = constraintExpr_simplify (e);
2710 DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e)));
2711 return e;
2715 bool constraintExpr_isConstantOnly (constraintExpr e)
2717 DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e)));
2718 llassert (constraintExpr_isDefined(e));
2720 switch (e->kind)
2722 case term:
2724 constraintTerm t = constraintExprData_termGetTerm(e->data);
2726 if (constraintTerm_isConstantOnly (t))
2728 return TRUE;
2730 else
2732 return FALSE;
2736 case binaryexpr:
2738 constraintExpr temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2739 constraintExpr temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2741 if (constraintExpr_isConstantOnly(temp1) &&
2742 constraintExpr_isConstantOnly(temp2) )
2744 return TRUE;
2746 else
2748 return FALSE;
2752 case unaryExpr:
2754 constraintExpr temp;
2756 temp = constraintExprData_unaryExprGetExpr (e->data );
2758 if (constraintExpr_isConstantOnly(temp) )
2760 return TRUE;
2762 else
2764 return FALSE;
2767 default:
2768 BADEXIT;