2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 /*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/
38 /*@-macrofcndecl@*/ /*@-macroparams@*/
39 # define ctuid_isAnyUserType(cid) \
40 ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST)
41 /*@=macrofcndecl@*/ /*@=macroparams@*/
43 /*@private@*/ typedef struct {
46 ctype base; /* type I point to (or element of array) */
47 ctype ptr; /* type of pointer to me */
48 ctype array; /* type of array of me */
49 cstring unparse; /* unparse me, if memoized */
52 typedef /*@only@*/ ctentry o_ctentry;
57 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
58 /* memoize matches...maybe in context? */
61 extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
62 # define ctentry_isBogus(c) \
63 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
65 static cttable cttab = { 0, 0, NULL };
67 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
68 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createNumAbstract (typeId p_u);
69 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
70 static /*@only@*/ ctentry
71 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
72 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
73 static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
74 static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
76 static void cttable_grow (void);
77 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
78 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
79 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
80 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, size_t p_size) /*@*/ ;
81 static bool ctbase_isAnytype (/*@notnull@*/ ctbase p_b) /*@*/ ;
84 ** These are file-static macros (used in ctype.c). No way to
85 ** declare them as static in C.
88 /*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
89 # define ctentry_getBase(c) ((c)->base)
90 # define ctentry_getKind(c) ((c)->kind)
91 # define ctentry_getArray(c) ((c)->array)
92 # define ctentry_getPtr(c) ((c)->ptr)
93 # define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
94 # define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
95 # define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
96 # define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
97 # define ctentry_setArray(c,b) ((c)->array = (b))
98 # define ctentry_setPtr(c,b) ((c)->ptr = (b))
100 # define ctbase_fixUser(c) (c = ctbase_realType(c))
101 /*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
103 static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
104 static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
105 static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
106 static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
107 static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
108 static /*@observer@*/ /*@notnull@*/ ctbase
109 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
110 static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
111 static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
112 static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
113 static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
114 static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
115 static /*@only@*/ /*@notnull@*/ ctbase ctbase_copy (/*@notnull@*/ ctbase p_c) /*@*/ ;
116 static void ctbase_free (/*@only@*/ ctbase p_c);
117 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
118 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
119 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
120 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
122 static /*@notnull@*/ /*@only@*/ ctbase
123 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
125 static /*@notnull@*/ /*@only@*/ ctbase
126 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
127 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
128 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
129 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
130 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
131 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
132 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
133 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
134 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
135 static /*@notnull@*/ ctype
136 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
137 static /*@notnull@*/ /*@observer@*/ ctbase
138 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
139 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
140 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
141 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
142 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
143 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
144 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
145 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
148 extern int cttable_lastIndex();
149 # define cttable_lastIndex() (cttab.size - 1)
155 /*@only@*/ uentryList params;
174 enumNameList members;
185 cprim prim; /* primitive */
186 typeId tid; /* abstract, user */
187 ctype base; /* ptr, array */
188 cfcn fcn; /* function */
189 tsu su; /* struct union */
190 tenum cenum; /* enum */
191 tconj conj; /* conj */
192 tfixed farray; /* fixed array */
201 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
202 static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
203 static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
204 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
205 static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
206 static /*@only@*/ /*@notnull@*/ ctbase
207 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
209 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
211 /*@constant null ctbase ctbase_undefined; @*/
212 # define ctbase_undefined ((ctbase)0)
214 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
215 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
217 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
219 return ((c) != ctbase_undefined);
222 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
224 return ((c) == ctbase_undefined);
227 static ctkind ctype_getCtKind (ctype c)
229 ctentry ce = ctype_getCtentry (c);
231 return ctentry_getKind (ce);
234 static bool ctbase_isUser (ctbase c)
236 if (ctbase_isDefined (c))
238 return (ctbase_isKind (c, CT_USER));
246 static bool ctbase_isEnum (ctbase c)
248 if (ctbase_isDefined (c))
250 return (ctbase_isKind (c, CT_ENUM));
258 static bool ctbase_isExpFcn (ctbase c)
260 if (ctbase_isDefined (c))
262 return (c->type == CT_EXPFCN);
270 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
272 if (ctbase_isDefined (c))
274 return (c->type == CT_CONJ);
282 static bool ctuid_isAP (ctuid c) /*@*/
284 return (c == CT_ARRAY || c == CT_PTR);
287 static typeId ctbase_typeId (ctbase p_c);
288 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
289 static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
290 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
291 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
292 static /*@notnull@*/ /*@only@*/ ctbase
293 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
294 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
295 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
296 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
297 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
298 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
299 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
300 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
301 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
302 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
303 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
305 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
306 static int nctbases = 0;
308 static /*@notnull@*/ /*@only@*/
309 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
311 static bool ctbase_isUnnamedSU (ctbase c)
313 return (ctbase_isDefined (c)
314 && (ctbase_isStruct (c) || ctbase_isUnion (c))
315 && isFakeTag (c->contents.su->name));
318 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
322 typeId uid = ctbase_typeId (c);
324 if (usymtab_isBoolType (uid))
326 return ctbase_getBool ();
330 ctbase ret = ctype_getCtbase
331 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
333 llassert (ret != ctbase_undefined);
344 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
346 ctbase r = ctbase_realType (c);
348 return (ctbase_isKind (r, CT_PTR) &&
349 ctype_isVoid (r->contents.base));
353 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
355 ctbase r = ctbase_realType (c);
357 return (ctbase_isKind (r, CT_PTR));
361 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
363 ctbase r = ctbase_realType (c);
365 return (ctbase_isKind (r, CT_ARRAY)
366 || ctbase_isKind (r, CT_FIXEDARRAY));
370 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
372 ctbase r = ctbase_realType (c);
374 return (ctbase_isKind (r, CT_FIXEDARRAY));
378 ctbase_isStruct (/*@notnull@*/ ctbase c)
380 ctbase r = ctbase_realType (c);
382 return (ctbase_isKind (r, CT_STRUCT));
386 ctbase_isUnion (/*@notnull@*/ ctbase c)
388 ctbase r = ctbase_realType (c);
390 return (ctbase_isKind (r, CT_UNION));
394 ** clean this up -> typeTable should store ctype
398 ctbase_typeBaseUid (ctbase c)
402 if (ctbase_isDefined (c))
408 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
410 else if (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST)
412 return c->contents.tid;
414 else if (ct == CT_FIXEDARRAY)
416 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
420 llcontbuglit ("ctbase_typeBaseUid: bad call");
421 return typeId_invalid;
424 return typeId_invalid;
428 ctbase_isBaseUA (ctbase c)
432 if (ctbase_isDefined (c))
438 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
440 else if (ct == CT_FIXEDARRAY)
442 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
445 return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
451 ctbase_typeId (ctbase c)
455 return c->contents.tid;
459 if (ctbase_isConj (c))
461 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
465 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
466 return typeId_invalid;
471 static /*@only@*/ cstring
472 ctbase_unparse (ctbase c)
474 if (ctbase_isUndefined (c)) {
475 return cstring_makeLiteral ("<<undef>>");
481 return cstring_makeLiteral ("?");
483 return cstring_copy (context_printBoolName ());
485 return (cprim_unparse (c->contents.prim));
489 return (usymtab_getTypeEntryName (c->contents.tid));
491 return (message ("<expf: %t>", c->contents.base));
493 /* no spaces for multiple pointers */
495 if (ctype_isPointer (c->contents.base))
497 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
501 return (message ("%t *", c->contents.base));
504 return (message ("%t [%d]",
505 c->contents.farray->base,
506 (int) c->contents.farray->size));
508 return (message ("%t []", c->contents.base));
510 return (message ("[function (%q) returns %t]",
511 uentryList_unparseParams (c->contents.fcn->params),
512 c->contents.fcn->rval));
514 if (cstring_isDefined (c->contents.su->name) &&
515 !cstring_isEmpty (c->contents.su->name) &&
516 !isFakeTag (c->contents.su->name))
518 return (message ("struct %s", c->contents.su->name));
522 return (message ("struct { %q }",
523 uentryList_unparseAbbrev (c->contents.su->fields)));
526 if (cstring_isDefined (c->contents.su->name) &&
527 !cstring_isEmpty (c->contents.su->name) &&
528 !isFakeTag (c->contents.su->name))
530 return (message ("union %s", c->contents.su->name));
534 return (message ("union { %q }",
535 uentryList_unparseAbbrev (c->contents.su->fields)));
538 if (isFakeTag (c->contents.cenum->tag))
540 return (message ("enum { %q }",
541 enumNameList_unparseBrief (c->contents.cenum->members)));
545 return (message ("enum %s { %q }",
546 c->contents.cenum->tag,
547 enumNameList_unparseBrief (c->contents.cenum->members)));
550 if (ctbase_isAnytype (c))
552 return (cstring_makeLiteral ("<any>"));
554 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
556 if (!ctype_isSimple (c->contents.conj->a) ||
557 !ctype_isSimple (c->contents.conj->b))
559 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
563 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
568 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
575 static /*@only@*/ cstring
576 ctbase_unparseDeep (ctbase c)
578 if (ctbase_isUndefined (c))
580 return cstring_makeLiteral ("<<undef>>");
586 return cstring_makeLiteral ("?");
588 return cstring_copy (context_printBoolName ());
590 return (cprim_unparse (c->contents.prim));
592 if (cstring_isNonEmpty (c->contents.cenum->tag))
594 return (message ("enum %s { %q }",
595 c->contents.cenum->tag,
596 enumNameList_unparse (c->contents.cenum->members)));
600 return (message ("enum { %q }",
601 enumNameList_unparse (c->contents.cenum->members)));
606 return (usymtab_getTypeEntryName (c->contents.tid));
608 return (message ("<expf: %t>", c->contents.base));
610 return (message ("%t *", c->contents.base));
612 return (message ("%t [%d]", c->contents.farray->base,
613 (int) c->contents.farray->size));
615 return (message ("%t []", c->contents.base));
617 return (message ("[function (%q) returns %t]",
618 uentryList_unparse (c->contents.fcn->params),
619 c->contents.fcn->rval));
621 return (message ("struct %s { ... } ", c->contents.su->name));
623 return (message ("union %s { ... }", c->contents.su->name));
625 if (ctbase_isAnytype (c))
627 return (cstring_makeLiteral ("<any>"));
631 return (message ("%t", c->contents.conj->a));
638 static /*@only@*/ cstring
639 ctbase_unparseNotypes (ctbase c)
641 llassert (ctbase_isDefined (c));
646 return cstring_makeLiteral ("?");
648 return cstring_copy (context_printBoolName ());
650 return (cprim_unparse (c->contents.prim));
652 if (typeId_isInvalid (c->contents.tid))
654 return cstring_makeLiteral ("enum");
658 return (message ("T#%d", c->contents.tid));
661 return (message ("uT#%d", c->contents.tid));
663 return (message ("aT#%d", c->contents.tid));
665 return (message ("nT#%d", c->contents.tid));
667 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
669 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
671 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
673 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
674 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
676 return (message ("struct %s", c->contents.su->name));
678 return (message ("union %s", c->contents.su->name));
680 return (message ("[enumlist]"));
682 if (ctbase_isAnytype (c))
684 return (cstring_makeLiteral ("<any>"));
688 return (message ("%q/%q",
689 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
690 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
697 static /*@only@*/ cstring
698 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
700 if (ctbase_isUndefined (c))
708 return (message ("? %q", name));
710 return (message ("%s %q", context_printBoolName (), name));
712 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
716 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
718 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
721 if (ctype_isFunction (c->contents.base))
723 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
727 cstring s = cstring_prependChar ('*', name);
728 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
733 return (message ("%q[%d]",
734 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
735 (int) c->contents.farray->size));
737 return (message ("%q[]",
738 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
741 cstring s = message ("%q(%q)", name,
742 uentryList_unparseParams (c->contents.fcn->params));
744 return (ctbase_unparseDeclaration
745 (ctype_getCtbase (c->contents.fcn->rval), s));
748 if (cstring_isDefined (c->contents.su->name) &&
749 !cstring_isEmpty (c->contents.su->name) &&
750 !isFakeTag (c->contents.su->name))
752 return (message ("struct %s %q", c->contents.su->name, name));
756 return (message ("struct { %q } %q",
757 uentryList_unparseAbbrev (c->contents.su->fields),
761 if (cstring_isDefined (c->contents.su->name) &&
762 !cstring_isEmpty (c->contents.su->name) &&
763 !isFakeTag (c->contents.su->name))
765 return (message ("union %s %q", c->contents.su->name, name));
769 return (message ("union { %q } %q",
770 uentryList_unparseAbbrev (c->contents.su->fields),
774 if (isFakeTag (c->contents.cenum->tag))
776 return (message ("enum { %q } %q",
777 enumNameList_unparseBrief (c->contents.cenum->members),
782 return (message ("enum %s { %q } %q",
783 c->contents.cenum->tag,
784 enumNameList_unparseBrief (c->contents.cenum->members),
788 if (ctbase_isAnytype (c))
790 return (message ("<any> %q", name));
792 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
794 if (!ctype_isSimple (c->contents.conj->a) ||
795 !ctype_isSimple (c->contents.conj->b))
797 cstring name1 = cstring_copy (name);
802 ctbase_unparseDeclaration
803 (ctype_getCtbase (c->contents.conj->a), name1),
804 ctbase_unparseDeclaration
805 (ctype_getCtbase (c->contents.conj->b), name)));
809 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
810 cstring_copy (name));
812 (message ("%q | %q", s1,
813 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
820 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
827 static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
837 return (ctbase_undefined);
839 return (ctbase_createUnknown ());
841 return (ctbase_createBool ());
843 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
844 reader_checkChar (c, '|');
847 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
848 reader_checkChar (c, '|');
851 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
852 reader_checkChar (c, '|');
855 res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
856 reader_checkChar (c, '|');
859 res = ctbase_makePointer (ctype_undump (c));
860 reader_checkChar (c, '|');
863 res = ctbase_makeArray (ctype_undump (c));
864 reader_checkChar (c, '|');
868 ctype ct = ctype_undump (c);
871 reader_checkChar (c, '/');
872 size = size_fromInt (reader_getInt (c));
873 reader_checkChar (c, '|');
874 return (ctbase_makeFixedArray (ct, size));
879 char *lp = strchr (*c, '(');
881 llassertfatal (lp != NULL);
884 ct = ctype_undump (c);
887 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
894 char *lc = strchr (*c, '{');
896 llassert (lc != NULL);
899 sname = mstring_copy (*c);
907 i = (unsigned) atoi (sname + 1);
912 fields = uentryList_undumpFields (c, g_currentloc);
914 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
920 char *lc = strchr (*c, '{');
922 llassert (lc != NULL);
925 sname = mstring_copy (*c);
926 llassert (sname != NULL);
934 i = (unsigned) atoi (sname + 1);
938 return (ctbase_createUnion (cstring_fromCharsO (sname),
939 uentryList_undumpFields (c, g_currentloc)));
945 char *lc = strchr (*c, '{');
947 llassert (lc != NULL);
950 sname = mstring_copy (*c);
957 i = (unsigned) atoi (sname + 1);
961 ret = ctbase_createEnum (cstring_fromCharsO (sname),
962 enumNameList_undump (c));
970 isExplicit = bool_fromInt (reader_getInt (c));
971 reader_checkChar (c, '.');
972 c1 = ctype_undump (c);
973 reader_checkChar (c, '/');
974 c2 = ctype_undump (c);
975 reader_checkChar (c, '|');
977 return (ctbase_makeConj (c1, c2, isExplicit));
983 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
985 /*drl bee: pbr*/ while (**c != '\0')
990 return ctbase_createUnknown ();
994 /* first letter of c encodes type: */
1010 static /*@only@*/ cstring
1011 ctbase_dump (ctbase c)
1013 if (!ctbase_isDefined (c))
1015 return cstring_makeLiteral ("?");
1021 return cstring_makeLiteral ("u");
1023 return cstring_makeLiteral ("b");
1025 return (message ("p%d|", c->contents.prim));
1027 return (message ("s%d|", usymtab_convertTypeId (c->contents.tid)));
1029 return (message ("a%d|", usymtab_convertTypeId (c->contents.tid)));
1031 return (message ("n%d|", usymtab_convertTypeId (c->contents.tid)));
1033 return (message ("t%q|", ctype_dump (c->contents.base)));
1035 return (message ("y%q|", ctype_dump (c->contents.base)));
1037 return (message ("F%q/%d|",
1038 ctype_dump (c->contents.farray->base),
1039 (int) c->contents.farray->size));
1041 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
1042 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1043 uentryList_dumpParams (c->contents.fcn->params)));
1045 return (message ("S%s{%q}", c->contents.su->name,
1046 uentryList_dumpFields (c->contents.su->fields)));
1048 return (message ("U%s{%q}", c->contents.su->name,
1049 uentryList_dumpFields (c->contents.su->fields)));
1054 if (cstring_isNonEmpty (c->contents.cenum->tag))
1056 s = message ("e%s{%q}",
1057 c->contents.cenum->tag,
1058 enumNameList_dump (c->contents.cenum->members));
1062 s = message ("e{%q}",
1063 enumNameList_dump (c->contents.cenum->members));
1068 return (message ("C%d.%q/%q|",
1069 bool_toInt (c->contents.conj->isExplicit),
1070 ctype_dump (c->contents.conj->a),
1071 ctype_dump (c->contents.conj->b)));
1073 /* should clean them up! */
1074 return (cstring_makeLiteral ("?"));
1076 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1077 return (message ("u"));
1084 static /*@only@*/ ctbase
1085 ctbase_copy (/*@notnull@*/ ctbase c)
1090 return (ctbase_createUnknown ());
1092 return (ctbase_createBool ());
1094 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1095 enumNameList_copy (c->contents.cenum->members)));
1097 return (ctbase_createPrim (c->contents.prim));
1099 return (ctbase_createUser (c->contents.tid));
1101 return (ctbase_createAbstract (c->contents.tid));
1103 return (ctbase_createNumAbstract (c->contents.tid));
1105 return (ctbase_expectFunction (c->contents.base));
1107 return (ctbase_makePointer (c->contents.base));
1109 return (ctbase_makeArray (c->contents.base));
1111 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1112 uentryList_copy (c->contents.fcn->params)));
1114 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1115 uentryList_copy (c->contents.su->fields)));
1117 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1118 uentryList_copy (c->contents.su->fields)));
1120 /*@i@*/ return (c); /* not a real copy for conj's */
1122 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1129 ctbase_elist (ctbase c)
1131 llassert (ctbase_isDefined (c));
1132 llassert (c->type == CT_ENUM);
1134 return (c->contents.cenum->members);
1138 ctbase_free (/*@only@*/ ctbase c)
1140 if (c == ctbase_bool || c == ctbase_unknown)
1142 /*@-mustfree@*/ return; /*@=mustfree@*/
1148 if (ctbase_isDefined (c))
1175 /* Cannot free params: uentryList_free (c->contents.fcn->params); */
1176 uentryList_freeShallow (c->contents.fcn->params);
1181 cstring_free (c->contents.su->name);
1182 uentryList_free (c->contents.su->fields);
1186 /* Don't bree conj's, */
1196 ** c should be * <unknown>
1199 static /*@only@*/ ctbase
1200 ctbase_expectFunction (ctype c)
1202 ctbase f = ctbase_new ();
1204 f->type = CT_EXPFCN;
1205 f->contents.base = c;
1211 ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
1213 return (ct->type == CT_EXPFCN);
1217 ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
1219 llassert (ctbase_isExpectFunction (ct));
1220 return ct->contents.base;
1224 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1228 /* undefined types never match */
1230 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1233 /* abstract types match user types of same name */
1235 c1 = ctbase_realType (c1);
1236 c2 = ctbase_realType (c2);
1238 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1239 ctbase_unparse (c2)));
1244 if (c1tid == CT_CONJ)
1246 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1247 force, arg, def, deep)
1248 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1249 force, arg, def, deep));
1252 if (c2tid == CT_CONJ)
1254 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1255 force, arg, def, deep)
1256 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1257 force, arg, def, deep));
1261 ** if the types don't match, there are some special cases...
1266 /* unknowns match anything */
1268 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1273 if (c1tid == CT_FIXEDARRAY
1274 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1276 if (ctype_isVoid (c2->contents.base))
1278 return (context_getFlag (FLG_ABSTVOIDP) ||
1279 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1280 !(ctype_isRealAbstract (c2->contents.base))));
1283 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1284 ctype_getCtbase (c2->contents.base),
1285 force, arg, def, deep));
1289 if (c2tid == CT_FIXEDARRAY
1290 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1292 if (ctype_isVoid (c1->contents.base))
1294 return (context_getFlag (FLG_ABSTVOIDP) ||
1295 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1296 !(ctype_isRealAbstract (c1->contents.base))));
1299 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1300 ctype_getCtbase (c2->contents.farray->base),
1301 force, arg, def, deep));
1304 /* evs 2000-07-25: Bool's may match user/abstract types */
1306 if ((c1tid == CT_BOOL
1307 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1309 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1311 return (context_msgBoolInt ());
1314 if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
1315 ctype t2c = c2->contents.base;
1316 return (ctype_isBool (t2c));
1319 if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
1320 ctype t1c = c1->contents.base;
1322 return (ctype_isBool (t1c));
1325 if ((c1tid == CT_ENUM
1326 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1328 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1330 return (context_msgEnumInt ());
1334 ** arrays and pointers...yuk!
1336 ** Considered equivalent except in definitions.
1337 ** (e.g., function parameters are equivalent)
1343 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1350 ** Function pointers can be removed.
1352 ** [function ..] is equivalent to [function ..] *
1355 if (c1tid == CT_PTR && c2tid == CT_FCN)
1357 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1359 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1364 if (c2tid == CT_PTR && c1tid == CT_FCN)
1366 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1368 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1374 ** we allow forward declarations to structures like,
1376 ** typedef struct _t *t;
1379 ** struct _t * to match t
1382 if (context_getFlag (FLG_FORWARDDECL))
1384 if (ctuid_isAnyUserType (c1tid))
1386 if (ctuid_isAP (c2tid))
1388 ctype ts = c2->contents.base;
1390 if (ctype_isUA (ts))
1392 typeId ttid = ctype_typeId (ts);
1393 typeId ctid = c1->contents.tid ;
1395 if (usymtab_matchForwardStruct (ctid, ttid))
1403 if (ctuid_isAnyUserType (c2tid))
1405 if (ctuid_isAP (c1tid))
1407 ctype ts = c1->contents.base;
1409 if (ctype_isUA (ts))
1411 typeId ttid = ctype_typeId (ts);
1412 typeId ctid = c2->contents.tid ;
1414 if (usymtab_matchForwardStruct (ctid, ttid))
1433 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1435 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1442 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1444 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1446 if (ctype_isVoid (c1->contents.base)
1447 || (ctype_isVoid (c2->contents.base)))
1449 if (ctype_isFunction (ctype_realType (c1->contents.base))
1450 || ctype_isFunction (ctype_realType (c2->contents.base)))
1452 return (!context_getFlag (FLG_CASTFCNPTR));
1456 return (context_getFlag (FLG_ABSTVOIDP) ||
1457 (!(ctype_isRealAbstract (c1->contents.base)) &&
1458 !(ctype_isRealAbstract (c2->contents.base))));
1463 /* Only allow one implicit function pointer. */
1465 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1466 ctype_isRealPointer (c2->contents.base))
1467 && (ctype_isRealFunction (c1->contents.base)
1468 || ctype_isRealFunction (c2->contents.base)))
1473 return (ctype_genMatch (c1->contents.base,
1474 c2->contents.base, force, arg, def, TRUE));
1477 if (ctype_isVoid (c1->contents.farray->base)
1478 || ctype_isVoid (c2->contents.farray->base))
1480 return (ctype_genMatch (c1->contents.farray->base,
1481 c2->contents.farray->base,
1482 force, arg, def, deep));
1484 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1486 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1488 return (ctype_genMatch (c1->contents.fcn->rval,
1489 c2->contents.fcn->rval,
1490 force, arg, def, TRUE)
1491 && uentryList_matchParams (c1->contents.fcn->params,
1492 c2->contents.fcn->params,
1496 DPRINTF (("Struct: %s / %s",
1497 c1->contents.su->name,
1498 c2->contents.su->name));
1500 if (isFakeTag (c1->contents.su->name)
1501 && isFakeTag (c2->contents.su->name))
1503 /* Both fake tags, check structure */
1504 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1510 return uentryList_matchFields (c1->contents.su->fields,
1511 c2->contents.su->fields);
1516 if (!cstring_isEmpty (c1->contents.su->name))
1518 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1522 if (!cstring_isEmpty (c2->contents.su->name))
1527 llcontbuglit ("ctbase_genMatch: match fields");
1532 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1538 ** like ctbase_match, except for conjuncts:
1539 ** modifies conjuncts to match only
1543 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1545 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1549 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1551 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1555 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1557 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1561 ctbase_matchArg (ctbase c1, ctbase c2)
1563 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1566 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1569 ctbase c = (ctbase) dmalloc (sizeof (*c));
1573 if (nctbases % 100 == 0 && nctbases > lastnc)
1575 llmsg (message ("ctbases: %d", nctbases));
1582 static /*@only@*/ ctbase
1583 ctbase_createPrim (cprim p)
1585 ctbase c = ctbase_new ();
1588 c->contents.prim = p;
1593 static /*@observer@*/ ctbase
1594 ctbase_getBool (void)
1596 /*@i@*/ return ctbase_createBool ();
1600 ctbase_createBool ()
1602 if (!ctbase_isDefined (ctbase_bool))
1604 ctbase_bool = ctbase_new ();
1605 ctbase_bool->type = CT_BOOL;
1606 ctbase_bool->contents.prim = CTX_BOOL;
1609 /*@-retalias@*/ /*@-globstate@*/
1611 /*@=retalias@*/ /*@=globstate@*/
1614 static /*@only@*/ ctbase
1615 ctbase_createUser (typeId u)
1617 ctbase c = ctbase_new ();
1620 c->contents.tid = u;
1622 llassert (typeId_isValid (u));
1627 static /*@only@*/ ctbase
1628 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1630 ctbase c = ctbase_new ();
1634 if (cstring_isUndefined (etag))
1636 llcontbuglit ("Undefined enum tag!");
1640 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1641 c->contents.cenum->tag = etag;
1642 c->contents.cenum->members = emembers;
1647 static /*@observer@*/ cstring
1648 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1650 return (ct->contents.cenum->tag);
1653 static /*@only@*/ ctbase
1654 ctbase_createAbstract (typeId u)
1656 ctbase c = ctbase_new ();
1659 c->contents.tid = u;
1661 /* also check its abstract? */
1663 llassert (typeId_isValid (c->contents.tid));
1668 static /*@only@*/ ctbase
1669 ctbase_createNumAbstract (typeId u)
1671 ctbase c = ctbase_new ();
1673 c->type = CT_NUMABST;
1674 c->contents.tid = u;
1676 /* also check its abstract? */
1678 llassert (typeId_isValid (c->contents.tid));
1682 static /*@only@*/ ctbase
1683 ctbase_createUnknown (void)
1685 if (!ctbase_isDefined (ctbase_unknown))
1687 ctbase_unknown = ctbase_new ();
1688 ctbase_unknown->type = CT_UNKNOWN;
1689 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1692 /*@-retalias@*/ /*@-globstate@*/
1693 return ctbase_unknown;
1694 /*@=retalias@*/ /*@=globstate@*/
1698 ** requires: result is not assigned to b
1699 ** (should copy, but no way to reclaim storage)
1702 static /*@only@*/ ctbase
1703 ctbase_makePointer (ctype b)
1705 ctbase c = ctbase_new ();
1708 c->contents.base = b;
1713 static /*@only@*/ ctbase
1714 ctbase_makeArray (ctype b)
1716 ctbase c = ctbase_new ();
1719 c->contents.base = b;
1724 static /*@notnull@*/ /*@only@*/ ctbase
1725 ctbase_makeFixedArray (ctype b, size_t size)
1727 ctbase c = ctbase_new ();
1729 c->type = CT_FIXEDARRAY;
1731 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1732 c->contents.farray->base = b;
1733 c->contents.farray->size = size;
1739 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1741 ctbase c = ctbase_new ();
1745 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1747 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1752 if (ctype_isPointer (b))
1754 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1758 ctb = ctype_getCtbase (b);
1761 llassert (ctbase_isDefined (ctb));
1762 llassert (ctb->type == CT_FCN);
1764 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1766 c->contents.fcn->rval = rval;
1767 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1771 c->contents.fcn->rval = b;
1772 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1773 /*@-branchstate@*/ /* p is really released on this branch */
1777 ct = cttable_addComplex (c);
1778 return (ct); /* was: ctype_makePointer (ct)); */
1782 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1784 ctbase c = ctbase_new ();
1788 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1790 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1795 if (ctype_isPointer (b))
1797 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1801 ctb = ctype_getCtbase (b);
1804 llassert (ctbase_isDefined (ctb));
1805 llassert (ctb->type == CT_FCN);
1807 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1809 c->contents.fcn->rval = rval;
1810 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1814 c->contents.fcn->rval = b;
1815 c->contents.fcn->params = uentryList_copy (p);
1820 ct = cttable_addComplex (c);
1821 return (ct); /* was: ctype_makePointer (ct)); */
1824 static /*@only@*/ ctbase
1825 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1827 ctbase c = ctbase_new ();
1831 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1832 c->contents.fcn->rval = b;
1833 c->contents.fcn->params = p;
1835 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1838 static /*@observer@*/ /*@notnull@*/ ctbase
1839 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1843 if (c->type == CT_FCN)
1848 llassert (ctbase_isFunction (c));
1850 res = ctype_getCtbase (c->contents.base);
1852 llassert (ctbase_isDefined (res));
1858 ctbase_isFunction (ctbase c)
1860 llassert (c != ctbase_undefined);
1862 if (c->type == CT_FCN)
1868 if (c->type == CT_PTR)
1870 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1872 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1879 /* doesn't copy c1 and c2 */
1881 static /*@only@*/ ctbase
1882 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1884 ctbase c = ctbase_new ();
1888 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1889 c->contents.conj->a = c1;
1890 c->contents.conj->b = c2;
1891 c->contents.conj->isExplicit = isExplicit;
1896 static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
1899 ** A unknown|dne conj is a special representation for an anytype.
1902 if (b->type == CT_CONJ)
1905 return (b->contents.conj->a == ctype_unknown
1906 && b->contents.conj->b == ctype_dne);
1907 /*@noaccess ctype@*/
1914 ctbase_getConjA (/*@notnull@*/ ctbase c)
1916 llassert (c->type == CT_CONJ);
1917 return (c->contents.conj->a);
1921 ctbase_getConjB (/*@notnull@*/ ctbase c)
1923 llassert (c->type == CT_CONJ);
1924 return (c->contents.conj->b);
1928 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1930 llassert (c->type == CT_CONJ);
1931 return (c->contents.conj->isExplicit);
1934 static /*@only@*/ ctbase
1935 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1937 ctbase c = ctbase_new ();
1939 c->type = CT_STRUCT;
1941 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1942 c->contents.su->name = n;
1943 c->contents.su->fields = f;
1948 static /*@observer@*/ uentryList
1949 ctbase_getuentryList (/*@notnull@*/ ctbase c)
1951 c = ctbase_realType (c);
1953 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1954 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1956 return (c->contents.su->fields);
1960 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1962 ctbase c = ctbase_new ();
1966 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1967 c->contents.su->name = n;
1968 c->contents.su->fields = f;
1974 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1977 c = ctbase_realType (c);
1980 if (ct == CT_FIXEDARRAY)
1982 return c->contents.farray->base;
1986 llassert (ctuid_isAP (ct));
1988 return c->contents.base;
1993 ctbase_baseFunction (/*@notnull@*/ ctbase c)
1996 c = ctbase_realFunction (c);
1998 if (c->type != CT_FCN)
2000 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
2003 return (c->contents.fcn->rval);
2007 ctbase_argsFunction (/*@notnull@*/ ctbase c)
2010 c = ctbase_realFunction (c);
2012 if (c->type != CT_FCN)
2014 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
2015 ctbase_unparse (c)));
2017 return (c->contents.fcn->params);
2021 ctbase_baseisExpFcn (ctype c)
2024 c = ctype_removePointers (c);
2026 cb = ctype_getCtbase (c);
2027 llassert (ctbase_isDefined (cb));
2029 if (cb->type == CT_FCN)
2031 c = ctype_removePointers (ctype_getReturnType (c));
2033 cb = ctype_getCtbase (c);
2034 llassert (ctbase_isDefined (cb));
2036 return (cb->type == CT_EXPFCN);
2042 ** ctbase_newBase behaves specially when p is a CONJ:
2044 ** c -> conj (newBase (c, p.a), p.b)
2048 ctbase_newBase (ctype c, ctype p)
2052 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
2054 if (ctype_isUndefined (c) || ctype_isUnknown (c))
2059 cb = ctype_getCtbase (c);
2061 if (ctype_isConj (p))
2063 ctbase pb = ctype_getCtbase (p);
2065 llassert (ctbase_isDefined (pb));
2067 if (pb->contents.conj->isExplicit)
2069 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
2070 pb->contents.conj->b));
2075 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2076 pb->contents.conj->b));
2081 if (ctbase_baseisExpFcn (c))
2083 return (ctbase_newBaseExpFcn (c, p));
2086 llassert (ctbase_isDefined (cb));
2106 cbn = ctbase_newBase (cb->contents.base, p);
2107 ret = ctype_makePointer (cbn);
2112 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2113 cb->contents.farray->size));
2115 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2117 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2118 cb->contents.fcn->params));
2120 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2121 ctbase_newBase (cb->contents.conj->b, p),
2122 cb->contents.conj->isExplicit));
2124 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2131 ctbase_newBaseExpFcn (ctype c, ctype p)
2133 ctbase cb = ctype_getCtbase (c);
2136 ctype fp = ctype_unknown;
2137 uentryList ctargs = ctype_argsFunction (c);
2140 ** okay, this is really ugly...
2142 ** pointers inside <expf> mean pointers to the function;
2143 ** pointers outside <expf> are pointers to the return value;
2144 ** because its a function there is one superfluous pointer.
2148 ** bf is a ctype, used to derived structure of cb
2151 if (!ctbase_isFunction (cb))
2152 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2154 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2157 ** pointers before expfcn -> p are pointers to function, not result
2161 tcb = ctype_getCtbase (tmpct);
2163 llassert (ctbase_isDefined (tcb));
2164 tmpct = tcb->contents.base;
2167 ** record pointers to base in fp
2170 while (!ctype_isUnknown (tmpct))
2172 if (ctype_isExpFcn (tmpct)) {
2173 ctbase ttcb = ctype_getCtbase (tmpct);
2176 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2177 ** The whole function pointer parsing is a major kludge, but it seems to work,
2178 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2181 llassert (ctbase_isDefined (ttcb));
2182 tmpct = ttcb->contents.base;
2183 llassert (!ctype_isUnknown (tmpct));
2186 switch (ctype_getCtKind (tmpct))
2189 fp = ctype_makePointer (fp);
2190 /*@switchbreak@*/ break;
2192 fp = ctype_makeArray (fp);
2193 /*@switchbreak@*/ break;
2196 ctbase fbase = ctype_getCtbase (tmpct);
2198 if (ctbase_isFunction (fbase))
2200 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2201 ctargs = ctbase_argsFunction (fbase);
2207 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2208 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2215 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2216 ctype_unparse (tmpct)));
2220 tmpct = ctype_baseArrayPtr (tmpct);
2224 tmpct = ctype_getReturnType (c);
2227 ** pointers to expf are pointers to return value
2230 while (!ctype_isExpFcn (tmpct))
2232 switch (ctype_getCtKind (tmpct))
2235 p = ctype_makePointer (p);
2236 /*@switchbreak@*/ break;
2238 p = ctype_makeArray (p);
2239 /*@switchbreak@*/ break;
2242 ctbase fbase = ctype_getCtbase (tmpct);
2244 if (ctbase_isFunction (fbase))
2246 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2252 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2253 ctype_unparse (tmpct)));
2261 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2266 tmpct = ctype_baseArrayPtr (tmpct);
2272 ** pointers to fp are pointers to function type
2275 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2277 while (ctype_getCtKind (fp) > CTK_PLAIN)
2279 switch (ctype_getCtKind (fp))
2282 ret = ctype_makePointer (ret);
2283 /*@switchbreak@*/ break;
2285 ret = ctype_makeArray (ret);
2286 /*@switchbreak@*/ break;
2289 ctbase fbase = ctype_getCtbase (fp);
2291 if (ctbase_isFunction (fbase))
2294 ctype_makeFunction (ret,
2295 uentryList_copy (ctbase_argsFunction (fbase)));
2306 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2310 fp = ctype_baseArrayPtr (fp);
2318 ** returns lowest level base of c: plain type
2321 static /*@notnull@*/ /*@only@*/ ctbase
2322 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2337 return (ctbase_copy (c));
2341 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2344 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2345 case CT_CONJ: /* base type of A conj branch? */
2346 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2348 return (ctbase_copy (c));
2351 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2358 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2362 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2364 llcontbuglit ("ctbase_compare: undefined ctbase");
2381 return (int_compare (c1->contents.prim, c2->contents.prim));
2385 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2388 case CT_ENUM: /* for now, keep like abstract */
2391 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2393 return (ctype_compare (c1->contents.base, c2->contents.base));
2395 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2397 return (ctype_compare (c1->contents.farray->base,
2398 c2->contents.farray->base));
2400 return (ctype_compare (c1->contents.base, c2->contents.base));
2403 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2407 return (uentryList_compareStrict (c1->contents.fcn->params,
2408 c2->contents.fcn->params));
2412 return (uentryList_compareParams (c1->contents.fcn->params,
2413 c2->contents.fcn->params));
2417 return (ctype_compare (c1->contents.base, c2->contents.base));
2420 /* evs 2000-07-28: this block was missing! */
2422 int ncmp = cstring_compare (c1->contents.su->name,
2423 c2->contents.su->name);
2426 if (isFakeTag (c1->contents.su->name)
2427 && isFakeTag (c2->contents.su->name)) {
2428 ; /* If they are both fake struct tags, don't require match. */
2435 DPRINTF (("Comparing fields: %s / %s",
2436 ctbase_unparse (c1),
2437 ctbase_unparse (c2)));
2439 return (uentryList_compareFields (c1->contents.su->fields,
2440 c2->contents.su->fields));
2443 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2444 c2->contents.conj->a));
2445 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2446 c2->contents.conj->b));
2447 return (bool_compare (c1->contents.conj->isExplicit,
2448 c2->contents.conj->isExplicit));
2455 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2457 return (ctbase_compare (c1, c2, TRUE));
2460 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2462 return (ctbase_compareStrict (c1,c2) == 0);
2465 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2467 return (ctbase_compare (c1, c2, FALSE) == 0);
2471 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2479 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2480 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2486 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2490 if (ck == kind1 || ck == kind2)
2494 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2495 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2501 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2503 return (c->type == CT_ABST || c->type == CT_NUMABST);
2507 ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
2509 return (c->type == CT_NUMABST);
2512 static bool ctbase_isUA (ctbase c)
2514 return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
2518 ctbase_almostEqual (ctbase c1, ctbase c2)
2522 /* undefined types never match */
2524 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2530 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2532 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2533 ctype_getCtbase (c2->contents.base)));
2536 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2538 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2539 ctype_getCtbase (c2->contents.farray->base)));
2550 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2556 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2558 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2560 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2562 return (ctype_almostEqual (c1->contents.farray->base,
2563 c2->contents.farray->base));
2565 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2567 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2568 && uentryList_matchParams (c1->contents.fcn->params,
2569 c2->contents.fcn->params, FALSE, TRUE));
2572 if (!cstring_isEmpty (c1->contents.su->name))
2574 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2578 if (!cstring_isEmpty (c2->contents.su->name))
2583 llcontbuglit ("ctbase_almostEqual: match fields");
2587 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2592 /*drl added July 02, 001
2593 called by ctype_getArraySize
2596 size_t ctbase_getArraySize (ctbase ctb)
2598 /*drl 1/25/2002 fixed discovered by Jim Francis */
2601 llassert (ctbase_isDefined (ctb) );
2602 r = ctbase_realType (ctb);
2603 llassert (ctbase_isFixedArray(r) );
2605 return (r->contents.farray->size);
2608 bool ctbase_isBigger (ctbase ct1, ctbase ct2)
2610 if (ct1 != NULL && ct2 != NULL
2611 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2613 /* Only compare sizes for primitives */
2614 cprim cp1 = ct1->contents.prim;
2615 cprim cp2 = ct2->contents.prim;
2616 int nbits1 = cprim_getExpectedBits (cp1);
2617 int nbits2 = cprim_getExpectedBits (cp2);
2619 if (nbits1 > nbits2) {