2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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 splint: splint@cs.virginia.edu
21 ** To report a bug: splint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
27 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
28 ** (This is necessary because there is no other way in C to have a
29 ** hidden scope, besides at the file level.)
34 abst_typedef /*@null@*/ struct s_ctbase *ctbase;
36 /*@private@*/ typedef struct {
39 ctype base; /* type I point to (or element of array) */
40 ctype ptr; /* type of pointer to me */
41 ctype array; /* type of array of me */
42 cstring unparse; /* unparse me, if memoized */
45 typedef /*@only@*/ ctentry o_ctentry;
50 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
51 /* memoize matches...maybe in context? */
54 extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
55 # define ctentry_isBogus(c) \
56 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
58 static cttable cttab = { 0, 0, NULL };
60 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
61 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
62 static /*@only@*/ ctentry
63 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
64 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
65 static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
66 static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
68 static void cttable_grow (void);
69 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
70 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
71 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
72 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, long p_size) /*@*/ ;
75 ** These are file-static macros (used in ctype.c). No way to
76 ** declare them as static in C.
79 /*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
80 # define ctentry_getBase(c) ((c)->base)
81 # define ctentry_getKind(c) ((c)->kind)
82 # define ctentry_getArray(c) ((c)->array)
83 # define ctentry_getPtr(c) ((c)->ptr)
84 # define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
85 # define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
86 # define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
87 # define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
88 # define ctentry_setArray(c,b) ((c)->array = (b))
89 # define ctentry_setPtr(c,b) ((c)->ptr = (b))
91 # define ctbase_fixUser(c) (c = ctbase_realType(c))
92 /*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
94 static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
95 static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
96 static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
97 static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
98 static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
99 static /*@observer@*/ /*@notnull@*/ ctbase
100 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
101 static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
102 static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
103 static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
104 static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
105 static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
106 static /*@only@*/ /*@notnull@*/ ctbase ctbase_copy (/*@notnull@*/ ctbase p_c) /*@*/ ;
107 static void ctbase_free (/*@only@*/ ctbase p_c);
108 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
109 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
110 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
111 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
113 static /*@notnull@*/ /*@only@*/ ctbase
114 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
116 static /*@notnull@*/ /*@only@*/ ctbase
117 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
118 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
119 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
120 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
121 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
122 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
123 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
124 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
125 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
126 static /*@notnull@*/ ctype
127 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
128 static /*@notnull@*/ /*@observer@*/ ctbase
129 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
130 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
131 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
132 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
133 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
134 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
135 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
136 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
139 extern int cttable_lastIndex();
140 # define cttable_lastIndex() (cttab.size - 1)
146 /*@only@*/ uentryList params;
165 enumNameList members;
176 cprim prim; /* primitive */
177 typeId tid; /* abstract, user */
178 ctype base; /* ptr, array */
179 cfcn fcn; /* function */
180 tsu su; /* struct union */
181 tenum cenum; /* enum */
182 tconj conj; /* conj */
183 tfixed farray; /* fixed array */
192 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
193 static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
194 static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
195 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
196 static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
197 static /*@only@*/ /*@notnull@*/ ctbase
198 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
200 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
202 /*@constant null ctbase ctbase_undefined; @*/
203 # define ctbase_undefined ((ctbase)0)
205 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
206 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
208 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
210 return ((c) != ctbase_undefined);
213 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
215 return ((c) == ctbase_undefined);
218 static ctkind ctype_getCtKind (ctype c)
220 ctentry ce = ctype_getCtentry (c);
222 return ctentry_getKind (ce);
225 static bool ctbase_isUser (ctbase c)
227 if (ctbase_isDefined (c))
229 return (ctbase_isKind (c, CT_USER));
237 static bool ctbase_isEnum (ctbase c)
239 if (ctbase_isDefined (c))
241 return (ctbase_isKind (c, CT_ENUM));
249 static bool ctbase_isExpFcn (ctbase c)
251 if (ctbase_isDefined (c))
253 return (c->type == CT_EXPFCN);
261 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
263 if (ctbase_isDefined (c))
265 return (c->type == CT_CONJ);
273 static bool ctuid_isAP (ctuid c) /*@*/
275 return (c == CT_ARRAY || c == CT_PTR);
278 static typeId ctbase_typeId (ctbase p_c);
279 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
280 static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
281 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
282 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
283 static /*@notnull@*/ /*@only@*/ ctbase
284 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
285 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
286 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
287 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
288 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
289 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
290 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
291 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
292 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
293 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
294 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
296 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
297 static int nctbases = 0;
299 static /*@notnull@*/ /*@only@*/
300 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
302 static bool ctbase_isUnnamedSU (ctbase c)
304 return (ctbase_isDefined (c)
305 && (ctbase_isStruct (c) || ctbase_isUnion (c))
306 && isFakeTag (c->contents.su->name));
309 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
313 typeId uid = ctbase_typeId (c);
315 if (usymtab_isBoolType (uid))
317 return ctbase_getBool ();
321 ctbase ret = ctype_getCtbase
322 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
324 llassert (ret != ctbase_undefined);
335 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
337 ctbase r = ctbase_realType (c);
339 return (ctbase_isKind (r, CT_PTR) &&
340 ctype_isVoid (r->contents.base));
344 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
346 ctbase r = ctbase_realType (c);
348 return (ctbase_isKind (r, CT_PTR));
352 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
354 ctbase r = ctbase_realType (c);
356 return (ctbase_isKind (r, CT_ARRAY)
357 || ctbase_isKind (r, CT_FIXEDARRAY));
361 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
363 ctbase r = ctbase_realType (c);
365 return (ctbase_isKind (r, CT_FIXEDARRAY));
369 ctbase_isStruct (/*@notnull@*/ ctbase c)
371 ctbase r = ctbase_realType (c);
373 return (ctbase_isKind (r, CT_STRUCT));
377 ctbase_isUnion (/*@notnull@*/ ctbase c)
379 ctbase r = ctbase_realType (c);
381 return (ctbase_isKind (r, CT_UNION));
385 ** clean this up -> typeTable should store ctype
389 ctbase_typeBaseUid (ctbase c)
393 if (ctbase_isDefined (c))
399 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
401 else if (ct == CT_USER || ct == CT_ABST)
403 return c->contents.tid;
405 else if (ct == CT_FIXEDARRAY)
407 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
411 llcontbuglit ("ctbase_typeBaseUid: bad call");
412 return typeId_invalid;
415 return typeId_invalid;
419 ctbase_isBaseUA (ctbase c)
423 if (ctbase_isDefined (c))
429 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
431 else if (ct == CT_FIXEDARRAY)
433 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
436 return (ct == CT_USER || ct == CT_ABST);
442 ctbase_typeId (ctbase c)
446 return c->contents.tid;
450 if (ctbase_isConj (c))
452 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
456 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
457 return typeId_invalid;
462 static /*@only@*/ cstring
463 ctbase_unparse (ctbase c)
465 if (ctbase_isUndefined (c)) {
466 return cstring_makeLiteral ("<<undef>>");
472 return cstring_makeLiteral ("?");
474 return cstring_copy (context_printBoolName ());
476 return (cprim_unparse (c->contents.prim));
478 return (usymtab_getTypeEntryName (c->contents.tid));
480 return (usymtab_getTypeEntryName (c->contents.tid));
482 return (message ("<expf: %t>", c->contents.base));
484 /* no spaces for multiple pointers */
486 if (ctype_isPointer (c->contents.base))
488 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
492 return (message ("%t *", c->contents.base));
495 return (message ("%t [%d]",
496 c->contents.farray->base,
497 (int) c->contents.farray->size));
499 return (message ("%t []", c->contents.base));
501 return (message ("[function (%q) returns %t]",
502 uentryList_unparseParams (c->contents.fcn->params),
503 c->contents.fcn->rval));
505 if (cstring_isDefined (c->contents.su->name) &&
506 !cstring_isEmpty (c->contents.su->name) &&
507 !isFakeTag (c->contents.su->name))
509 return (message ("struct %s", c->contents.su->name));
513 return (message ("struct { %q }",
514 uentryList_unparseAbbrev (c->contents.su->fields)));
517 if (cstring_isDefined (c->contents.su->name) &&
518 !cstring_isEmpty (c->contents.su->name) &&
519 !isFakeTag (c->contents.su->name))
521 return (message ("union %s", c->contents.su->name));
525 return (message ("union { %q }",
526 uentryList_unparseAbbrev (c->contents.su->fields)));
529 if (isFakeTag (c->contents.cenum->tag))
531 return (message ("enum { %q }",
532 enumNameList_unparseBrief (c->contents.cenum->members)));
536 return (message ("enum %s { %q }",
537 c->contents.cenum->tag,
538 enumNameList_unparseBrief (c->contents.cenum->members)));
541 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
543 if (!ctype_isSimple (c->contents.conj->a) ||
544 !ctype_isSimple (c->contents.conj->b))
546 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
550 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
555 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
562 static /*@only@*/ cstring
563 ctbase_unparseDeep (ctbase c)
565 if (ctbase_isUndefined (c))
567 return cstring_makeLiteral ("<<undef>>");
573 return cstring_makeLiteral ("?");
575 return cstring_copy (context_printBoolName ());
577 return (cprim_unparse (c->contents.prim));
579 if (cstring_isNonEmpty (c->contents.cenum->tag))
581 return (message ("enum %s { %q }",
582 c->contents.cenum->tag,
583 enumNameList_unparse (c->contents.cenum->members)));
587 return (message ("enum { %q }",
588 enumNameList_unparse (c->contents.cenum->members)));
591 return (usymtab_getTypeEntryName (c->contents.tid));
593 return (usymtab_getTypeEntryName (c->contents.tid));
595 return (message ("<expf: %t>", c->contents.base));
597 return (message ("%t *", c->contents.base));
599 return (message ("%t [%d]", c->contents.farray->base,
600 (int) c->contents.farray->size));
602 return (message ("%t []", c->contents.base));
604 return (message ("[function (%q) returns %t]",
605 uentryList_unparse (c->contents.fcn->params),
606 c->contents.fcn->rval));
608 return (message ("struct %s { ... } ", c->contents.su->name));
610 return (message ("union %s { ... }", c->contents.su->name));
612 return (message ("%t", c->contents.conj->a));
618 static /*@only@*/ cstring
619 ctbase_unparseNotypes (ctbase c)
621 llassert (ctbase_isDefined (c));
626 return cstring_makeLiteral ("?");
628 return cstring_copy (context_printBoolName ());
630 return (cprim_unparse (c->contents.prim));
632 if (typeId_isInvalid (c->contents.tid))
634 return cstring_makeLiteral ("enum");
638 return (message ("T#%d", c->contents.tid));
641 return (message ("uT#%d", c->contents.tid));
643 return (message ("aT#%d", c->contents.tid));
645 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
647 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
649 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
651 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
652 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
654 return (message ("struct %s", c->contents.su->name));
656 return (message ("union %s", c->contents.su->name));
658 return (message ("[enumlist]"));
660 return (message ("%q/%q",
661 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
662 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
668 static /*@only@*/ cstring
669 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
671 if (ctbase_isUndefined (c))
679 return (message ("? %q", name));
681 return (message ("%s %q", context_printBoolName (), name));
683 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
686 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
688 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
691 if (ctype_isFunction (c->contents.base))
693 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
697 cstring s = cstring_prependChar ('*', name);
698 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
703 return (message ("%q[%d]",
704 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
705 (int) c->contents.farray->size));
707 return (message ("%q[]",
708 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
711 cstring s = message ("%q(%q)", name,
712 uentryList_unparseParams (c->contents.fcn->params));
714 return (ctbase_unparseDeclaration
715 (ctype_getCtbase (c->contents.fcn->rval), s));
718 if (cstring_isDefined (c->contents.su->name) &&
719 !cstring_isEmpty (c->contents.su->name) &&
720 !isFakeTag (c->contents.su->name))
722 return (message ("struct %s %q", c->contents.su->name, name));
726 return (message ("struct { %q } %q",
727 uentryList_unparseAbbrev (c->contents.su->fields),
731 if (cstring_isDefined (c->contents.su->name) &&
732 !cstring_isEmpty (c->contents.su->name) &&
733 !isFakeTag (c->contents.su->name))
735 return (message ("union %s %q", c->contents.su->name, name));
739 return (message ("union { %q } %q",
740 uentryList_unparseAbbrev (c->contents.su->fields),
744 if (isFakeTag (c->contents.cenum->tag))
746 return (message ("enum { %q } %q",
747 enumNameList_unparseBrief (c->contents.cenum->members),
752 return (message ("enum %s { %q } %q",
753 c->contents.cenum->tag,
754 enumNameList_unparseBrief (c->contents.cenum->members),
758 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
760 if (!ctype_isSimple (c->contents.conj->a) ||
761 !ctype_isSimple (c->contents.conj->b))
763 cstring name1 = cstring_copy (name);
768 ctbase_unparseDeclaration
769 (ctype_getCtbase (c->contents.conj->a), name1),
770 ctbase_unparseDeclaration
771 (ctype_getCtbase (c->contents.conj->b), name)));
775 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
776 cstring_copy (name));
778 (message ("%q | %q", s1,
779 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
786 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
793 static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
803 return (ctbase_undefined);
805 return (ctbase_createUnknown ());
807 return (ctbase_createBool ());
809 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
810 reader_checkChar (c, '|');
813 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
814 reader_checkChar (c, '|');
817 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
818 reader_checkChar (c, '|');
821 res = ctbase_makePointer (ctype_undump (c));
822 reader_checkChar (c, '|');
825 res = ctbase_makeArray (ctype_undump (c));
826 reader_checkChar (c, '|');
830 ctype ct = ctype_undump (c);
833 reader_checkChar (c, '/');
834 size = reader_getInt (c);
835 reader_checkChar (c, '|');
836 return (ctbase_makeFixedArray (ct, size));
841 char *lp = strchr (*c, '(');
843 llassertfatal (lp != NULL);
846 ct = ctype_undump (c);
849 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
856 char *lc = strchr (*c, '{');
858 llassert (lc != NULL);
861 sname = mstring_copy (*c);
869 i = (unsigned) atoi (sname + 1);
874 fields = uentryList_undumpFields (c, g_currentloc);
876 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
882 char *lc = strchr (*c, '{');
884 llassert (lc != NULL);
887 sname = mstring_copy (*c);
888 llassert (sname != NULL);
896 i = (unsigned) atoi (sname + 1);
900 return (ctbase_createUnion (cstring_fromCharsO (sname),
901 uentryList_undumpFields (c, g_currentloc)));
907 char *lc = strchr (*c, '{');
909 llassert (lc != NULL);
912 sname = mstring_copy (*c);
919 i = (unsigned) atoi (sname + 1);
923 ret = ctbase_createEnum (cstring_fromCharsO (sname),
924 enumNameList_undump (c));
932 isExplicit = bool_fromInt (reader_getInt (c));
933 reader_checkChar (c, '.');
934 c1 = ctype_undump (c);
935 reader_checkChar (c, '/');
936 c2 = ctype_undump (c);
937 reader_checkChar (c, '|');
939 return (ctbase_makeConj (c1, c2, isExplicit));
945 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
947 /*drl bee: pbr*/ while (**c != '\0')
952 return ctbase_createUnknown ();
956 /* first letter of c encodes type: */
972 static /*@only@*/ cstring
973 ctbase_dump (ctbase c)
975 if (!ctbase_isDefined (c))
977 return cstring_makeLiteral ("?");
983 return cstring_makeLiteral ("u");
985 return cstring_makeLiteral ("b");
987 return (message ("p%d|", c->contents.prim));
989 return (message ("s%d|",
990 usymtab_convertId (c->contents.tid)));
992 return (message ("a%d|", usymtab_convertId (c->contents.tid)));
994 return (message ("t%q|", ctype_dump (c->contents.base)));
996 return (message ("y%q|", ctype_dump (c->contents.base)));
998 return (message ("F%q/%d|",
999 ctype_dump (c->contents.farray->base),
1000 (int) c->contents.farray->size));
1002 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
1003 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1004 uentryList_dumpParams (c->contents.fcn->params)));
1006 return (message ("S%s{%q}", c->contents.su->name,
1007 uentryList_dumpFields (c->contents.su->fields)));
1009 return (message ("U%s{%q}", c->contents.su->name,
1010 uentryList_dumpFields (c->contents.su->fields)));
1015 if (cstring_isNonEmpty (c->contents.cenum->tag))
1017 s = message ("e%s{%q}",
1018 c->contents.cenum->tag,
1019 enumNameList_dump (c->contents.cenum->members));
1023 s = message ("e{%q}",
1024 enumNameList_dump (c->contents.cenum->members));
1029 return (message ("C%d.%q/%q|",
1030 bool_toInt (c->contents.conj->isExplicit),
1031 ctype_dump (c->contents.conj->a),
1032 ctype_dump (c->contents.conj->b)));
1034 /* should clean them up! */
1035 return (cstring_makeLiteral ("?"));
1037 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1038 return (message ("u"));
1045 static /*@only@*/ ctbase
1046 ctbase_copy (/*@notnull@*/ ctbase c)
1051 return (ctbase_createUnknown ());
1053 return (ctbase_createBool ());
1055 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1056 enumNameList_copy (c->contents.cenum->members)));
1058 return (ctbase_createPrim (c->contents.prim));
1060 return (ctbase_createUser (c->contents.tid));
1062 return (ctbase_createAbstract (c->contents.tid));
1064 return (ctbase_expectFunction (c->contents.base));
1066 return (ctbase_makePointer (c->contents.base));
1068 return (ctbase_makeArray (c->contents.base));
1070 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1071 uentryList_copy (c->contents.fcn->params)));
1073 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1074 uentryList_copy (c->contents.su->fields)));
1076 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1077 uentryList_copy (c->contents.su->fields)));
1079 /*@i@*/ return (c); /* not a real copy for conj's */
1081 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1088 ctbase_elist (ctbase c)
1090 llassert (ctbase_isDefined (c));
1091 llassert (c->type == CT_ENUM);
1093 return (c->contents.cenum->members);
1097 ctbase_free (/*@only@*/ ctbase c)
1099 if (c == ctbase_bool || c == ctbase_unknown)
1101 /*@-mustfree@*/ return; /*@=mustfree@*/
1107 if (ctbase_isDefined (c))
1135 /*@i32@*/ /* uentryList_free (c->contents.fcn->params); */
1140 cstring_free (c->contents.su->name);
1141 uentryList_free (c->contents.su->fields);
1145 /* Don't bree conj's, */
1155 ** c should be * <unknown>
1158 static /*@only@*/ ctbase
1159 ctbase_expectFunction (ctype c)
1161 ctbase f = ctbase_new ();
1163 f->type = CT_EXPFCN;
1164 f->contents.base = c;
1170 ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
1172 return (ct->type == CT_EXPFCN);
1176 ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
1178 llassert (ctbase_isExpectFunction (ct));
1179 return ct->contents.base;
1183 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1187 /* undefined types never match */
1189 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1192 /* abstract types match user types of same name */
1194 c1 = ctbase_realType (c1);
1195 c2 = ctbase_realType (c2);
1197 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1198 ctbase_unparse (c2)));
1203 if (c1tid == CT_CONJ)
1205 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1206 force, arg, def, deep)
1207 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1208 force, arg, def, deep));
1211 if (c2tid == CT_CONJ)
1213 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1214 force, arg, def, deep)
1215 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1216 force, arg, def, deep));
1220 ** if the types don't match, there are some special cases...
1225 /* unknowns match anything */
1227 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1232 if (c1tid == CT_FIXEDARRAY
1233 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1235 if (ctype_isVoid (c2->contents.base))
1237 return (context_getFlag (FLG_ABSTVOIDP) ||
1238 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1239 !(ctype_isRealAbstract (c2->contents.base))));
1242 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1243 ctype_getCtbase (c2->contents.base),
1244 force, arg, def, deep));
1248 if (c2tid == CT_FIXEDARRAY
1249 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1251 if (ctype_isVoid (c1->contents.base))
1253 return (context_getFlag (FLG_ABSTVOIDP) ||
1254 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1255 !(ctype_isRealAbstract (c1->contents.base))));
1258 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1259 ctype_getCtbase (c2->contents.farray->base),
1260 force, arg, def, deep));
1263 /* evs 2000-07-25: Bool's may match user/abstract types */
1265 if ((c1tid == CT_BOOL
1266 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1268 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1270 return (context_msgBoolInt ());
1273 if ((c1tid == CT_BOOL && (c2tid == CT_ABST || c2tid == CT_USER))) {
1274 ctype t2c = c2->contents.base;
1276 return (ctype_isBool (t2c));
1279 if ((c2tid == CT_BOOL && (c1tid == CT_ABST || c1tid == CT_USER))) {
1280 ctype t1c = c1->contents.base;
1282 return (ctype_isBool (t1c));
1285 if ((c1tid == CT_ENUM
1286 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1288 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1290 return (context_msgEnumInt ());
1294 ** arrays and pointers...yuk!
1296 ** Considered equivalent except in definitions.
1297 ** (e.g., function parameters are equivalent)
1303 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1310 ** Function pointers can be removed.
1312 ** [function ..] is equivalent to [function ..] *
1315 if (c1tid == CT_PTR && c2tid == CT_FCN)
1317 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1319 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1324 if (c2tid == CT_PTR && c1tid == CT_FCN)
1326 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1328 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1334 ** we allow forward declarations to structures like,
1336 ** typedef struct _t *t;
1339 ** struct _t * to match t
1342 if (context_getFlag (FLG_FORWARDDECL))
1344 if (c1tid == CT_ABST || c1tid == CT_USER)
1346 if (ctuid_isAP (c2tid))
1348 ctype ts = c2->contents.base;
1350 if (ctype_isUA (ts))
1352 typeId ttid = ctype_typeId (ts);
1353 typeId ctid = c1->contents.tid ;
1355 if (usymtab_matchForwardStruct (ctid, ttid))
1363 if (c2tid == CT_ABST || c2tid == CT_USER)
1365 if (ctuid_isAP (c1tid))
1367 ctype ts = c1->contents.base;
1369 if (ctype_isUA (ts))
1371 typeId ttid = ctype_typeId (ts);
1372 typeId ctid = c2->contents.tid ;
1374 if (usymtab_matchForwardStruct (ctid, ttid))
1393 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1395 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1400 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1402 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1404 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1406 if (ctype_isVoid (c1->contents.base)
1407 || (ctype_isVoid (c2->contents.base)))
1409 if (ctype_isFunction (ctype_realType (c1->contents.base))
1410 || ctype_isFunction (ctype_realType (c2->contents.base)))
1412 return (!context_getFlag (FLG_CASTFCNPTR));
1416 return (context_getFlag (FLG_ABSTVOIDP) ||
1417 (!(ctype_isRealAbstract (c1->contents.base)) &&
1418 !(ctype_isRealAbstract (c2->contents.base))));
1423 /* Only allow one implicit function pointer. */
1425 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1426 ctype_isRealPointer (c2->contents.base))
1427 && (ctype_isRealFunction (c1->contents.base)
1428 || ctype_isRealFunction (c2->contents.base)))
1433 return (ctype_genMatch (c1->contents.base,
1434 c2->contents.base, force, arg, def, TRUE));
1437 if (ctype_isVoid (c1->contents.farray->base)
1438 || ctype_isVoid (c2->contents.farray->base))
1440 return (ctype_genMatch (c1->contents.farray->base,
1441 c2->contents.farray->base,
1442 force, arg, def, deep));
1444 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1446 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1448 return (ctype_genMatch (c1->contents.fcn->rval,
1449 c2->contents.fcn->rval,
1450 force, arg, def, TRUE)
1451 && uentryList_matchParams (c1->contents.fcn->params,
1452 c2->contents.fcn->params,
1456 DPRINTF (("Struct: %s / %s",
1457 c1->contents.su->name,
1458 c2->contents.su->name));
1460 if (isFakeTag (c1->contents.su->name)
1461 && isFakeTag (c2->contents.su->name))
1463 /* Both fake tags, check structure */
1464 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1470 return uentryList_matchFields (c1->contents.su->fields,
1471 c2->contents.su->fields);
1476 if (!cstring_isEmpty (c1->contents.su->name))
1478 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1482 if (!cstring_isEmpty (c2->contents.su->name))
1487 llcontbuglit ("ctbase_genMatch: match fields");
1492 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1498 ** like ctbase_match, except for conjuncts:
1499 ** modifies conjuncts to match only
1503 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1505 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1509 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1511 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1515 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1517 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1521 ctbase_matchArg (ctbase c1, ctbase c2)
1523 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1526 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1529 ctbase c = (ctbase) dmalloc (sizeof (*c));
1533 if (nctbases % 100 == 0 && nctbases > lastnc)
1535 llmsg (message ("ctbases: %d", nctbases));
1542 static /*@only@*/ ctbase
1543 ctbase_createPrim (cprim p)
1545 ctbase c = ctbase_new ();
1548 c->contents.prim = p;
1553 static /*@observer@*/ ctbase
1554 ctbase_getBool (void)
1556 /*@i@*/ return ctbase_createBool ();
1560 ctbase_createBool ()
1562 if (!ctbase_isDefined (ctbase_bool))
1564 ctbase_bool = ctbase_new ();
1565 ctbase_bool->type = CT_BOOL;
1566 ctbase_bool->contents.prim = CTX_BOOL;
1569 /*@-retalias@*/ /*@-globstate@*/
1571 /*@=retalias@*/ /*@=globstate@*/
1574 static /*@only@*/ ctbase
1575 ctbase_createUser (typeId u)
1577 ctbase c = ctbase_new ();
1580 c->contents.tid = u;
1582 llassert (typeId_isValid (u));
1587 static /*@only@*/ ctbase
1588 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1590 ctbase c = ctbase_new ();
1594 if (cstring_isUndefined (etag))
1596 llcontbuglit ("Undefined enum tag!");
1600 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1601 c->contents.cenum->tag = etag;
1602 c->contents.cenum->members = emembers;
1607 static /*@observer@*/ cstring
1608 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1610 return (ct->contents.cenum->tag);
1613 static /*@only@*/ ctbase
1614 ctbase_createAbstract (typeId u)
1616 ctbase c = ctbase_new ();
1619 c->contents.tid = u;
1621 /* also check its abstract? */
1623 llassert (typeId_isValid (c->contents.tid));
1628 static /*@only@*/ ctbase
1629 ctbase_createUnknown (void)
1631 if (!ctbase_isDefined (ctbase_unknown))
1633 ctbase_unknown = ctbase_new ();
1634 ctbase_unknown->type = CT_UNKNOWN;
1635 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1638 /*@-retalias@*/ /*@-globstate@*/
1639 return ctbase_unknown;
1640 /*@=retalias@*/ /*@=globstate@*/
1644 ** requires: result is not assigned to b
1645 ** (should copy, but no way to reclaim storage)
1648 static /*@only@*/ ctbase
1649 ctbase_makePointer (ctype b)
1651 ctbase c = ctbase_new ();
1654 c->contents.base = b;
1659 static /*@only@*/ ctbase
1660 ctbase_makeArray (ctype b)
1662 ctbase c = ctbase_new ();
1665 c->contents.base = b;
1670 static /*@notnull@*/ /*@only@*/ ctbase
1671 ctbase_makeFixedArray (ctype b, long size)
1673 ctbase c = ctbase_new ();
1675 c->type = CT_FIXEDARRAY;
1677 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1678 c->contents.farray->base = b;
1679 c->contents.farray->size = size;
1685 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1687 ctbase c = ctbase_new ();
1691 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1693 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1698 if (ctype_isPointer (b))
1700 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1704 ctb = ctype_getCtbase (b);
1707 llassert (ctbase_isDefined (ctb));
1708 llassert (ctb->type == CT_FCN);
1710 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1712 c->contents.fcn->rval = rval;
1713 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1717 c->contents.fcn->rval = b;
1718 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1719 /*@-branchstate@*/ /* p is really released on this branch */
1723 ct = cttable_addComplex (c);
1724 return (ct); /* was: ctype_makePointer (ct)); */
1728 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1730 ctbase c = ctbase_new ();
1734 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1736 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1741 if (ctype_isPointer (b))
1743 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1747 ctb = ctype_getCtbase (b);
1750 llassert (ctbase_isDefined (ctb));
1751 llassert (ctb->type == CT_FCN);
1753 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1755 c->contents.fcn->rval = rval;
1756 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1760 c->contents.fcn->rval = b;
1761 c->contents.fcn->params = uentryList_copy (p);
1766 ct = cttable_addComplex (c);
1767 return (ct); /* was: ctype_makePointer (ct)); */
1770 static /*@only@*/ ctbase
1771 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1773 ctbase c = ctbase_new ();
1777 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1778 c->contents.fcn->rval = b;
1779 c->contents.fcn->params = p;
1781 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1784 static /*@observer@*/ /*@notnull@*/ ctbase
1785 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1789 if (c->type == CT_FCN)
1794 llassert (ctbase_isFunction (c));
1796 res = ctype_getCtbase (c->contents.base);
1798 llassert (ctbase_isDefined (res));
1804 ctbase_isFunction (ctbase c)
1806 llassert (c != ctbase_undefined);
1808 if (c->type == CT_FCN)
1814 if (c->type == CT_PTR)
1816 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1818 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1825 /* doesn't copy c1 and c2 */
1827 static /*@only@*/ ctbase
1828 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1830 ctbase c = ctbase_new ();
1834 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1835 c->contents.conj->a = c1;
1836 c->contents.conj->b = c2;
1837 c->contents.conj->isExplicit = isExplicit;
1843 ctbase_getConjA (/*@notnull@*/ ctbase c)
1845 llassert (c->type == CT_CONJ);
1846 return (c->contents.conj->a);
1850 ctbase_getConjB (/*@notnull@*/ ctbase c)
1852 llassert (c->type == CT_CONJ);
1853 return (c->contents.conj->b);
1857 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1859 llassert (c->type == CT_CONJ);
1860 return (c->contents.conj->isExplicit);
1863 static /*@only@*/ ctbase
1864 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1866 ctbase c = ctbase_new ();
1868 c->type = CT_STRUCT;
1870 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1871 c->contents.su->name = n;
1872 c->contents.su->fields = f;
1877 static /*@observer@*/ uentryList
1878 ctbase_getuentryList (/*@notnull@*/ ctbase c)
1880 c = ctbase_realType (c);
1882 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1883 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1885 return (c->contents.su->fields);
1889 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1891 ctbase c = ctbase_new ();
1895 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1896 c->contents.su->name = n;
1897 c->contents.su->fields = f;
1903 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1906 c = ctbase_realType (c);
1909 if (ct == CT_FIXEDARRAY)
1911 return c->contents.farray->base;
1915 llassert (ctuid_isAP (ct));
1917 return c->contents.base;
1922 ctbase_baseFunction (/*@notnull@*/ ctbase c)
1925 c = ctbase_realFunction (c);
1927 if (c->type != CT_FCN)
1929 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
1932 return (c->contents.fcn->rval);
1936 ctbase_argsFunction (/*@notnull@*/ ctbase c)
1939 c = ctbase_realFunction (c);
1941 if (c->type != CT_FCN)
1943 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
1944 ctbase_unparse (c)));
1946 return (c->contents.fcn->params);
1950 ctbase_baseisExpFcn (ctype c)
1953 c = ctype_removePointers (c);
1955 cb = ctype_getCtbase (c);
1956 llassert (ctbase_isDefined (cb));
1958 if (cb->type == CT_FCN)
1960 c = ctype_removePointers (ctype_getReturnType (c));
1962 cb = ctype_getCtbase (c);
1963 llassert (ctbase_isDefined (cb));
1965 return (cb->type == CT_EXPFCN);
1971 ** ctbase_newBase behaves specially when p is a CONJ:
1973 ** c -> conj (newBase (c, p.a), p.b)
1977 ctbase_newBase (ctype c, ctype p)
1981 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
1983 if (ctype_isUndefined (c) || ctype_isUnknown (c))
1988 cb = ctype_getCtbase (c);
1990 if (ctype_isConj (p))
1992 ctbase pb = ctype_getCtbase (p);
1994 llassert (ctbase_isDefined (pb));
1996 if (pb->contents.conj->isExplicit)
1998 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
1999 pb->contents.conj->b));
2004 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2005 pb->contents.conj->b));
2010 if (ctbase_baseisExpFcn (c))
2012 return (ctbase_newBaseExpFcn (c, p));
2015 llassert (ctbase_isDefined (cb));
2034 cbn = ctbase_newBase (cb->contents.base, p);
2035 ret = ctype_makePointer (cbn);
2040 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2041 cb->contents.farray->size));
2043 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2045 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2046 cb->contents.fcn->params));
2048 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2049 ctbase_newBase (cb->contents.conj->b, p),
2050 cb->contents.conj->isExplicit));
2052 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2059 ctbase_newBaseExpFcn (ctype c, ctype p)
2061 ctbase cb = ctype_getCtbase (c);
2064 ctype fp = ctype_unknown;
2065 uentryList ctargs = ctype_argsFunction (c);
2068 ** okay, this is really ugly...
2070 ** pointers inside <expf> mean pointers to the function;
2071 ** pointers outside <expf> are pointers to the return value;
2072 ** because its a function there is one superfluous pointer.
2076 ** bf is a ctype, used to derived structure of cb
2079 if (!ctbase_isFunction (cb))
2080 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2082 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2085 ** pointers before expfcn -> p are pointers to function, not result
2089 tcb = ctype_getCtbase (tmpct);
2091 llassert (ctbase_isDefined (tcb));
2092 tmpct = tcb->contents.base;
2095 ** record pointers to base in fp
2098 while (!ctype_isUnknown (tmpct))
2100 if (ctype_isExpFcn (tmpct)) {
2101 ctbase ttcb = ctype_getCtbase (tmpct);
2104 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2105 ** The whole function pointer parsing is a major kludge, but it seems to work,
2106 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2109 llassert (ctbase_isDefined (ttcb));
2110 tmpct = ttcb->contents.base;
2111 llassert (!ctype_isUnknown (tmpct));
2114 switch (ctype_getCtKind (tmpct))
2117 fp = ctype_makePointer (fp);
2118 /*@switchbreak@*/ break;
2120 fp = ctype_makeArray (fp);
2121 /*@switchbreak@*/ break;
2124 ctbase fbase = ctype_getCtbase (tmpct);
2126 if (ctbase_isFunction (fbase))
2128 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2129 ctargs = ctbase_argsFunction (fbase);
2135 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2136 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2143 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2144 ctype_unparse (tmpct)));
2148 tmpct = ctype_baseArrayPtr (tmpct);
2152 tmpct = ctype_getReturnType (c);
2155 ** pointers to expf are pointers to return value
2158 while (!ctype_isExpFcn (tmpct))
2160 switch (ctype_getCtKind (tmpct))
2163 p = ctype_makePointer (p);
2164 /*@switchbreak@*/ break;
2166 p = ctype_makeArray (p);
2167 /*@switchbreak@*/ break;
2170 ctbase fbase = ctype_getCtbase (tmpct);
2172 if (ctbase_isFunction (fbase))
2174 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2180 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2181 ctype_unparse (tmpct)));
2189 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2194 tmpct = ctype_baseArrayPtr (tmpct);
2200 ** pointers to fp are pointers to function type
2203 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2205 while (ctype_getCtKind (fp) > CTK_PLAIN)
2207 switch (ctype_getCtKind (fp))
2210 ret = ctype_makePointer (ret);
2211 /*@switchbreak@*/ break;
2213 ret = ctype_makeArray (ret);
2214 /*@switchbreak@*/ break;
2217 ctbase fbase = ctype_getCtbase (fp);
2219 if (ctbase_isFunction (fbase))
2222 ctype_makeFunction (ret,
2223 uentryList_copy (ctbase_argsFunction (fbase)));
2234 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2238 fp = ctype_baseArrayPtr (fp);
2246 ** returns lowest level base of c: plain type
2249 static /*@notnull@*/ /*@only@*/ ctbase
2250 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2264 return (ctbase_copy (c));
2268 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2271 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2272 case CT_CONJ: /* base type of A conj branch? */
2273 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2275 return (ctbase_copy (c));
2278 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2285 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2289 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2291 llcontbuglit ("ctbase_compare: undefined ctbase");
2308 return (int_compare (c1->contents.prim, c2->contents.prim));
2312 return (int_compare (c1->contents.tid, c2->contents.tid));
2315 case CT_ENUM: /* for now, keep like abstract */
2317 return (int_compare (c1->contents.tid, c2->contents.tid));
2319 return (ctype_compare (c1->contents.base, c2->contents.base));
2321 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2323 return (ctype_compare (c1->contents.farray->base,
2324 c2->contents.farray->base));
2326 return (ctype_compare (c1->contents.base, c2->contents.base));
2329 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2333 return (uentryList_compareStrict (c1->contents.fcn->params,
2334 c2->contents.fcn->params));
2338 return (uentryList_compareParams (c1->contents.fcn->params,
2339 c2->contents.fcn->params));
2343 return (ctype_compare (c1->contents.base, c2->contents.base));
2346 /* evs 2000-07-28: this block was missing! */
2348 int ncmp = cstring_compare (c1->contents.su->name,
2349 c2->contents.su->name);
2352 if (isFakeTag (c1->contents.su->name)
2353 && isFakeTag (c2->contents.su->name)) {
2354 ; /* If they are both fake struct tags, don't require match. */
2361 DPRINTF (("Comparing fields: %s / %s",
2362 ctbase_unparse (c1),
2363 ctbase_unparse (c2)));
2365 return (uentryList_compareFields (c1->contents.su->fields,
2366 c2->contents.su->fields));
2369 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2370 c2->contents.conj->a));
2371 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2372 c2->contents.conj->b));
2373 return (bool_compare (c1->contents.conj->isExplicit,
2374 c2->contents.conj->isExplicit));
2381 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2383 return (ctbase_compare (c1, c2, TRUE));
2386 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2388 return (ctbase_compareStrict (c1,c2) == 0);
2391 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2393 return (ctbase_compare (c1, c2, FALSE) == 0);
2397 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2405 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2406 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2412 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2416 if (ck == kind1 || ck == kind2)
2420 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2421 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2427 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2429 return (c->type == CT_ABST);
2432 static bool ctbase_isUA (ctbase c)
2434 return (ctbase_isDefined (c) && ((c)->type == CT_USER || (c)->type == CT_ABST));
2438 ctbase_almostEqual (ctbase c1, ctbase c2)
2442 /* undefined types never match */
2444 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2450 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2452 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2453 ctype_getCtbase (c2->contents.base)));
2456 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2458 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2459 ctype_getCtbase (c2->contents.farray->base)));
2470 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2474 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2476 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2478 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2480 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2482 return (ctype_almostEqual (c1->contents.farray->base,
2483 c2->contents.farray->base));
2485 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2487 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2488 && uentryList_matchParams (c1->contents.fcn->params,
2489 c2->contents.fcn->params, FALSE, TRUE));
2492 if (!cstring_isEmpty (c1->contents.su->name))
2494 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2498 if (!cstring_isEmpty (c2->contents.su->name))
2503 llcontbuglit ("ctbase_almostEqual: match fields");
2507 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2512 /*drl added July 02, 001
2513 called by ctype_getArraySize
2516 long int ctbase_getArraySize (ctbase ctb)
2518 /*drl 1/25/2002 fixed discover by Jim Francis */
2522 llassert (ctbase_isDefined (ctb) );
2523 r = ctbase_realType (ctb);
2524 llassert (ctbase_isFixedArray(r) );
2528 return (r->contents.farray->size);