2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
25 ** uentryList.c (from slist_template.c)
28 # include "lclintMacros.nf"
31 /*@only@*/ /*@notnull@*/ uentryList
34 uentryList s = (uentryList) dmalloc (sizeof (*s));
37 s->nspace = uentryListBASESIZE;
38 s->elements = (uentry *)
39 dmalloc (sizeof (*s->elements) * uentryListBASESIZE);
46 uentryList_single (/*@keep@*/ uentry el)
48 uentryList s = (uentryList) dmalloc (sizeof (*s));
51 s->nspace = uentryListBASESIZE - 1;
52 s->elements = (uentry *) dmalloc (sizeof (*s->elements) * uentryListBASESIZE);
61 uentryList_grow (uentryList s)
66 llassert (!uentryList_isUndefined (s));
68 s->nspace += uentryListBASESIZE;
70 newelements = (uentry *) dmalloc (sizeof (*newelements)
71 * (s->nelements + s->nspace));
73 for (i = 0; i < s->nelements; i++)
75 newelements[i] = s->elements[i];
79 s->elements = newelements;
82 void uentryList_clear (uentryList s)
84 if (uentryList_isUndefined (s))
90 s->nspace += s->nelements;
95 uentryList uentryList_add (uentryList s, /*@keep@*/ uentry el)
97 if (uentryList_isUndefined (s))
99 s = uentryList_new ();
106 s->elements[s->nelements] = el;
113 uentryList_unparse (uentryList s)
115 cstring st = cstring_undefined;
118 if (uentryList_isDefined (s))
120 for (i = 0; i < uentryList_size (s); i++)
124 st = message ("%q;", uentry_unparse (s->elements[i]));
127 st = message ("%q %q;", st, uentry_unparse (s->elements[i]));
134 /*@unused@*/ /*@only@*/ cstring
135 uentryList_unparseFull (uentryList s)
137 cstring st = cstring_undefined;
140 if (uentryList_isDefined (s))
142 for (i = 0; i < uentryList_size (s); i++)
146 st = message ("%q;", uentry_unparseFull (s->elements[i]));
150 st = message ("%q %q;", st, uentry_unparseFull (s->elements[i]));
158 cstring uentryList_unparseParams (uentryList s)
161 cstring st = cstring_undefined;
164 if (uentryList_isUndefined (s))
168 else if (uentryList_isVoid (s))
170 return (cstring_makeLiteral ("void"));
174 for (i = 0; i < uentryList_size (s); i++)
178 st = message ("%s", ctype_unparse (uentry_getType (s->elements[i])));
182 st = message ("%q, %s", st, ctype_unparse (uentry_getType (s->elements[i])));
190 bool uentryList_matchParams (uentryList p1, uentryList p2, bool force, bool arg)
192 int sz1 = uentryList_size (p1);
193 int sz2 = uentryList_size (p2);
196 if (p1 == p2) return TRUE;
198 if (uentryList_isMissingParams (p1) || uentryList_isMissingParams (p2))
206 for (i = 0; i < sz1; i++)
208 if (!ctype_genMatch (uentry_getType (p1->elements[i]),
209 uentry_getType (p2->elements[i]),
220 uentryList_unparseAbbrev (uentryList p)
223 cstring s = cstring_undefined;
226 if (uentryList_isUndefined (p))
229 if (uentryList_size (p) == 0)
230 return cstring_makeLiteral ("void");
232 for (i = 0; i < p->nelements && i < PRINTBREADTH; i++)
236 s = message ("%q;", uentry_unparseAbbrev (p->elements[i]));
241 s = message ("%q %q;", s, uentry_unparseAbbrev (p->elements[i]));
245 if (i != uentryList_size (p))
246 s = message ("%q, ...", s);
252 uentryList_lookupDirectName (uentryList s, cstring name)
254 if (uentryList_isDefined (s))
258 for (i = 0; i < uentryList_size (s); i++)
260 if (cstring_equal (name, uentry_rawName (s->elements[i])))
271 uentryList_lookupRealName (uentryList s, cstring name)
273 if (uentryList_isDefined (s))
277 for (i = 0; i < uentryList_size (s); i++)
279 cstring uname = uentry_getName (s->elements[i]);
281 if (cstring_equal (name, uname))
283 cstring_free (uname);
287 cstring_free (uname);
294 uentryList uentryList_copy (uentryList s)
297 if (uentryList_isDefined (s))
299 uentryList t = (uentryList) dmalloc (sizeof (*t));
302 t->nelements = s->nelements;
304 t->current = s->current;
306 if (s->nelements > 0)
308 t->elements = (uentry *) dmalloc (sizeof (*t->elements) * t->nelements);
310 for (i = 0; i < s->nelements; i++)
312 t->elements[i] = uentry_copy (s->elements[i]);
324 return uentryList_undefined;
329 uentryList_free (uentryList s)
332 if (!uentryList_isUndefined (s))
336 for (i = 0; i < s->nelements; i++)
338 uentry_free (s->elements[i]);
347 uentryList_isVoid (uentryList cl)
349 if (cl != NULL && cl->nelements == 1)
351 return (ctype_isVoid (uentry_getType (cl->elements[0])));
357 uentryList_getN (uentryList p, int n)
359 llassert (uentryList_isDefined (p));
361 if (n < 0 || (n >= uentryList_size (p)))
363 llcontbug (message ("uentryList_getN: out of range: %d (size %d)",
364 n, uentryList_size (p)));
365 return uentry_undefined;
368 return (p->elements[n]);
371 void uentryList_fixMissingNames (uentryList cl)
373 uentryList_elements (cl, ce)
375 if (!uentry_hasRealName (ce))
377 ctype ct = uentry_getType (ce);
381 uentry_setName (ce, usymtab_getTypeEntryName (ctype_typeId (ct)));
385 llbug (message ("uentryList_fixMissingNames: not UA: %s",
386 ctype_unparse (ct)));
389 uentry_setType (ce, ctype_int);
391 } end_uentryList_elements;
394 void uentryList_fixImpParams (uentryList cl)
397 if (context_getFlag (FLG_PARAMIMPTEMP))
399 uentryList_elements (cl, ce)
401 sRef s = uentry_getSref (ce);
402 alkind ak = sRef_getAliasKind (s);
404 if (alkind_isUnknown (ak) || alkind_isImplicit (ak))
406 exkind ek = sRef_getExKind (s);
408 if (exkind_isKnown (ek))
410 sRef_setAliasKind (s, AK_IMPDEPENDENT, fileloc_undefined);
414 sRef_setAliasKind (s, AK_IMPTEMP, fileloc_undefined);
420 } end_uentryList_elements;
425 uentryList_compareParams (uentryList s, uentryList t)
429 if (s == t) return 0;
431 if (uentryList_isUndefined (s)) return 1;
432 if (uentryList_isUndefined (t)) return -1;
434 sz = uentryList_size (s);
436 INTCOMPARERETURN (uentryList_size (t), sz);
438 for (i = 0; i < sz; i++)
440 COMPARERETURN (uentry_compare (s->elements[i], t->elements[i]));
447 uentryList_compareStrict (uentryList s, uentryList t)
456 if (uentryList_isMissingParams (s))
458 if (uentryList_isMissingParams (t))
469 if (uentryList_isMissingParams (t))
475 sz = uentryList_size (s);
477 INTCOMPARERETURN (uentryList_size (t), sz);
479 for (i = 0; i < sz; i++)
481 COMPARERETURN (uentry_compareStrict (s->elements[i], t->elements[i]));
490 uentryList_compareFields (uentryList s, uentryList t)
494 if (s == t) return 0;
496 if (uentryList_isUndefined (s))
498 if (uentryList_isUndefined (t))
501 sz = uentryList_size (s);
503 if (uentryList_size (t) != sz)
505 return (int_compare (sz, uentryList_size (t)));
508 for (i = 0; i < sz; i++)
510 uentry se = s->elements[i];
511 uentry te = t->elements[i];
512 int namecmp = cstring_compare (uentry_rawName (se), uentry_rawName (te));
516 int uc = uentry_compare (s->elements[i], t->elements[i]);
533 uentryList_current (uentryList s)
535 llassert (uentryList_isDefined (s));
536 llassert (!(s->current < 0 || (s->current >= s->nelements)));
537 return (s->elements[s->current]);
541 uentryList_dumpParams (uentryList s)
543 cstring st = cstring_undefined;
545 if (uentryList_isUndefined (s)) return st;
547 uentryList_elements (s, current)
549 st = message ("%q%q,", st, uentry_dumpParam (current));
550 } end_uentryList_elements;
556 uentryList_dumpFields (uentryList s)
558 cstring st = cstring_undefined;
560 if (uentryList_isUndefined (s)) return st;
562 uentryList_elements (s, current)
564 if (!uentry_isVariable (current))
566 llassert (uentry_isFunction (current));
567 st = message ("%q!%q,", st, uentry_dump (current));
571 st = message ("%q%q,", st, uentry_dump (current));
573 } end_uentryList_elements;
578 /*@only@*/ uentryList
579 uentryList_undumpFields (char **s, fileloc loc)
581 uentryList ul = uentryList_new ();
583 while (**s != '\0' && **s != '}')
588 ul = uentryList_add (ul, uentry_undump (ekind_function, loc, s));
592 ul = uentryList_add (ul, uentry_undump (ekind_variable, loc, s));
601 /*@only@*/ uentryList
602 uentryList_undump (char **s)
605 uentryList pn = uentryList_new ();
610 while (c != '#' && c != '@' && c != ')')
612 uentry ue = uentry_undump (ekind_variable, g_currentloc, s);
615 if (!uentry_isUndefined (ue))
617 pn = uentryList_add (pn, ue);
634 uentryList_reset (uentryList s)
636 if (uentryList_isUndefined (s)) return;
641 uentryList_isFinished (uentryList s)
643 if (uentryList_isUndefined (s)) return TRUE;
644 return (s->current > s->nelements - 1);
648 uentryList_advanceSafe (uentryList s)
650 if (uentryList_isUndefined (s)) return;
654 if (s->current > s->nelements)
656 s->current = s->nelements;
661 uentryList_size (uentryList s)
663 if (uentryList_isUndefined (s)) return 0;
665 if (s->nelements == 1 && ctype_isVoid (uentry_getType (s->elements[0])))
672 uentryList_isMissingParams (uentryList s)
674 return (uentryList_isUndefined (s) || s->nelements == 0);
677 bool uentryList_hasReturned (uentryList ul)
679 uentryList_elements (ul, current)
681 if (uentry_isReturned (current)) return TRUE;
682 } end_uentryList_elements;
688 uentryList_lookupField (uentryList f, cstring name)
690 int i = uentryList_lookupDirectName (f, name);
694 return (uentryList_getN (f, i));
698 return uentry_undefined;
702 /*@only@*/ uentryList
703 uentryList_mergeFields (/*@only@*/ uentryList f1, /*@only@*/ uentryList f2)
705 if (uentryList_isUndefined (f1))
710 if (uentryList_isDefined (f2))
712 uentryList_elements (f2, current)
714 uentry old = uentryList_lookupField (f1, uentry_rawName (current));
716 if (uentry_isValid (old))
720 message ("Field name reused: %s", uentry_rawName (current)),
721 uentry_whereDefined (current));
722 llgenmsg (message ("Previous use of %s", uentry_rawName (current)),
723 uentry_whereDefined (old));
726 /* okay to use exposed current since f2 is killed */
727 /*@-exposetrans@*/ /*@-dependenttrans@*/
728 f1 = uentryList_add (f1, current);
729 /*@=exposetrans@*/ /*@=dependenttrans@*/
731 } end_uentryList_elements;
733 sfree (f2->elements);
741 uentryList_showFieldDifference (uentryList p1, uentryList p2)
746 llassert (NOALIAS (p1, p2));
747 llassert (uentryList_isDefined (p1));
748 llassert (uentryList_isDefined (p2));
750 for (index = 0; index < p1->nelements; index++)
752 cp1 = p1->elements[index];
754 if (index == p2->nelements)
757 (message ("Field present in %s, missing in %rdeclaration: %q",
758 uentry_specDeclName (cp1),
759 uentry_isDeclared (cp1),
760 uentry_unparse (cp1)),
761 uentry_whereEither (cp1));
765 cp2 = p2->elements[index];
767 if (!(cstring_equal (uentry_rawName (cp1), uentry_rawName (cp2))))
770 (message ("Field %s in %s corresponds to %s in %rdeclaration",
771 uentry_rawName (cp1),
772 uentry_specOrDefName (cp1),
773 uentry_rawName (cp2),
774 uentry_isCodeDefined (cp1)),
775 uentry_whereDefined (cp2));
776 uentry_showWhereLastPlain (cp1);
781 if (!ctype_match (uentry_getType (cp1), uentry_getType (cp2)))
784 (message ("Field %s %rdeclared as %s, %s as %s",
785 uentry_rawName (cp2),
786 uentry_isCodeDefined (cp1),
787 ctype_unparse (uentry_getType (cp1)),
788 uentry_specOrDefName (cp2),
789 ctype_unparse (uentry_getType (cp2))),
790 uentry_whereDefined (cp2));
791 uentry_showWhereLastPlain (cp1);
797 if (index != p2->nelements)
799 cp2 = p2->elements[index];
802 (message ("Extra field in new declaration: %q",
803 uentry_unparse (cp2)),
804 uentry_whereEither (cp2));
809 llbug (message ("uentryList_showFieldDifference: match: %q / %q",
810 uentryList_unparse (p1), uentryList_unparse (p2)));
814 uentryList_matchFields (uentryList p1, uentryList p2)
824 if (uentryList_isEmpty (p1) || uentryList_isEmpty (p2))
829 if (uentryList_size (p1) != uentryList_size (p2))
834 for (index = 0; index < p1->nelements; index++)
836 cp1 = p1->elements[index];
837 cp2 = p2->elements[index];
839 if (!(cstring_equal (uentry_rawName (cp1), uentry_rawName (cp2))
840 && (ctype_almostEqual (uentry_getType (cp1), uentry_getType (cp2)))))
841 { /* was ctype_match! */