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