00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 # include "lclintMacros.nf"
00033 # include "basic.h"
00034
00035 sRefSet
00036 sRefSet_new ()
00037 {
00038 return sRefSet_undefined;
00039 }
00040
00041 static sRefSet
00042 sRefSet_newEmpty (void)
00043 {
00044 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
00045
00046 s->entries = 0;
00047 s->nspace = sRefSetBASESIZE;
00048 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
00049
00050 return (s);
00051 }
00052
00053 sRefSet
00054 sRefSet_single ( sRef sr)
00055 {
00056 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
00057
00058 s->entries = 1;
00059 s->nspace = sRefSetBASESIZE - 1;
00060 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
00061 s->elements[0] = sr;
00062
00063 return (s);
00064 }
00065
00066 static void
00067 sRefSet_grow ( sRefSet s)
00068 {
00069 int i;
00070 sRef *newelements;
00071
00072 s->nspace = sRefSetBASESIZE;
00073 newelements = (sRef *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
00074
00075 for (i = 0; i < s->entries; i++)
00076 {
00077 newelements[i] = s->elements[i];
00078 }
00079
00080 sfree (s->elements);
00081 s->elements = newelements;
00082 }
00083
00084 sRefSet
00085 sRefSet_insert (sRefSet s, sRef el)
00086 {
00087 if (sRefSet_isUndefined (s))
00088 {
00089 s = sRefSet_newEmpty ();
00090 }
00091
00092
00093 if (!sRefSet_isSameMember (s, el))
00094 {
00095
00096 if (s->nspace <= 0)
00097 sRefSet_grow (s);
00098
00099 s->nspace--;
00100
00101 llassert (s->elements != NULL);
00102 s->elements[s->entries] = el;
00103
00104 s->entries++;
00105 }
00106 else
00107 {
00108 }
00109
00110 return s;
00111 }
00112
00113 void
00114 sRefSet_clear (sRefSet s)
00115 {
00116 if (sRefSet_isDefined (s))
00117 {
00118 s->nspace += s->entries;
00119 s->entries = 0;
00120 }
00121 }
00122
00123
00124
00125
00126
00127 void
00128 sRefSet_clearStatics (sRefSet s)
00129 {
00130 if (sRefSet_isDefined (s))
00131 {
00132 int i;
00133
00134 for (i = 0; i < s->entries; i++)
00135 {
00136 sRef current = s->elements[i];
00137
00138 if (sRef_isFileStatic (sRef_getRootBase (current)))
00139 {
00140 int j;
00141
00142 for (j = i; j < s->entries - 1; j++)
00143 {
00144 s->elements[j] = s->elements[j+1];
00145 }
00146
00147 s->entries--;
00148 s->nspace++;
00149 i--;
00150 }
00151 }
00152 }
00153 }
00154
00155 bool
00156 sRefSet_delete (sRefSet s, sRef el)
00157 {
00158 int i;
00159
00160 if (sRefSet_isUndefined (s)) return FALSE;
00161
00162 if (s->elements != NULL)
00163 {
00164 for (i = 0; i < s->entries; i++)
00165 {
00166 sRef current = s->elements[i];
00167
00168 if (sRef_realSame (el, current))
00169 {
00170 int j;
00171
00172 for (j = i; j < s->entries - 1; j++)
00173 {
00174 s->elements[j] = s->elements[j+1];
00175 }
00176
00177 s->entries--;
00178 s->nspace++;
00179 return TRUE;
00180 }
00181 }
00182 }
00183
00184 return FALSE;
00185 }
00186
00187 sRef
00188 sRefSet_choose (sRefSet s)
00189 {
00190 llassert (sRefSet_isDefined (s));
00191 llassert (s->entries > 0);
00192 llassert (s->elements != NULL);
00193
00194 return (s->elements[0]);
00195 }
00196
00197 sRef
00198 sRefSet_mergeIntoOne (sRefSet s)
00199 {
00200 sRef res;
00201 int i;
00202
00203 if (sRefSet_isUndefined (s)) return sRef_undefined;
00204 if (s->entries == 0) return sRef_undefined;
00205
00206 llassert (s->elements != NULL);
00207
00208 res = s->elements[0];
00209
00210 for (i = 1; i < s->entries; i++)
00211 {
00212 sRef tmp;
00213
00214 tmp = sRef_makeConj (res, s->elements[i]);
00215 res = tmp;
00216 }
00217
00218 return res;
00219 }
00220
00221
00222
00223
00224
00225 bool
00226 sRefSet_deleteBase (sRefSet s, sRef base)
00227 {
00228 int i = 0;
00229 int offset = 0;
00230
00231 if (sRefSet_isUndefined (s) || (s->elements == NULL))
00232 {
00233 return FALSE;
00234 } ;
00235
00236 while (i + offset < s->entries)
00237 {
00238 sRef current = s->elements[i + offset];
00239
00240 while (sRef_includedBy (current, base))
00241 {
00242 offset++;
00243 if (i + offset >= s->entries) goto doneLoop;
00244 current = s->elements [i + offset];
00245 }
00246
00247 if (offset > 0)
00248 {
00249 s->elements [i] = current;
00250 }
00251
00252 i++;
00253 }
00254
00255 doneLoop:
00256 s->entries -= offset;
00257 s->nspace += offset;
00258
00259 return (offset > 0);
00260 }
00261
00262
00263
00264
00265
00266 sRefSet
00267 sRefSet_unionFree ( sRefSet s1, sRefSet s2)
00268 {
00269 sRefSet res = sRefSet_union (s1, s2);
00270
00271 sRefSet_free (s2);
00272 return res;
00273 }
00274
00275 sRefSet
00276 sRefSet_union ( sRefSet s1, sRefSet s2)
00277 {
00278 if (s1 == s2)
00279 {
00280 return s1;
00281 }
00282
00283 if (sRefSet_isEmpty (s1))
00284 {
00285 s1 = sRefSet_copy (s1, s2);
00286 }
00287 else
00288 {
00289 sRefSet_allElements (s2, el)
00290 {
00291 s1 = sRefSet_insert (s1, el);
00292 } end_sRefSet_allElements;
00293 }
00294
00295 return s1;
00296 }
00297
00298
00299
00300
00301
00302 sRefSet
00303 sRefSet_unionExcept ( sRefSet s1, sRefSet s2, sRef ex)
00304 {
00305 if (s1 == s2) return s1;
00306
00307 sRefSet_allElements (s2, el)
00308 {
00309 if (sRef_same (el, ex))
00310 {
00311 }
00312 else
00313 {
00314 s1 = sRefSet_insert (s1, el);
00315 }
00316 } end_sRefSet_allElements;
00317
00318 return s1;
00319 }
00320
00321 sRefSet
00322 sRefSet_realNewUnion (sRefSet s1, sRefSet s2)
00323 {
00324 llassert (NOALIAS (s1, s2));
00325
00326 if (sRefSet_isUndefined (s1))
00327 {
00328 return (sRefSet_newCopy (s2));
00329 }
00330 else
00331 {
00332 sRefSet ret = sRefSet_newCopy (s1);
00333
00334 sRefSet_allElements (s2, el)
00335 {
00336 ret = sRefSet_insert (ret, el);
00337 } end_sRefSet_allElements;
00338
00339 return ret;
00340 }
00341 }
00342
00343
00344
00345 sRefSet
00346 sRefSet_intersect (sRefSet s1, sRefSet s2)
00347 {
00348 sRefSet s = sRefSet_new ();
00349
00350 llassert (NOALIAS (s1, s2));
00351
00352 sRefSet_allElements (s1, el)
00353 {
00354 if (sRefSet_member (s2, el))
00355 {
00356 s = sRefSet_insert (s, el);
00357 }
00358 } end_sRefSet_allElements;
00359
00360 return s;
00361 }
00362
00363 sRefSet
00364 sRefSet_levelUnion ( sRefSet sr, sRefSet s, int lexlevel)
00365 {
00366 llassert (NOALIAS (sr, s));
00367
00368 sRefSet_allElements (s, el)
00369 {
00370 if (sRef_lexLevel (el) <= lexlevel)
00371 {
00372 sr = sRefSet_insert (sr, el);
00373 }
00374 } end_sRefSet_allElements;
00375
00376 return sr;
00377 }
00378
00379 void
00380 sRefSet_levelPrune (sRefSet s, int lexlevel)
00381 {
00382 if (sRefSet_isDefined (s))
00383 {
00384 int i;
00385 int backcount = sRefSet_size (s) - 1;
00386
00387 for (i = 0; i <= backcount; i++)
00388 {
00389 sRef el = s->elements[i];
00390
00391 if (sRef_lexLevel (el) > lexlevel)
00392 {
00393 int j;
00394
00395
00396 for (j = backcount; j > i; j--)
00397 {
00398 backcount--;
00399 s->entries--;
00400 s->nspace++;
00401
00402 if (sRef_lexLevel (s->elements[j]) <= lexlevel)
00403 {
00404 s->elements[i] = s->elements[j];
00405
00406 if (backcount == i) s->entries++;
00407 break;
00408 }
00409 }
00410
00411 if (backcount == i)
00412 {
00413 s->entries--;
00414 }
00415 }
00416 }
00417 }
00418 }
00419
00420
00421
00422
00423
00424 sRefSet
00425 sRefSet_copy ( sRefSet s1, sRefSet s2)
00426 {
00427 int origentries;
00428
00429 llassert (NOALIAS (s1, s2));
00430
00431 if (sRefSet_isUndefined (s1))
00432 {
00433 if (sRefSet_isEmpty (s2))
00434 {
00435 return s1;
00436 }
00437 else
00438 {
00439 s1 = sRefSet_newEmpty ();
00440 }
00441 }
00442
00443 origentries = s1->entries;
00444
00445 s1->nspace = s1->entries + s1->nspace;
00446 s1->entries = 0;
00447
00448 sRefSet_allElements (s2, el)
00449 {
00450 if (s1->nspace == 0)
00451 {
00452 sRefSet_grow (s1);
00453 }
00454
00455 s1->elements[s1->entries] = el;
00456 s1->nspace--;
00457 s1->entries++;
00458 } end_sRefSet_allElements;
00459
00460 return s1;
00461 }
00462
00463 sRefSet
00464 sRefSet_newCopy ( sRefSet s)
00465 {
00466 if (sRefSet_isEmpty (s))
00467 {
00468 return sRefSet_undefined;
00469 }
00470 else
00471 {
00472 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
00473 int i;
00474
00475 r->entries = s->entries;
00476 r->nspace = s->nspace;
00477 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
00478
00479 for (i = 0; i < s->entries; i++)
00480 {
00481 r->elements[i] = s->elements[i];
00482 }
00483
00484 return r;
00485 }
00486 }
00487
00488 sRefSet
00489 sRefSet_levelCopy ( sRefSet s, int lexlevel)
00490 {
00491 if (sRefSet_isEmpty (s))
00492 {
00493 return sRefSet_undefined;
00494 }
00495 else
00496 {
00497 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
00498 int i;
00499
00500 r->nspace = s->entries;
00501 r->entries = 0;
00502 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries));
00503
00504 for (i = 0; i < s->entries; i++)
00505 {
00506 if (sRef_lexLevel (s->elements[i]) <= lexlevel)
00507 {
00508 r->elements[r->entries] = s->elements[i];
00509 r->entries++;
00510 r->nspace--;
00511 }
00512 }
00513
00514 return r;
00515 }
00516 }
00517
00518 sRefSet
00519 sRefSet_newDeepCopy (sRefSet s)
00520 {
00521 if (sRefSet_isUndefined (s))
00522 {
00523 return sRefSet_newEmpty ();
00524 }
00525 else
00526 {
00527 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
00528 int i;
00529
00530 r->entries = s->entries;
00531 r->nspace = s->nspace;
00532 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
00533
00534 for (i = 0; i < s->entries; i++)
00535 {
00536 r->elements[i] = sRef_copy (s->elements[i]);
00537 }
00538
00539 return r;
00540 }
00541 }
00542
00543 static bool
00544 sRefSet_isElementCompare (bool (*test)(sRef, sRef), sRefSet s, sRef el)
00545 {
00546 sRefSet_allElements (s, e)
00547 {
00548 if ((test)(el, e))
00549 {
00550 return TRUE;
00551 }
00552 } end_sRefSet_allElements;
00553
00554 return FALSE;
00555 }
00556
00557 static bool
00558 sRefSet_isElementTest (bool (*test)(sRef), sRefSet s)
00559 {
00560 sRefSet_allElements (s, e)
00561 {
00562 if ((test)(e))
00563 {
00564 return TRUE;
00565 }
00566 } end_sRefSet_allElements;
00567
00568 return FALSE;
00569 }
00570
00571 bool
00572 sRefSet_hasRealElement (sRefSet s)
00573 {
00574 sRefSet_allElements (s, e)
00575 {
00576 if (sRef_isMeaningful (e) && !sRef_isUnconstrained (e))
00577 {
00578 return TRUE;
00579 }
00580 } end_sRefSet_allElements;
00581
00582 return FALSE;
00583 }
00584
00585 bool
00586 sRefSet_isSameMember (sRefSet s, sRef el)
00587 {
00588 return (sRefSet_isElementCompare (sRef_realSame, s, el));
00589 }
00590
00591 bool
00592 sRefSet_isSameNameMember (sRefSet s, sRef el)
00593 {
00594 return (sRefSet_isElementCompare (sRef_sameName, s, el));
00595 }
00596
00597 bool
00598 sRefSet_member (sRefSet s, sRef el)
00599 {
00600 return (sRefSet_isElementCompare (sRef_similar, s, el));
00601 }
00602
00603 bool
00604 sRefSet_hasStatic (sRefSet s)
00605 {
00606 return (sRefSet_isElementTest (sRef_isFileStatic, s));
00607 }
00608
00609 bool
00610 sRefSet_hasUnconstrained (sRefSet s)
00611 {
00612 return (sRefSet_isElementTest (sRef_isUnconstrained, s));
00613 }
00614
00615 cstring
00616 sRefSet_unparseUnconstrained (sRefSet s)
00617 {
00618 int num = 0;
00619 cstring res = cstring_undefined;
00620
00621 sRefSet_allElements (s, el)
00622 {
00623 if (sRef_isUnconstrained (el))
00624 {
00625 if (cstring_isUndefined (res))
00626 {
00627 res = cstring_copy (sRef_unconstrainedName (el));
00628 }
00629 else
00630 {
00631 res = message ("%q, %s", res, sRef_unconstrainedName (el));
00632 }
00633
00634 num++;
00635 }
00636 } end_sRefSet_allElements ;
00637
00638 if (num == 0)
00639 {
00640 llassert (cstring_isUndefined (res));
00641 return (cstring_makeLiteral ("<ERROR: no unconstrained calls>"));
00642 }
00643 else if (num == 1)
00644 {
00645 return (message ("unconstrained function %q", res));
00646 }
00647 else
00648 {
00649 return (message ("unconstrained functions %q", res));
00650 }
00651 }
00652
00653 cstring
00654 sRefSet_unparseUnconstrainedPlain (sRefSet s)
00655 {
00656 cstring res = cstring_undefined;
00657
00658 sRefSet_allElements (s, el)
00659 {
00660 if (sRef_isUnconstrained (el))
00661 {
00662 if (cstring_isUndefined (res))
00663 {
00664 res = cstring_copy (sRef_unconstrainedName (el));
00665 }
00666 else
00667 {
00668 res = message ("%q, %s", res, sRef_unconstrainedName (el));
00669 }
00670 }
00671 } end_sRefSet_allElements ;
00672
00673 return res;
00674 }
00675
00676 bool
00677 sRefSet_modifyMember (sRefSet s, sRef m)
00678 {
00679 bool ret = FALSE;
00680
00681 sRefSet_allElements (s, e)
00682 {
00683 if (sRef_similar (m, e))
00684 {
00685 sRef_setModified (e);
00686 ret = TRUE;
00687 }
00688 } end_sRefSet_allElements;
00689
00690
00691 return ret;
00692 }
00693
00694 sRef
00695 sRefSet_lookupMember (sRefSet s, sRef el)
00696 {
00697 sRefSet_allElements (s, e)
00698 {
00699 if (sRef_similar (el, e))
00700 {
00701 return e;
00702 }
00703 } end_sRefSet_allElements;
00704
00705 return sRef_undefined;
00706 }
00707
00708 int sRefSet_size (sRefSet s)
00709 {
00710 if (sRefSet_isUndefined (s)) return 0;
00711 return s->entries;
00712 }
00713
00714 cstring
00715 sRefSet_unparse (sRefSet s)
00716 {
00717 int i;
00718 cstring st = cstring_makeLiteral ("{");
00719
00720 if (sRefSet_isDefined (s))
00721 {
00722 for (i = 0; i < sRefSet_size (s); i++)
00723 {
00724 if (i == 0)
00725 st = message ("%q %q", st, sRef_unparse (s->elements[i]));
00726 else
00727 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
00728 }
00729 }
00730
00731 st = message ("%q }", st);
00732 return st;
00733 }
00734
00735 cstring sRefSet_unparsePlain (sRefSet s)
00736 {
00737 int i;
00738 cstring st = cstring_undefined;
00739
00740 if (sRefSet_isDefined (s))
00741 {
00742 for (i = 0; i < sRefSet_size (s); i++)
00743 {
00744 if (i == 0)
00745 st = sRef_unparse (s->elements[i]);
00746 else
00747 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
00748 }
00749 }
00750
00751 return st;
00752 }
00753
00754 cstring
00755 sRefSet_unparseDebug (sRefSet s)
00756 {
00757 int i;
00758 cstring st = cstring_makeLiteral ("{");
00759
00760 if (sRefSet_isDefined (s))
00761 {
00762 for (i = 0; i < sRefSet_size (s); i++)
00763 {
00764 if (i == 0)
00765 {
00766 st = message ("%q %q", st, sRef_unparseDebug (s->elements[i]));
00767 }
00768 else
00769 {
00770 st = message ("%q, %q", st, sRef_unparseDebug (s->elements[i]));
00771 }
00772 }
00773 }
00774
00775 st = message ("%q }", st);
00776 return st;
00777 }
00778
00779 void
00780 sRefSet_fixSrefs (sRefSet s)
00781 {
00782 if (sRefSet_isDefined (s))
00783 {
00784 int i;
00785
00786 for (i = 0; i < sRefSet_size (s); i++)
00787 {
00788 sRef current = s->elements[i];
00789
00790 if (sRef_isLocalVar (current))
00791 {
00792 s->elements[i] = uentry_getSref (sRef_getUentry (current));
00793 }
00794 }
00795 }
00796 }
00797
00798 void
00799 sRefSet_free ( sRefSet s)
00800 {
00801 if (!sRefSet_isUndefined (s))
00802 {
00803 llassertprint (s->entries < 1000, ("sRefSet free size: %d", s->entries));
00804
00805 sfree (s->elements);
00806 sfree (s);
00807 }
00808 }
00809
00810 sRefSet sRefSet_removeIndirection (sRefSet s)
00811 {
00812
00813
00814
00815
00816 sRefSet t = sRefSet_new ();
00817
00818
00819 sRefSet_allElements (s, el)
00820 {
00821 if (!sRef_isAddress (el))
00822 {
00823 t = sRefSet_insert (t, sRef_makeAddress (el));
00824 }
00825 } end_sRefSet_allElements;
00826
00827 return t;
00828 }
00829
00830 sRefSet sRefSet_addIndirection (sRefSet s)
00831 {
00832
00833
00834
00835
00836 sRefSet t = sRefSet_new ();
00837
00838
00839 sRefSet_allElements (s, el)
00840 {
00841 ctype ct = ctype_realType (sRef_getType (el));
00842
00843
00844 if ((ctype_isArrayPtr (ct)))
00845 {
00846
00847 sRef a = sRef_constructPointer (el);
00848
00849 t = sRefSet_insert (t, a);
00850 }
00851 } end_sRefSet_allElements;
00852
00853 return t;
00854 }
00855
00856 sRefSet sRefSet_accessField (sRefSet s, cstring f)
00857 {
00858
00859
00860
00861
00862 sRefSet t = sRefSet_new ();
00863
00864
00865 sRefSet_allElements (s, el)
00866 {
00867 ctype ct = ctype_realType (sRef_getType (el));
00868
00869 if ((ctype_isStruct (ct) || ctype_isUnion (ct))
00870 && (!uentry_isUndefined (uentryList_lookupField (ctype_getFields (ct), f))))
00871 {
00872 t = sRefSet_insert (t, sRef_makeNCField (el, f));
00873 }
00874 } end_sRefSet_allElements;
00875
00876 return t;
00877 }
00878
00879 sRefSet sRefSet_fetchUnknown (sRefSet s)
00880 {
00881 sRefSet t = sRefSet_new ();
00882
00883 sRefSet_allElements (s, el)
00884 {
00885 ctype ct = ctype_realType (sRef_getType (el));
00886
00887 if (ctype_isArrayPtr (ct))
00888 {
00889 t = sRefSet_insert (t, sRef_makeArrayFetch (el));
00890 }
00891 } end_sRefSet_allElements;
00892
00893 return t;
00894 }
00895
00896 sRefSet sRefSet_fetchKnown (sRefSet s, int i)
00897 {
00898 sRefSet t = sRefSet_new ();
00899
00900 sRefSet_allElements (s, el)
00901 {
00902 ctype ct = ctype_realType (sRef_getType (el));
00903
00904 if (ctype_isArrayPtr (ct))
00905 {
00906 t = sRefSet_insert (t, sRef_makeArrayFetchKnown (el, i));
00907 }
00908 } end_sRefSet_allElements;
00909
00910 return t;
00911 }
00912
00913 int sRefSet_compare (sRefSet s1, sRefSet s2)
00914 {
00915 sRefSet_allElements (s1, el)
00916 {
00917 if (!sRefSet_isSameMember (s2, el))
00918 {
00919 return -1;
00920 }
00921 } end_sRefSet_allElements;
00922
00923 sRefSet_allElements (s2, el)
00924 {
00925 if (!sRefSet_isSameMember (s1, el))
00926 {
00927 return 1;
00928 }
00929 } end_sRefSet_allElements;
00930
00931 return 0;
00932 }
00933
00934 bool sRefSet_equal (sRefSet s1, sRefSet s2)
00935 {
00936 sRefSet_allElements (s1, el)
00937 {
00938 if (!sRefSet_isSameMember (s2, el))
00939 {
00940 return FALSE;
00941 }
00942 } end_sRefSet_allElements;
00943
00944 sRefSet_allElements (s2, el)
00945 {
00946 if (!sRefSet_isSameMember (s1, el))
00947 {
00948 return FALSE;
00949 }
00950 } end_sRefSet_allElements;
00951
00952 return TRUE;
00953 }
00954
00955 sRefSet
00956 sRefSet_undump (char **s)
00957 {
00958 char c;
00959 sRefSet sl = sRefSet_new ();
00960
00961 while ((c = **s) != '#' && c != '@' && c != '$' && c != '&')
00962 {
00963 sl = sRefSet_insert (sl, sRef_undump (s));
00964
00965
00966 if (**s == ',')
00967 {
00968 (*s)++;
00969 }
00970 }
00971
00972 return sl;
00973 }
00974
00975 cstring
00976 sRefSet_dump (sRefSet sl)
00977 {
00978 cstring st = cstring_undefined;
00979 bool first = TRUE;
00980
00981
00982 sRefSet_allElements (sl, el)
00983 {
00984 if (!first)
00985 {
00986 st = cstring_appendChar (st, ',');
00987 }
00988 else
00989 {
00990 first = FALSE;
00991 }
00992
00993 st = cstring_concatFree (st, sRef_dump (el));
00994 } end_sRefSet_allElements;
00995
00996 return st;
00997 }
00998