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.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** sRefSet.c
26 **
27 ** based on set_template.c
28 **
29 ** where T has T_equal (or change this) and T_unparse
30 */
31
32 # include "splintMacros.nf"
33 # include "basic.h"
34
35 sRefSet
sRefSet_new()36 sRefSet_new ()
37 {
38 return sRefSet_undefined;
39 }
40
41 static /*@notnull@*/ /*@only@*/ sRefSet
sRefSet_newEmpty(void)42 sRefSet_newEmpty (void)
43 {
44 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
45
46 s->entries = 0;
47 s->nspace = sRefSetBASESIZE;
48 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
49
50 return (s);
51 }
52
53 /*@only@*/ sRefSet
sRefSet_single(sRef sr)54 sRefSet_single (/*@exposed@*/ sRef sr)
55 {
56 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
57
58 s->entries = 1;
59 s->nspace = sRefSetBASESIZE - 1;
60 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
61 s->elements[0] = sr;
62
63 return (s);
64 }
65
66 static void
sRefSet_grow(sRefSet s)67 sRefSet_grow (/*@notnull@*/ sRefSet s)
68 {
69 int i;
70 sRef *newelements;
71
72 s->nspace = sRefSetBASESIZE;
73 newelements = (sRef *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
74
75 for (i = 0; i < s->entries; i++)
76 {
77 newelements[i] = s->elements[i];
78 }
79
80 sfree (s->elements);
81 s->elements = newelements;
82 }
83
84 sRefSet
sRefSet_insert(sRefSet s,sRef el)85 sRefSet_insert (sRefSet s, /*@exposed@*/ sRef el)
86 {
87 if (sRefSet_isUndefined (s))
88 {
89 s = sRefSet_newEmpty ();
90 }
91
92
93 if (!sRefSet_isSameMember (s, el))
94 {
95
96 if (s->nspace <= 0)
97 sRefSet_grow (s);
98
99 s->nspace--;
100
101 llassert (s->elements != NULL);
102 s->elements[s->entries] = el;
103 s->entries++;
104 }
105 else
106 {
107 ;
108 }
109
110 return s;
111 }
112
113 void
sRefSet_clear(sRefSet s)114 sRefSet_clear (sRefSet s)
115 {
116 if (sRefSet_isDefined (s))
117 {
118 s->nspace += s->entries;
119 s->entries = 0;
120 }
121 }
122
123 /*
124 ** slow algorithm...but it doesn't matter
125 */
126
127 void
sRefSet_clearStatics(sRefSet s)128 sRefSet_clearStatics (sRefSet s)
129 {
130 if (sRefSet_isDefined (s))
131 {
132 int i;
133
134 for (i = 0; i < s->entries; i++)
135 {
136 sRef current = s->elements[i];
137
138 if (sRef_isFileStatic (sRef_getRootBase (current)))
139 {
140 int j;
141
142 for (j = i; j < s->entries - 1; j++)
143 {
144 s->elements[j] = s->elements[j+1];
145 }
146
147 s->entries--;
148 s->nspace++;
149 i--;
150 }
151 }
152 }
153 }
154
155 bool
sRefSet_delete(sRefSet s,sRef el)156 sRefSet_delete (sRefSet s, sRef el)
157 {
158 int i;
159
160 if (sRefSet_isUndefined (s)) return FALSE;
161
162 if (s->elements != NULL)
163 {
164 for (i = 0; i < s->entries; i++)
165 {
166 sRef current = s->elements[i];
167
168 if (sRef_realSame (el, current))
169 {
170 int j;
171
172 for (j = i; j < s->entries - 1; j++)
173 {
174 s->elements[j] = s->elements[j+1];
175 }
176
177 s->entries--;
178 s->nspace++;
179 return TRUE;
180 }
181 }
182 }
183
184 return FALSE;
185 }
186
187 /*@exposed@*/ sRef
sRefSet_choose(sRefSet s)188 sRefSet_choose (sRefSet s)
189 {
190 llassert (sRefSet_isDefined (s));
191 llassert (s->entries > 0);
192 llassert (s->elements != NULL);
193
194 return (s->elements[0]);
195 }
196
197 /*@exposed@*/ sRef
sRefSet_mergeIntoOne(sRefSet s)198 sRefSet_mergeIntoOne (sRefSet s)
199 {
200 sRef res;
201 int i;
202
203 if (sRefSet_isUndefined (s)) return sRef_undefined;
204 if (s->entries == 0) return sRef_undefined;
205
206 llassert (s->elements != NULL);
207
208 res = s->elements[0];
209
210 for (i = 1; i < s->entries; i++)
211 {
212 sRef tmp;
213
214 tmp = sRef_makeConj (res, s->elements[i]);
215 res = tmp;
216 }
217
218 return res;
219 }
220
221 /*
222 ** this is really yucky...but it works...
223 */
224
225 bool
sRefSet_deleteBase(sRefSet s,sRef base)226 sRefSet_deleteBase (sRefSet s, sRef base)
227 {
228 int i = 0;
229 int offset = 0;
230
231 if (sRefSet_isUndefined (s) || (s->elements == NULL))
232 {
233 return FALSE;
234 } ;
235
236 while (i + offset < s->entries)
237 {
238 sRef current = s->elements[i + offset];
239
240 while (sRef_includedBy (current, base))
241 {
242 offset++;
243 if (i + offset >= s->entries) goto doneLoop;
244 current = s->elements [i + offset];
245 }
246
247 if (offset > 0)
248 {
249 s->elements [i] = current;
250 }
251
252 i++;
253 }
254
255 doneLoop:
256 s->entries -= offset;
257 s->nspace += offset;
258
259 return (offset > 0);
260 }
261
262 /*
263 ** modifies *s1
264 */
265
266 sRefSet
sRefSet_unionFree(sRefSet s1,sRefSet s2)267 sRefSet_unionFree (/*@returned@*/ sRefSet s1, sRefSet s2)
268 {
269 sRefSet res = sRefSet_union (s1, s2);
270
271 sRefSet_free (s2);
272 return res;
273 }
274
275 sRefSet
sRefSet_union(sRefSet s1,sRefSet s2)276 sRefSet_union (/*@returned@*/ sRefSet s1, sRefSet s2)
277 {
278 if (s1 == s2)
279 {
280 return s1;
281 }
282
283 if (sRefSet_isEmpty (s1))
284 {
285 s1 = sRefSet_copyInto (s1, s2);
286 }
287 else
288 {
289 sRefSet_allElements (s2, el)
290 {
291 s1 = sRefSet_insert (s1, el);
292 } end_sRefSet_allElements;
293 }
294
295 return s1;
296 }
297
298 /*
299 ** s1 <- s1 U (s2 - ex - params)
300 */
301
302 sRefSet
sRefSet_unionExcept(sRefSet s1,sRefSet s2,sRef ex)303 sRefSet_unionExcept (/*@returned@*/ sRefSet s1, sRefSet s2, sRef ex)
304 {
305 if (s1 == s2) return s1;
306
307 sRefSet_allElements (s2, el)
308 {
309 if (sRef_same (el, ex))
310 {
311 ;
312 }
313 else
314 {
315 s1 = sRefSet_insert (s1, el);
316 }
317 } end_sRefSet_allElements;
318
319 return s1;
320 }
321
322 /*@only@*/ sRefSet
sRefSet_realNewUnion(sRefSet s1,sRefSet s2)323 sRefSet_realNewUnion (sRefSet s1, sRefSet s2)
324 {
325 llassert (NOALIAS (s1, s2));
326
327 if (sRefSet_isUndefined (s1))
328 {
329 return (sRefSet_newCopy (s2));
330 }
331 else
332 {
333 sRefSet ret = sRefSet_newCopy (s1);
334
335 sRefSet_allElements (s2, el)
336 {
337 ret = sRefSet_insert (ret, el);
338 } end_sRefSet_allElements;
339
340 return ret;
341 }
342 }
343
344 /* slow! */
345
346 /*@only@*/ sRefSet
sRefSet_intersect(sRefSet s1,sRefSet s2)347 sRefSet_intersect (sRefSet s1, sRefSet s2)
348 {
349 sRefSet s = sRefSet_new ();
350
351 llassert (NOALIAS (s1, s2));
352
353 sRefSet_allElements (s1, el)
354 {
355 if (sRefSet_member (s2, el))
356 {
357 s = sRefSet_insert (s, el);
358 }
359 } end_sRefSet_allElements;
360
361 return s;
362 }
363
364 sRefSet
sRefSet_levelUnion(sRefSet sr,sRefSet s,int lexlevel)365 sRefSet_levelUnion (/*@returned@*/ sRefSet sr, sRefSet s, int lexlevel)
366 {
367 llassert (NOALIAS (sr, s));
368
369 sRefSet_allElements (s, el)
370 {
371 if (sRef_lexLevel (el) <= lexlevel)
372 {
373 sr = sRefSet_insert (sr, el);
374 }
375 } end_sRefSet_allElements;
376
377 return sr;
378 }
379
380 void
sRefSet_levelPrune(sRefSet s,int lexlevel)381 sRefSet_levelPrune (sRefSet s, int lexlevel)
382 {
383 if (sRefSet_isDefined (s))
384 {
385 int i;
386 int backcount = sRefSet_size (s) - 1;
387
388 for (i = 0; i <= backcount; i++)
389 {
390 sRef el = s->elements[i];
391
392 if (sRef_lexLevel (el) > lexlevel)
393 {
394 int j;
395
396
397 for (j = backcount; j > i; j--)
398 {
399 backcount--;
400 s->entries--;
401 s->nspace++;
402
403 if (sRef_lexLevel (s->elements[j]) <= lexlevel)
404 {
405 s->elements[i] = s->elements[j];
406
407 if (backcount == i) s->entries++;
408 /*@innerbreak@*/ break;
409 }
410 }
411
412 if (backcount == i)
413 {
414 s->entries--;
415 }
416 }
417 }
418 }
419 }
420
421 /*
422 ** s1 <- s2
423 */
424
sRefSet_copyInto(sRefSet s1,sRefSet s2)425 sRefSet sRefSet_copyInto (/*@returned@*/ sRefSet s1, /*@exposed@*/ sRefSet s2)
426 {
427 int origentries;
428
429 llassert (NOALIAS (s1, s2));
430
431 if (sRefSet_isUndefined (s1))
432 {
433 if (sRefSet_isEmpty (s2))
434 {
435 return s1;
436 }
437 else
438 {
439 s1 = sRefSet_newEmpty ();
440 }
441 }
442
443 origentries = s1->entries;
444
445 s1->nspace = s1->entries + s1->nspace;
446 s1->entries = 0;
447
448 sRefSet_allElements (s2, el)
449 {
450 if (s1->nspace == 0)
451 {
452 sRefSet_grow (s1);
453 }
454
455 s1->elements[s1->entries] = el;
456 s1->nspace--;
457 s1->entries++;
458 } end_sRefSet_allElements;
459
460 return s1;
461 }
462
463 /*@only@*/ sRefSet
sRefSet_newCopy(sRefSet s)464 sRefSet_newCopy (/*@exposed@*/ sRefSet s)
465 {
466 if (sRefSet_isEmpty (s))
467 {
468 return sRefSet_undefined;
469 }
470 else
471 {
472 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
473 int i;
474
475 r->entries = s->entries;
476 r->nspace = s->nspace;
477 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
478
479 for (i = 0; i < s->entries; i++)
480 {
481 r->elements[i] = s->elements[i];
482 }
483
484 return r;
485 }
486 }
487
488 /*@only@*/ sRefSet
sRefSet_levelCopy(sRefSet s,int lexlevel)489 sRefSet_levelCopy (/*@exposed@*/ sRefSet s, int lexlevel)
490 {
491 if (sRefSet_isEmpty (s))
492 {
493 return sRefSet_undefined;
494 }
495 else
496 {
497 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
498 int i;
499
500 r->nspace = s->entries;
501 r->entries = 0;
502 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries));
503
504 for (i = 0; i < s->entries; i++)
505 {
506 if (sRef_lexLevel (s->elements[i]) <= lexlevel)
507 {
508 r->elements[r->entries] = s->elements[i];
509 r->entries++;
510 r->nspace--;
511 }
512 }
513
514 return r;
515 }
516 }
517
518 /*@only@*/ sRefSet
sRefSet_newDeepCopy(sRefSet s)519 sRefSet_newDeepCopy (sRefSet s)
520 {
521 if (sRefSet_isUndefined (s))
522 {
523 return sRefSet_newEmpty ();
524 }
525 else
526 {
527 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
528 int i;
529
530 r->entries = s->entries;
531 r->nspace = s->nspace;
532 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
533
534 for (i = 0; i < s->entries; i++)
535 {
536 r->elements[i] = sRef_copy (s->elements[i]);
537 }
538
539 return r;
540 }
541 }
542
543 static bool
sRefSet_isElementCompare(bool (* test)(sRef,sRef),sRefSet s,sRef el)544 sRefSet_isElementCompare (bool (*test)(sRef, sRef), sRefSet s, sRef el)
545 {
546 sRefSet_allElements (s, e)
547 {
548 if ((test)(el, e))
549 {
550 return TRUE;
551 }
552 } end_sRefSet_allElements;
553
554 return FALSE;
555 }
556
557 static bool
sRefSet_isElementTest(bool (* test)(sRef),sRefSet s)558 sRefSet_isElementTest (bool (*test)(sRef), sRefSet s)
559 {
560 sRefSet_allElements (s, e)
561 {
562 if ((test)(e))
563 {
564 return TRUE;
565 }
566 } end_sRefSet_allElements;
567
568 return FALSE;
569 }
570
571 bool
sRefSet_hasRealElement(sRefSet s)572 sRefSet_hasRealElement (sRefSet s)
573 {
574 sRefSet_allElements (s, e)
575 {
576 if (sRef_isMeaningful (e) && !sRef_isUnconstrained (e))
577 {
578 return TRUE;
579 }
580 } end_sRefSet_allElements;
581
582 return FALSE;
583 }
584
585 bool
sRefSet_containsSameObject(sRefSet s,sRef el)586 sRefSet_containsSameObject (sRefSet s, sRef el)
587 {
588 return (sRefSet_isElementCompare (sRef_sameObject, s, el));
589 }
590
591 bool
sRefSet_isSameMember(sRefSet s,sRef el)592 sRefSet_isSameMember (sRefSet s, sRef el)
593 {
594 return (sRefSet_isElementCompare (sRef_realSame, s, el));
595 }
596
597 bool
sRefSet_isSameNameMember(sRefSet s,sRef el)598 sRefSet_isSameNameMember (sRefSet s, sRef el)
599 {
600 return (sRefSet_isElementCompare (sRef_sameName, s, el));
601 }
602
603 bool
sRefSet_member(sRefSet s,sRef el)604 sRefSet_member (sRefSet s, sRef el)
605 {
606 return (sRefSet_isElementCompare (sRef_similar, s, el));
607 }
608
609 bool
sRefSet_hasStatic(sRefSet s)610 sRefSet_hasStatic (sRefSet s)
611 {
612 return (sRefSet_isElementTest (sRef_isFileStatic, s));
613 }
614
615 bool
sRefSet_hasUnconstrained(sRefSet s)616 sRefSet_hasUnconstrained (sRefSet s)
617 {
618 return (sRefSet_isElementTest (sRef_isUnconstrained, s));
619 }
620
621 cstring
sRefSet_unparseUnconstrained(sRefSet s)622 sRefSet_unparseUnconstrained (sRefSet s)
623 {
624 int num = 0;
625 cstring res = cstring_undefined;
626
627 sRefSet_allElements (s, el)
628 {
629 if (sRef_isUnconstrained (el))
630 {
631 if (cstring_isUndefined (res))
632 {
633 res = cstring_copy (sRef_unconstrainedName (el));
634 }
635 else
636 {
637 res = message ("%q, %s", res, sRef_unconstrainedName (el));
638 }
639
640 num++;
641 }
642 } end_sRefSet_allElements ;
643
644 if (num == 0)
645 {
646 llassert (cstring_isUndefined (res));
647 return (cstring_makeLiteral ("<ERROR: no unconstrained calls>"));
648 }
649 else if (num == 1)
650 {
651 return (message ("unconstrained function %q", res));
652 }
653 else
654 {
655 return (message ("unconstrained functions %q", res));
656 }
657 }
658
659 cstring
sRefSet_unparseUnconstrainedPlain(sRefSet s)660 sRefSet_unparseUnconstrainedPlain (sRefSet s)
661 {
662 cstring res = cstring_undefined;
663
664 sRefSet_allElements (s, el)
665 {
666 if (sRef_isUnconstrained (el))
667 {
668 if (cstring_isUndefined (res))
669 {
670 res = cstring_copy (sRef_unconstrainedName (el));
671 }
672 else
673 {
674 res = message ("%q, %s", res, sRef_unconstrainedName (el));
675 }
676 }
677 } end_sRefSet_allElements ;
678
679 return res;
680 }
681
682 bool
sRefSet_modifyMember(sRefSet s,sRef m)683 sRefSet_modifyMember (sRefSet s, sRef m)
684 {
685 bool ret = FALSE;
686
687 sRefSet_allElements (s, e)
688 {
689 if (sRef_similar (m, e))
690 {
691 sRef_setModified (e);
692 ret = TRUE;
693 }
694 } end_sRefSet_allElements;
695
696
697 return ret;
698 }
699
700 /*@exposed@*/ sRef
sRefSet_lookupMember(sRefSet s,sRef el)701 sRefSet_lookupMember (sRefSet s, sRef el)
702 {
703 sRefSet_allElements (s, e)
704 {
705 if (sRef_similar (el, e))
706 {
707 return e;
708 }
709 } end_sRefSet_allElements;
710
711 return sRef_undefined;
712 }
713
sRefSet_size(sRefSet s)714 int sRefSet_size (sRefSet s)
715 {
716 if (sRefSet_isUndefined (s)) return 0;
717 return s->entries;
718 }
719
720 /*@only@*/ cstring
sRefSet_unparse(sRefSet s)721 sRefSet_unparse (sRefSet s)
722 {
723 int i;
724 cstring st = cstring_makeLiteral ("{");
725
726 if (sRefSet_isDefined (s))
727 {
728 for (i = 0; i < sRefSet_size (s); i++)
729 {
730 if (i == 0)
731 st = message ("%q %q", st, sRef_unparse (s->elements[i]));
732 else
733 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
734 }
735 }
736
737 st = message ("%q }", st);
738 return st;
739 }
740
sRefSet_unparsePlain(sRefSet s)741 cstring sRefSet_unparsePlain (sRefSet s)
742 {
743 int i;
744 cstring st = cstring_undefined;
745
746 if (sRefSet_isDefined (s))
747 {
748 for (i = 0; i < sRefSet_size (s); i++)
749 {
750 if (i == 0)
751 st = sRef_unparse (s->elements[i]);
752 else
753 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
754 }
755 }
756
757 return st;
758 }
759
760 cstring
sRefSet_unparseDebug(sRefSet s)761 sRefSet_unparseDebug (sRefSet s)
762 {
763 int i;
764 cstring st = cstring_makeLiteral ("{");
765
766 if (sRefSet_isDefined (s))
767 {
768 for (i = 0; i < sRefSet_size (s); i++)
769 {
770 if (i == 0)
771 {
772 st = message ("%q %q", st, sRef_unparseDebug (s->elements[i]));
773 }
774 else
775 {
776 st = message ("%q, %q", st, sRef_unparseDebug (s->elements[i]));
777 }
778 }
779 }
780
781 st = message ("%q }", st);
782 return st;
783 }
784
785 cstring
sRefSet_unparseFull(sRefSet s)786 sRefSet_unparseFull (sRefSet s)
787 {
788 int i;
789 cstring st = cstring_makeLiteral ("{");
790
791 if (sRefSet_isDefined (s))
792 {
793 for (i = 0; i < sRefSet_size (s); i++)
794 {
795 if (i == 0)
796 {
797 st = message ("%q %q", st, sRef_unparseFull (s->elements[i]));
798 }
799 else
800 {
801 st = message ("%q, %q", st, sRef_unparseFull (s->elements[i]));
802 }
803 }
804 }
805
806 st = message ("%q }", st);
807 return st;
808 }
809
810 void
sRefSet_fixSrefs(sRefSet s)811 sRefSet_fixSrefs (sRefSet s)
812 {
813 if (sRefSet_isDefined (s))
814 {
815 int i;
816
817 for (i = 0; i < sRefSet_size (s); i++)
818 {
819 sRef current = s->elements[i];
820
821 if (sRef_isLocalVar (current))
822 {
823 s->elements[i] = uentry_getSref (sRef_getUentry (current));
824 }
825 }
826 }
827 }
828
829 void
sRefSet_free(sRefSet s)830 sRefSet_free (/*@only@*/ sRefSet s)
831 {
832 if (!sRefSet_isUndefined (s))
833 {
834 /* evans 2003-10-20: increase size sanity limit from 1000 */
835 llassertprint (s->entries < 99999, ("sRefSet free size: %d", s->entries));
836
837 sfree (s->elements);
838 sfree (s);
839 }
840 }
841
sRefSet_removeIndirection(sRefSet s)842 sRefSet sRefSet_removeIndirection (sRefSet s)
843 {
844 /*
845 ** returns a NEW sRefSet containing references to all sRef's in s
846 */
847
848 sRefSet t = sRefSet_new ();
849
850
851 sRefSet_allElements (s, el)
852 {
853 if (!sRef_isAddress (el))
854 {
855 t = sRefSet_insert (t, sRef_makeAddress (el));
856 }
857 } end_sRefSet_allElements;
858
859 return t;
860 }
861
sRefSet_addIndirection(sRefSet s)862 sRefSet sRefSet_addIndirection (sRefSet s)
863 {
864 /*
865 ** returns a NEW sRefSet containing references to all sRef's in s
866 */
867
868 sRefSet t = sRefSet_new ();
869
870
871 sRefSet_allElements (s, el)
872 {
873 ctype ct = ctype_realType (sRef_getType (el));
874
875
876 if ((ctype_isArrayPtr (ct)))
877 {
878
879 sRef a = sRef_constructPointer (el);
880 t = sRefSet_insert (t, a);
881 }
882 } end_sRefSet_allElements;
883
884 return t;
885 }
886
sRefSet_accessField(sRefSet s,cstring f)887 sRefSet sRefSet_accessField (sRefSet s, /*@observer@*/ cstring f)
888 {
889 /*
890 ** returns a NEW sRefSet containing references to all sRef's in s
891 */
892
893 sRefSet t = sRefSet_new ();
894
895 sRefSet_allElements (s, el)
896 {
897 ctype ct = ctype_realType (sRef_getType (el));
898
899 if ((ctype_isStruct (ct) || ctype_isUnion (ct))
900 && (!uentry_isUndefined (uentryList_lookupField (ctype_getFields (ct), f))))
901 {
902 t = sRefSet_insert (t, sRef_makeNCField (el, f));
903 }
904 } end_sRefSet_allElements;
905
906 return t;
907 }
908
sRefSet_fetchUnknown(sRefSet s)909 sRefSet sRefSet_fetchUnknown (sRefSet s)
910 {
911 sRefSet t = sRefSet_new ();
912
913 sRefSet_allElements (s, el)
914 {
915 ctype ct = ctype_realType (sRef_getType (el));
916
917 if (ctype_isArrayPtr (ct))
918 {
919 t = sRefSet_insert (t, sRef_makeArrayFetch (el));
920 }
921 } end_sRefSet_allElements;
922
923 return t;
924 }
925
sRefSet_fetchKnown(sRefSet s,int i)926 sRefSet sRefSet_fetchKnown (sRefSet s, int i)
927 {
928 sRefSet t = sRefSet_new ();
929
930 sRefSet_allElements (s, el)
931 {
932 ctype ct = ctype_realType (sRef_getType (el));
933
934 if (ctype_isArrayPtr (ct))
935 {
936 t = sRefSet_insert (t, sRef_makeArrayFetchKnown (el, i));
937 }
938 } end_sRefSet_allElements;
939
940 return t;
941 }
942
sRefSet_compare(sRefSet s1,sRefSet s2)943 int sRefSet_compare (sRefSet s1, sRefSet s2)
944 {
945 sRefSet_allElements (s1, el)
946 {
947 if (!sRefSet_isSameMember (s2, el))
948 {
949 return -1;
950 }
951 } end_sRefSet_allElements;
952
953 sRefSet_allElements (s2, el)
954 {
955 if (!sRefSet_isSameMember (s1, el))
956 {
957 return 1;
958 }
959 } end_sRefSet_allElements;
960
961 return 0;
962 }
963
sRefSet_equal(sRefSet s1,sRefSet s2)964 bool sRefSet_equal (sRefSet s1, sRefSet s2)
965 {
966 sRefSet_allElements (s1, el)
967 {
968 if (!sRefSet_isSameMember (s2, el))
969 {
970 return FALSE;
971 }
972 } end_sRefSet_allElements;
973
974 sRefSet_allElements (s2, el)
975 {
976 if (!sRefSet_isSameMember (s1, el))
977 {
978 return FALSE;
979 }
980 } end_sRefSet_allElements;
981
982 return TRUE;
983 }
984
985 /*@only@*/ sRefSet
sRefSet_undump(char ** s)986 sRefSet_undump (char **s)
987 {
988 char c;
989 sRefSet sl = sRefSet_new ();
990
991 while ((c = **s) != '#' && c != '@' && c != '$' && c != '&')
992 {
993 sl = sRefSet_insert (sl, sRef_undump (s));
994
995
996 if (**s == ',')
997 {
998 (*s)++;
999 }
1000 }
1001
1002 return sl;
1003 }
1004
1005 /*@only@*/ cstring
sRefSet_dump(sRefSet sl)1006 sRefSet_dump (sRefSet sl)
1007 {
1008 cstring st = cstring_undefined;
1009 bool first = TRUE;
1010
1011
1012 sRefSet_allElements (sl, el)
1013 {
1014 if (!first)
1015 {
1016 st = cstring_appendChar (st, ',');
1017 }
1018 else
1019 {
1020 first = FALSE;
1021 }
1022
1023 st = cstring_concatFree (st, sRef_dump (el));
1024 } end_sRefSet_allElements;
1025
1026 return st;
1027 }
1028
1029 void
sRefSet_markImmutable(sRefSet s)1030 sRefSet_markImmutable (sRefSet s)
1031 {
1032 sRefSet_allElements (s, el)
1033 {
1034 sRef_markImmutable (el);
1035 } end_sRefSet_allElements;
1036 }
1037
1038